J'étais sur le point de publier un module sur NPM, lorsque j'ai pensé à le réécrire dans ES6, à la fois pour le pérenniser et pour apprendre ES6. J'ai utilisé Babel pour transpiler vers ES5 et exécuter des tests. Mais je ne sais pas trop comment procéder:
- Dois-je transpiler et publier le dossier résultant / de sortie sur NPM?
- Dois-je inclure le dossier de résultats dans mon dépôt Github?
- Ou dois-je maintenir 2 dépôts, un avec le code ES6 + le script gulp pour Github, et un avec les résultats transpilés + les tests pour NPM?
En bref: quelles étapes dois-je suivre pour publier un module écrit en ES6 sur NPM, tout en permettant aux gens de parcourir / fourcher le code d'origine?
javascript
node.js
npm
ecmascript-6
babeljs
Tech Guy itinérant
la source
la source
Réponses:
Le modèle que j'ai vu jusqu'à présent est de conserver les fichiers es6 dans un
src
répertoire et de créer vos éléments dans la prépublication de npm dans lelib
répertoire.Vous aurez besoin d'un fichier .npmignore, similaire à .gitignore mais ignorant
src
au lieu delib
.la source
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Cela devrait garantir que les installations n'échouent pas lors du déploiement dans de nouveaux environnements..npmignore
vous pouvez utiliser lefiles
champ dans package.json . Il vous permet de spécifier exactement les fichiers que vous souhaitez publier, au lieu de rechercher des fichiers aléatoires que vous ne souhaitez pas publier.J'aime la réponse de José. J'ai déjà remarqué que plusieurs modules suivent ce modèle. Voici comment vous pouvez facilement l'implémenter avec Babel6. J'installe
babel-cli
localement pour que la construction ne casse pas si jamais je change ma version globale de babel..npmignore
.gitignore
Installez Babel
package.json
la source
scripts
serontnode_modules/.bin
ajoutées à leur$PATH
et depuisbabel-cli
installe un binaire,node_modules/.bin/babel
il n'est pas nécessaire de référencer la commande par chemin.prepublish
pose problème car il pourrait s'exécuter au moment de l'installation ( github.com/npm/npm/issues/3059 ), préférez leversion
hook de script plus idiomatique ( docs.npmjs.com/cli/version )prepublish
soit toujours là. Pour le moment, je pense compiler manuellement lesrc
répertoire etnpm publish
c'est la voie à suivre.prepublishOnly
hook de script (voir docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Notez que dans la version 5 de npm, cela devrait fonctionner comme prévu, mais pour le moment (en supposant que vous utilisez npm v4 +), cela devrait fonctionner.prepublish
s'exécute avantpublish
(obv.), Ce qui pousse les choses vers npm (ou partout où vous configurez). C'est donc pour créer ce qui se trouve dans le package NPM, même s'il n'est pas enregistré.TL; DR - Ne le faites pas, jusqu'au ~ octobre 2019. L' équipe des modules Node.js a demandé :
Mise à jour de mai 2019
Depuis 2015, date à laquelle cette question a été posée, la prise en charge de JavaScript pour les modules a considérablement mûri et, espérons-le, sera officiellement stable en octobre 2019. Toutes les autres réponses sont désormais obsolètes ou trop compliquées. Voici la situation actuelle et les meilleures pratiques.
Prise en charge ES6
99% de ES6 (aka 2015) est pris en charge par Node depuis la version 6 . La version actuelle de Node est 12. Tous les navigateurs Evergreen prennent en charge la grande majorité des fonctionnalités ES6. ECMAScript est maintenant à la version 2019 , et le schéma de gestion des versions favorise désormais l'utilisation des années.
Modules ES (également appelés modules ECMAScript) dans les navigateurs
Tous les navigateurs Evergreen prennent en charge les
import
modules ES6 depuis 2017. Les importations dynamiques sont prises en charge par Chrome (+ forks comme Opera et Samsung Internet) et Safari. La prise en charge de Firefox est prévue pour la prochaine version, 67.Vous n'avez plus besoin de Webpack / rollup / Parcel etc. pour charger des modules. Ils peuvent être encore utiles à d'autres fins, mais ne sont pas nécessaires pour charger votre code. Vous pouvez importer directement des URL pointant vers le code des modules ES.
Modules ES dans Node
Les modules ES (
.mjs
fichiers avecimport
/export
) sont pris en charge depuis Node v8.5.0 en appelantnode
avec l'--experimental-modules
indicateur. Node v12, sorti en avril 2019, a réécrit le support des modules expérimentaux. Le changement le plus visible est que l'extension de fichier doit être spécifiée par défaut lors de l'importation:Notez les
.mjs
extensions obligatoires partout. Courir comme:La version Node 12 correspond également au moment où l'équipe des modules a demandé aux développeurs de ne pas publier de packages de modules ES destinés à être utilisés par Node.js jusqu'à ce qu'une solution soit trouvée pour utiliser les packages via
require('pkg')
etimport 'pkg'
. Vous pouvez toujours publier des modules ES natifs destinés aux navigateurs.Prise en charge de l'écosystème des modules ES natifs
En mai 2019, le support de l'écosystème pour les modules ES est immature. Par exemple, les frameworks de test comme Jest et Ava ne prennent pas en charge
--experimental-modules
. Vous devez utiliser un transpilateur, et devez ensuite décider entre utiliser laimport { symbol }
syntaxe nommée import ( ) (qui ne fonctionnera pas encore avec la plupart des packages npm) et la syntaxe d'importation par défaut (import Package from 'package'
), qui fonctionne, mais pas lorsque Babel l'analyse pour les paquets créés en TypeScript (graphql-tools, node-influx, faast etc.) Il existe cependant une solution de contournement qui fonctionne à la fois avec--experimental-modules
et si Babel transpile votre code afin que vous puissiez le tester avec Jest / Ava / Mocha etc:Sans doute moche, mais de cette façon, vous pouvez écrire votre propre code de modules ES avec
import
/export
et l'exécuter avecnode --experimental-modules
, sans transpilers. Si vous avez des dépendances qui ne sont pas encore prêtes pour ESM, importez-les comme ci-dessus, et vous pourrez utiliser des frameworks de test et d'autres outils via Babel.Réponse précédente à la question - rappelez-vous, ne le faites pas tant que Node n'a pas résolu le problème de demande / importation, espérons-le vers octobre 2019.
Publication de modules ES6 sur npm, avec compatibilité descendante
Pour publier un module ES sur npmjs.org afin qu'il puisse être importé directement, sans Babel ou d'autres transpileurs, pointez simplement le
main
champ de votrepackage.json
vers le.mjs
fichier, mais omettez l'extension:C'est le seul changement. En omettant l'extension, Node recherchera d'abord un fichier mjs s'il est exécuté avec --experimental-modules. Sinon, il reviendra au fichier .js, donc votre processus de transpilation existant pour prendre en charge les anciennes versions de Node fonctionnera comme avant - assurez-vous simplement de pointer Babel vers le ou les
.mjs
fichiers.Voici la source d'un module ES natif avec rétrocompatibilité pour Node <8.5.0 que j'ai publié sur NPM. Vous pouvez l'utiliser dès maintenant, sans Babel ou autre chose.
Installez le module:
Créez un fichier test test.mjs :
Exécutez le nœud (v8.5.0 +) avec l'indicateur --experimental-modules:
Manuscrit
Si vous développez en TypeScript, vous pouvez générer du code ES6 et utiliser des modules ES6:
Ensuite, vous devez renommer la
*.js
sortie en.mjs
, un problème connu qui, espérons-le, sera bientôt résolu afin detsc
pouvoir générer.mjs
directement les fichiers.la source
mjs
fichiers. Node.js prévoit de déployer un support officiel en octobre 2019, ce qui est le premier que je revois sérieusement.@Jose a raison. Il n'y a rien de mal à publier ES6 / ES2015 sur NPM, mais cela peut causer des problèmes, en particulier si la personne qui utilise votre package utilise Webpack, par exemple, car normalement les gens ignorent le
node_modules
dossier lors du prétraitement avecbabel
pour des raisons de performances.Donc, utilisez simplement
gulp
,grunt
ou simplement Node.js pour créer unlib
dossier qui est ES5.Voici mon
build-lib.js
script, dans lequel je garde./tools/
(nongulp
ougrunt
ici):Voici un dernier conseil: vous devez ajouter un .npmignore à votre projet . S'il
npm publish
ne trouve pas ce fichier, il l'utilisera à la.gitignore
place, ce qui vous posera des problèmes car normalement votre.gitignore
fichier sera exclu./lib
et inclus./src
, ce qui est exactement le contraire de ce que vous voulez lorsque vous publiez sur NPM. Le.npmignore
fichier a fondamentalement la même syntaxe que.gitignore
(AFAIK).la source
.npmignore
vous pouvez utiliser lefiles
champ dans package.json . Il vous permet de spécifier exactement les fichiers que vous souhaitez publier, au lieu de rechercher des fichiers aléatoires que vous ne souhaitez pas publier..npmignore
, essayerpackage.json
« s à lafiles
place, voir: github.com/c-hive/guides/blob/master/js/...Suivant l'approche de José et Marius, (avec mise à jour de la dernière version de Babel en 2019): Conservez les derniers fichiers JavaScript dans un répertoire src, et construisez avec le
prepublish
script de npm et sortez dans le répertoire lib..npmignore
.gitignore
Installer Babel (version 7.5.5 dans mon cas)
package.json
Et j'ai
src/index.js
qui utilise la fonction de flèche:Voici le dépôt sur GitHub .
Vous pouvez maintenant publier le package:
Avant que le package ne soit publié sur npm, vous verrez qu'il
lib/index.js
a été généré, qui est transpilé en es5:[Update for Rollup bundler]
Comme demandé par @kyw, comment intégreriez-vous le bundler Rollup?
Tout d'abord, installez
rollup
etrollup-plugin-babel
Deuxièmement, créez
rollup.config.js
dans le répertoire racine du projetEnfin, mettez
prepublish
à jour danspackage.json
Maintenant, vous pouvez exécuter
npm publish
, et avant que le paquet ne soit publié sur npm, vous verrez que lib / index.js a été généré, qui est transpilé en es5:Remarque: en passant, vous n'en avez plus besoin
@babel/cli
si vous utilisez le bundler Rollup. Vous pouvez le désinstaller en toute sécurité:la source
Si vous voulez voir cela en action dans un petit module Node open source très simple, jetez un œil à nth-day (que j'ai commencé - également d'autres contributeurs). Regardez dans le fichier package.json et à l'étape de pré-publication qui vous mènera à où et comment faire cela. Si vous clonez ce module, vous pouvez l'exécuter localement et l'utiliser comme modèle pour vous.
la source
Node.js 13.2.0+ prend en charge ESM sans l'indicateur expérimental et il existe quelques options pour publier des packages NPM hybrides (ESM et CommonJS) (en fonction du niveau de compatibilité descendante nécessaire): https://2ality.com/2019 /10/hybrid-npm-packages.html
Je recommande d'utiliser la méthode de compatibilité descendante complète pour faciliter l'utilisation de votre package. Cela pourrait ressembler à ceci:
Le package hybride contient les fichiers suivants:
mypkg/package.json
Importation depuis CommonJS:
Importation depuis ESM:
Nous avons fait une enquête sur le support ESM en 05.2019 et avons constaté que de nombreuses bibliothèques manquaient de support (d'où la recommandation de compatibilité descendante):
.mjs
fichiers[email protected]
.mjs
fichiers:la source
Les deux critères d'un package NPM sont qu'il est utilisable avec rien de plus qu'un
require( 'package' )
et fait quelque chose de logiciel-ish.Si vous remplissez ces deux conditions, vous pouvez faire ce que vous voulez. Même si le module est écrit en ES6, si l'utilisateur final n'a pas besoin de le savoir, je le transpilerais pour l'instant pour obtenir un support maximal.
Cependant, si, comme koa , votre module nécessite une compatibilité avec les utilisateurs utilisant les fonctionnalités ES6, la solution à deux packages serait peut-être une meilleure idée.
À emporter
require( 'your-package' )
fonctionner.la source
require( 'package' )
au fonctionnement. Je vais modifier ma réponse pour que cela soit plus clair. Cela dit, la réponse de Jose est bien meilleure que la mienne.La clé principale
package.json
décide du point d'entrée du package une fois qu'il est publié. Ainsi, vous pouvez placer la sortie de votre Babel où vous voulez et avoir juste à mentionner le bon chemin dans lamain
clé.Voici un article bien écrit sur la façon de publier un package npm
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Voici un exemple de dépôt que vous pouvez utiliser comme référence
https://github.com/flexdinesh/npm-module-boilerplate
la source
import
capables directement sans avoir besoin de Babel ou de tout autre transpileur.En fonction de l'anatomie de votre module, cette solution peut ne pas fonctionner, mais si votre module est contenu dans un seul fichier, et n'a pas de dépendances (n'utilise pas l' importation ), en utilisant le modèle suivant, vous pouvez publier votre code tel quel , et pourra être importé avec import (modules du navigateur ES6) et nécessiter (modules Node CommonJS)
En prime, il pourra être importé à l'aide d'un élément HTML SCRIPT.
main.js :
mon-module.js :
package.json : `
Pour utiliser votre module, vous pouvez désormais utiliser la syntaxe régulière ...
Lors de l'importation dans NODE ...
Lors de l'importation dans le NAVIGATEUR ...
Ou même lorsqu'il est inclus à l'aide d'un élément de script HTML ...
la source
Quelques notes supplémentaires pour tout le monde, en utilisant ses propres modules directement depuis github, sans passer par les modules publiés :
Le hook ( largement utilisé ) "Prepublish" ne fait rien pour vous.
La meilleure chose à faire (si vous prévoyez de s'appuyer sur des dépôts github, pas sur des éléments publiés):
src
de .npmignore (en d'autres termes: autorisez-le). Si vous n'en avez pas.npmignore
, rappelez-vous: Une copie de.gitignore
sera utilisée à la place dans l'emplacement d'installation, comme vous lels node_modules/yourProject
verrez.babel-cli
que votre module est une dépendance, pas seulement un devDepenceny puisque vous construisez en effet sur la machine consommatrice, c'est-à-dire sur l'ordinateur des développeurs d'applications, qui utilise votre modulefaire la construction, dans le crochet d'installation, c'est-à-dire:
"install": "babel src -d lib -s"
(aucune valeur ajoutée en essayant quoi que ce soit de "préinstall", c'est-à-dire que babel-cli pourrait manquer)
la source
npm pack
sortie, 3) archiver la sortie de la construction.