Ich wollte gerade ein Modul für NPM veröffentlichen, als ich darüber nachdachte, es in ES6 neu zu schreiben, um es zukunftssicher zu machen und ES6 zu lernen. Ich habe Babel verwendet, um auf ES5 zu transpilieren und Tests durchzuführen. Aber ich bin mir nicht sicher, wie ich vorgehen soll:
- Transpiliere und veröffentliche ich den resultierenden / out-Ordner in NPM?
- Füge ich den Ergebnisordner in mein Github-Repo ein?
- Oder pflege ich 2 Repos, eines mit dem ES6-Code + Gulp-Skript für Github und eines mit den transpilierten Ergebnissen + Tests für NPM?
Kurz gesagt: Welche Schritte muss ich unternehmen, um ein in ES6 geschriebenes Modul in NPM zu veröffentlichen und gleichzeitig den Benutzern das Durchsuchen / Verzweigen des Originalcodes zu ermöglichen?
javascript
node.js
npm
ecmascript-6
babeljs
Travelling Tech Guy
quelle
quelle
Antworten:
Das Muster, das ich bisher gesehen habe, besteht darin, die es6-Dateien in einem
src
Verzeichnis zu speichern und Ihre Daten in der Vorveröffentlichung von npm im Verzeichnis zu erstellenlib
.Sie benötigen eine .npmignore-Datei, ähnlich wie .gitignore, aber ignoriert
src
stattlib
.quelle
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Dies sollte sicherstellen, dass die Installation bei der Bereitstellung in neuen Umgebungen nicht fehlschlägt..npmignore
können Sie dasfiles
Feld in package.json verwenden . Hier können Sie genau die Dateien angeben, die Sie veröffentlichen möchten, anstatt nach zufälligen Dateien zu suchen, die Sie nicht veröffentlichen möchten.Ich mag Josés Antwort. Ich habe bereits festgestellt, dass mehrere Module diesem Muster folgen. So können Sie es einfach mit Babel6 implementieren. Ich installiere
babel-cli
lokal, damit der Build nicht kaputt geht, wenn ich jemals meine globale Babel-Version ändere..npmignore
.gitignore
Installieren Sie Babel
package.json
quelle
scripts
werdennode_modules/.bin
zu ihrem hinzugefügt,$PATH
und dababel-cli
eine Binärdatei installiertnode_modules/.bin/babel
wird, muss der Befehl nicht über den Pfad referenziert werden.prepublish
problematisch ist, da es zur Installationszeit ausgeführt werden kann ( github.com/npm/npm/issues/3059 ). Bevorzugen Sie den idiomatischerenversion
Skript-Hook ( docs.npmjs.com/cli/version )prepublish
immer noch da ist. Im Moment denke ich, dassrc
Verzeichnis manuell zu kompilieren undnpm publish
ist der richtige Weg.prepublishOnly
Skript-Hook verwenden (siehe docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Beachten Sie, dass dies in Version 5 von npm wie erwartet funktionieren sollte, aber vorerst (vorausgesetzt, Sie verwenden npm v4 +) sollte dies funktionieren.prepublish
vorpublish
(obv.) Ausgeführt , wodurch Inhalte auf npm (oder wo immer Sie sie konfigurieren) verschoben werden . Es geht also darum, das zu erstellen, was im NPM-Paket enthalten ist, auch wenn es nicht eingecheckt ist.TL; DR - Nicht bis ~ Oktober 2019. Das Node.js Modules Team hat gefragt :
2019 Mai Update
Seit 2015, als diese Frage gestellt wurde, ist die JavaScript-Unterstützung für Module erheblich ausgereift und wird hoffentlich im Oktober 2019 offiziell stabil sein. Alle anderen Antworten sind jetzt veraltet oder übermäßig kompliziert. Hier ist die aktuelle Situation und Best Practice.
ES6-Unterstützung
99% von ES6 (auch bekannt als 2015) wird seit Version 6 von Node unterstützt . Die aktuelle Version von Node ist 12. Alle immergrünen Browser unterstützen die überwiegende Mehrheit der ES6-Funktionen. ECMAScript ist jetzt in der Version 2019 und das Versionsschema bevorzugt jetzt die Verwendung von Jahren.
ES-Module (auch bekannt als ECMAScript-Module) in Browsern
Alle immergrün Browser wurden unterstützt
import
-ing ES6 Module seit 2017. Dynamische Importe werden unterstützt von Chrome (+ Gabeln wie Opera und Samsung Internet) und Safari. Die Firefox-Unterstützung ist für die nächste Version 67 vorgesehen.Sie benötigen kein Webpack / Rollup / Paket usw. mehr, um Module zu laden. Sie können für andere Zwecke noch nützlich sein, müssen jedoch nicht Ihren Code laden. Sie können URLs direkt importieren, die auf den Code des ES-Moduls verweisen.
ES-Module im Knoten
ES-Module (
.mjs
Dateien mitimport
/export
) werden seit Node v8.5.0 durch Aufrufennode
mit dem--experimental-modules
Flag unterstützt. Node v12, veröffentlicht im April 2019, hat die Unterstützung für experimentelle Module neu geschrieben. Die sichtbarste Änderung ist, dass die Dateierweiterung beim Import standardmäßig angegeben werden muss:Beachten Sie die obligatorischen
.mjs
Erweiterungen. Rennen wie:Die Node 12-Version wurde auch veröffentlicht, als das Modules-Team die Entwickler aufforderte , keine ES-Modulpakete zu veröffentlichen, die für die Verwendung durch Node.js vorgesehen sind, bis eine Lösung für die Verwendung von Paketen über
require('pkg')
und gefunden wurdeimport 'pkg'
. Sie können weiterhin native ES-Module veröffentlichen, die für Browser bestimmt sind.Ökosystemunterstützung nativer ES-Module
Ab Mai 2019 ist die Ökosystemunterstützung für ES-Module noch nicht ausgereift. Beispielsweise werden Test-Frameworks wie Jest und Ava nicht unterstützt
--experimental-modules
. Sie müssen einen Transpiler verwenden und sich dann zwischen der benannten import (import { symbol }
) -Syntax (die mit den meisten npm-Paketen noch nicht funktioniert) und der Standardimportsyntax (import Package from 'package'
) entscheiden, die funktioniert, aber nicht, wenn Babel sie analysiert Für in TypeScript erstellte Pakete (Graphql-Tools, Node-Influx, Faast usw.) gibt es jedoch eine Problemumgehung, die sowohl mit--experimental-modules
als auch mit Babel funktioniert, wenn Babel Ihren Code transpiliert, sodass Sie ihn mit Jest / Ava / Mocha usw. testen können:Wohl hässlich, aber auf diese Weise können Sie Ihren eigenen ES-Modulcode mit
import
/ schreibenexport
und ihnnode --experimental-modules
ohne Transpiler ausführen . Wenn Sie Abhängigkeiten haben, die noch nicht ESM-fähig sind, importieren Sie sie wie oben beschrieben, und Sie können Testframeworks und andere Tools über Babel verwenden.Vorherige Antwort auf die Frage - denken Sie daran, tun Sie dies erst, wenn Node das Erfordernis / Import-Problem gelöst hat, hoffentlich um Oktober 2019.
Veröffentlichen von ES6-Modulen in npm mit Abwärtskompatibilität
Um ein ES-Modul auf npmjs.org zu veröffentlichen, damit es ohne Babel oder andere Transpiler direkt importiert werden kann, zeigen Sie einfach das
main
Feld in Ihrempackage.json
auf die.mjs
Datei, lassen Sie jedoch die Erweiterung weg :Das ist die einzige Änderung. Wenn Sie die Erweiterung weglassen, sucht Node zuerst nach einer mjs-Datei, wenn sie mit --experimental-modules ausgeführt wird. Andernfalls wird auf die .js-Datei zurückgegriffen, sodass Ihr vorhandener Transpilationsprozess zur Unterstützung älterer Node-Versionen wie zuvor funktioniert. Stellen Sie einfach sicher, dass Babel auf die
.mjs
Datei (en) verweist .Hier ist die Quelle für ein natives ES-Modul mit Abwärtskompatibilität für Knoten <8.5.0 , das ich in NPM veröffentlicht habe. Sie können es jetzt verwenden, ohne Babel oder irgendetwas anderes.
Installieren Sie das Modul:
Erstellen Sie eine Testdatei test.mjs :
Führen Sie den Knoten (v8.5.0 +) mit dem Flag --experimental-modules aus:
Typoskript
Wenn Sie in TypeScript entwickeln, können Sie ES6-Code generieren und ES6-Module verwenden:
Dann müssen Sie die
*.js
Ausgabe in umbenennen.mjs
, ein bekanntes Problem , das hoffentlich bald behoben wird, damit Dateien direkttsc
ausgegeben.mjs
werden können.quelle
mjs
Dateien enthielten . Node.js plant, die offizielle Unterstützung im Oktober 2019 einzuführen. Dies ist der früheste Zeitpunkt, an dem ich dies ernsthaft wiederholen würde.@ Jose ist richtig. Es ist nichts Falsches daran, ES6 / ES2015 in NPM zu veröffentlichen, aber das kann zu Problemen führen, insbesondere wenn die Person, die Ihr Paket verwendet, beispielsweise Webpack verwendet, da normalerweise Benutzer den
node_modules
Ordner während der Vorverarbeitungbabel
aus Leistungsgründen ignorieren .Also, einfach zu verwenden
gulp
,grunt
oder einfach Node.js einen bauenlib
Ordner, ES5 ist.Hier ist mein
build-lib.js
Skript, in dem ich mich behalte./tools/
(neingulp
odergrunt
hier):Hier ein letzter Rat: Sie müssen Ihrem Projekt einen .npmignore hinzufügen . Wenn
npm publish
diese Datei nicht gefunden wird, wird sie.gitignore
stattdessen verwendet, was zu Problemen führt, da Ihre.gitignore
Datei normalerweise ausgeschlossen./lib
und eingeschlossen wird. Dies./src
ist genau das Gegenteil von dem, was Sie beim Veröffentlichen in NPM wünschen. Die.npmignore
Datei hat grundsätzlich die gleiche Syntax wie.gitignore
(AFAIK).quelle
.npmignore
können Sie dasfiles
Feld in package.json verwenden . Hier können Sie genau die Dateien angeben, die Sie veröffentlichen möchten, anstatt nach zufälligen Dateien zu suchen, die Sie nicht veröffentlichen möchten..npmignore
, versuchen Siepackage.json
‚sfiles
statt finden: github.com/c-hive/guides/blob/master/js/...Folgen Sie dem Ansatz von José und Marius (mit Aktualisierung der neuesten Version von Babel im Jahr 2019): Bewahren Sie die neuesten JavaScript-Dateien in einem src-Verzeichnis auf und erstellen Sie sie mit dem
prepublish
Skript von npm und geben Sie sie in das lib-Verzeichnis aus..npmignore
.gitignore
Installieren Sie Babel (in meinem Fall Version 7.5.5)
package.json
Und ich habe
src/index.js
welche die Pfeilfunktion benutzt:Hier ist das Repo auf GitHub .
Jetzt können Sie das Paket veröffentlichen:
Bevor das Paket auf npm veröffentlicht wird, sehen Sie, dass
lib/index.js
es generiert wurde, das in es5 transpiliert wird:[Update für Rollup-Bundler]
Wie würden Sie den Rollup-Bundler integrieren, wie von @kyw gefragt?
Zuerst installieren
rollup
undrollup-plugin-babel
Zweitens erstellen Sie
rollup.config.js
im ProjektstammverzeichnisZuletzt aktualisieren
prepublish
inpackage.json
Jetzt können Sie ausführen
npm publish
und bevor das Paket auf npm veröffentlicht wird, werden Sie sehen, dass lib / index.js generiert wurde, das in es5 transpiliert wird:Hinweis:
@babel/cli
Übrigens brauchen Sie nicht mehr, wenn Sie den Rollup-Bundler verwenden. Sie können es sicher deinstallieren:quelle
Wenn Sie dies in einem sehr einfachen kleinen Open-Source-Knotenmodul in Aktion sehen möchten, schauen Sie sich den n-ten Tag an (den ich gestartet habe - auch andere Mitwirkende). Schauen Sie in die Datei package.json und in den vorveröffentlichten Schritt, der Sie dahin führt, wo und wie Sie dies tun. Wenn Sie dieses Modul klonen, können Sie es lokal ausführen und als Vorlage für Sie verwenden.
quelle
Node.js 13.2.0+ unterstützt ESM ohne das experimentelle Flag und es gibt einige Optionen zum Veröffentlichen von Hybrid-NPM-Paketen (ESM und CommonJS) (abhängig von der erforderlichen Abwärtskompatibilität): https://2ality.com/2019 /10/hybrid-npm-packages.html
Ich empfehle die vollständige Abwärtskompatibilität, um die Verwendung Ihres Pakets zu vereinfachen. Dies könnte wie folgt aussehen:
Das Hybridpaket enthält die folgenden Dateien:
mypkg/package.json
Importieren aus CommonJS:
Importieren aus ESM:
Wir haben im Jahr 05.2019 eine Untersuchung zur ESM-Unterstützung durchgeführt und festgestellt, dass vielen Bibliotheken die Unterstützung fehlt (daher die Empfehlung für die Abwärtskompatibilität):
.mjs
Dateien[email protected]
.mjs
Dateien:quelle
Die beiden Kriterien eines NPM-Pakets sind, dass es nur mit a verwendet werden kann
require( 'package' )
und etwas Software-artiges tut.Wenn Sie diese beiden Anforderungen erfüllen, können Sie tun, was Sie wollen. Selbst wenn das Modul in ES6 geschrieben ist und der Endbenutzer das nicht wissen muss, würde ich es vorerst transpilieren, um maximale Unterstützung zu erhalten.
Wenn Ihr Modul jedoch wie Koa Kompatibilität mit Benutzern erfordert, die ES6-Funktionen verwenden, ist die Lösung mit zwei Paketen möglicherweise die bessere Idee.
Wegbringen
require( 'your-package' )
Arbeiten benötigen .quelle
require( 'package' )
die Arbeit erforderlich sind . Ich werde meine Antwort bearbeiten, um dies klarer zu machen. Trotzdem ist Joses Antwort viel besser als meine.Der Hauptschlüssel
package.json
entscheidet über den Einstiegspunkt in das Paket, sobald es veröffentlicht ist. So können Sie die Ausgabe Ihres Babel platzieren, wo immer Sie möchten, und müssen nur den richtigen Pfad in dermain
Taste angeben.Hier ist ein gut geschriebener Artikel zum Veröffentlichen eines npm-Pakets
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Hier ist ein Beispiel-Repo, das Sie als Referenz verwenden können
https://github.com/flexdinesh/npm-module-boilerplate
quelle
import
direkt verfügbaren NPM-Modulen veröffentlichen können (und sollten) , ohne Babel oder andere Transpiler zu benötigen.Abhängig von der Anatomie Ihres Moduls funktioniert diese Lösung möglicherweise nicht. Wenn Ihr Modul jedoch in einer einzelnen Datei enthalten ist und keine Abhängigkeiten aufweist (kein Import verwendet wird ), können Sie Ihren Code mithilfe des folgenden Musters so wie er ist freigeben und können mit Import importiert werden (Browser ES6-Module) und erfordern (Node CommonJS-Module)
Als Bonus ist es geeignet, mit einem SCRIPT-HTML-Element importiert zu werden.
main.js :
my-module.js :
package.json : `
Um Ihr Modul zu verwenden, können Sie jetzt die reguläre Syntax verwenden ...
Beim Import in NODE ...
Beim Import in BROWSER ...
Oder auch wenn es mit einem HTML-Skriptelement enthalten ist ...
quelle
Ein paar zusätzliche Hinweise für alle, die eigene Module direkt von Github verwenden und keine veröffentlichten Module durchgehen :
Der ( weit verbreitete ) "Prepublish" -Haken tut nichts für Sie.
Das Beste, was man tun kann (wenn man sich auf Github-Repos verlassen will, nicht auf veröffentlichte Sachen):
src
von .npmignore aufheben (mit anderen Worten: zulassen). Wenn Sie keine haben.npmignore
, denken Sie daran: Eine Kopie von.gitignore
wird stattdessen am installierten Speicherort verwendet, wiels node_modules/yourProject
Sie sehen werden.babel-cli
Stellen Sie sicher, dass es sich um eine Abhängigkeit in Ihrem Modul handelt, nicht nur um eine devDepenceny, da Sie tatsächlich auf der konsumierenden Maschine aufbauen, die auch auf dem Computer des App-Entwicklers bekannt ist, der Ihr Modul verwendetMach das Build-Ding im Installations-Hook, dh:
"install": "babel src -d lib -s"
(kein Mehrwert beim Versuch einer "Vorinstallation", dh babel-cli fehlt möglicherweise)
quelle
npm pack
Ausgabe hochladen und von ihr abhängig machen , 3) die Build-Ausgabe einchecken.