Estaba a punto de publicar un módulo en NPM, cuando pensé en reescribirlo en ES6, para prepararlo en el futuro y aprender ES6. He usado Babel para transpilar a ES5 y ejecutar pruebas. Pero no estoy seguro de cómo proceder:
- ¿Transpilo y publico la carpeta resultante / fuera en NPM?
- ¿Incluyo la carpeta de resultados en mi repositorio de Github?
- ¿O mantengo 2 repositorios, uno con el código ES6 + script gulp para Github y otro con los resultados transpilados + pruebas para NPM?
En resumen: ¿qué pasos debo seguir para publicar un módulo escrito en ES6 en NPM, y al mismo tiempo permitir que la gente explore / bifurque el código original?
javascript
node.js
npm
ecmascript-6
babeljs
Travelling Tech Guy
fuente
fuente
Respuestas:
El patrón que he visto hasta ahora es mantener los archivos es6 en un
src
directorio y construir sus cosas en la publicación previa de npm en ellib
directorio.Necesitará un archivo .npmignore, similar a .gitignore pero ignorando en
src
lugar delib
.fuente
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Esto debería garantizar que las instalaciones no fallen al implementar en nuevos entornos..npmignore
usted, puede usar elfiles
campo en package.json . Le permite especificar exactamente los archivos que desea publicar, en lugar de buscar archivos aleatorios que no desea publicar.Me gusta la respuesta de José. He notado que varios módulos siguen ese patrón ya. Así es como puede implementarlo fácilmente con Babel6. Lo instalo
babel-cli
localmente para que la compilación no se rompa si alguna vez cambio mi versión global de babel..npmignore
.gitignore
Instalar Babel
package.json
fuente
scripts
habránode_modules/.bin
agregado a su$PATH
y desde quebabel-cli
instala un binarionode_modules/.bin/babel
no hay necesidad de hacer referencia al comando por ruta.prepublish
es problemático porque podría ejecutarse en el momento de la instalación ( github.com/npm/npm/issues/3059 ), prefiera elversion
gancho de script más idiomático ( docs.npmjs.com/cli/version )prepublish
sigue ahí. Por el momento creo que compilar manualmente elsrc
directorio ynpm publish
es el camino a seguir.prepublishOnly
secuencia de comandos (consulte docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Tenga en cuenta que en la versión 5 de npm esto debería funcionar como se esperaba, pero por ahora (suponiendo que esté usando npm v4 +) esto debería funcionar.prepublish
ejecuta antespublish
(obv.), Lo que lleva las cosas a npm (o donde sea que configure). Así que es para construir lo que incluye el paquete NPM, incluso si no está registrado.TL; DR - No, hasta ~ octubre de 2019. El equipo de módulos de Node.js ha preguntado :
Actualización de mayo de 2019
Desde 2015, cuando se hizo esta pregunta, el soporte de JavaScript para los módulos ha madurado significativamente y esperamos que sea oficialmente estable en octubre de 2019. Todas las demás respuestas ahora son obsoletas o demasiado complicadas. Aquí está la situación actual y las mejores prácticas.
Soporte ES6
El 99% de ES6 (también conocido como 2015) ha sido compatible con Node desde la versión 6 . La versión actual de Node es 12. Todos los navegadores de hoja perenne admiten la gran mayoría de las funciones de ES6. ECMAScript ahora está en la versión 2019 , y el esquema de versiones ahora favorece el uso de años.
Módulos ES (también conocidos como módulos ECMAScript) en navegadores
Todos los navegadores de hoja perenne han sido compatibles con los
import
módulos ES6 desde 2017. Las importaciones dinámicas son compatibles con Chrome (+ tenedores como Opera y Samsung Internet) y Safari. El soporte de Firefox está programado para la próxima versión, 67.Ya no necesita Webpack / rollup / Parcel, etc. para cargar módulos. Pueden seguir siendo útiles para otros fines, pero no están obligados a cargar su código. Puede importar directamente las URL que apuntan al código de los módulos ES.
Módulos ES en Nodo
Los módulos ES (
.mjs
archivos conimport
/export
) han sido soportados desde el Nodo v8.5.0 llamandonode
con la--experimental-modules
bandera. Nodo v12, lanzado en abril de 2019, reescribió el soporte de módulos experimentales. El cambio más visible es que la extensión del archivo debe especificarse de forma predeterminada al importar:Tenga en cuenta las
.mjs
extensiones obligatorias en todo. Correr como:La versión Node 12 también es cuando el Equipo de Módulos solicitó a los desarrolladores que no publiquen paquetes de módulos ES destinados a ser utilizados por Node.js hasta que se encuentre una solución para usar paquetes a través de ambos
require('pkg')
yimport 'pkg'
. Todavía puede publicar módulos ES nativos destinados a navegadores.Soporte de ecosistema de módulos ES nativos
A partir de mayo de 2019, el soporte del ecosistema para los módulos ES es inmaduro. Por ejemplo, los marcos de prueba como Jest y Ava no son compatibles
--experimental-modules
. Debe usar un transpilador, y luego debe decidir entre usar laimport { symbol }
sintaxis nombrada import ( ) (que todavía no funcionará con la mayoría de los paquetes npm), y la sintaxis predeterminada de importación (import Package from 'package'
), que funciona, pero no cuando Babel lo analiza para paquetes creados en TypeScript (graphql-tools, node-influx, faast, etc.) Sin embargo, existe una solución alternativa que funciona con--experimental-modules
y si Babel transpila su código para que pueda probarlo con Jest / Ava / Mocha, etc.Posiblemente feo, pero de esta manera puede escribir su propio código de módulos ES con
import
/export
y ejecutarlo connode --experimental-modules
, sin transpiladores. Si tiene dependencias que aún no están preparadas para ESM, impórtelas como se indica arriba y podrá usar marcos de prueba y otras herramientas a través de Babel.Respuesta previa a la pregunta: recuerde, no haga esto hasta que Node resuelva el problema de requerir / importar, con suerte alrededor de octubre de 2019.
Publicación de módulos ES6 en npm, con compatibilidad con versiones anteriores
Para publicar un módulo ES en npmjs.org para que se pueda importar directamente, sin Babel u otros transpiladores, simplemente apunte el
main
campo enpackage.json
el.mjs
archivo, pero omita la extensión:Ese es el único cambio. Al omitir la extensión, Node buscará primero un archivo mjs si se ejecuta con --experimental-modules. De lo contrario, volverá al archivo .js, por lo que su proceso de transpilación existente para admitir versiones de Nodo anteriores funcionará como antes, solo asegúrese de apuntar a Babel a los
.mjs
archivos.Aquí está la fuente de un módulo ES nativo con compatibilidad con versiones anteriores para Nodo <8.5.0 que publiqué en NPM. Puedes usarlo ahora mismo, sin Babel ni nada más.
Instale el módulo:
Cree un archivo de prueba test.mjs :
Ejecute el nodo (v8.5.0 +) con el indicador --experimental-modules:
Mecanografiado
Si desarrolla en TypeScript, puede generar código ES6 y usar módulos ES6:
Luego, debe cambiar
*.js
el nombre de la salida a.mjs
, un problema conocido que, con suerte, se solucionará pronto para quetsc
pueda enviar.mjs
archivos directamente.fuente
mjs
archivos. Node.js planea lanzar el soporte oficial en octubre de 2019, que es lo primero que volvería a revisar seriamente.@Jose tiene razón. No hay nada de malo en publicar ES6 / ES2015 en NPM, pero eso puede causar problemas, especialmente si la persona que usa su paquete usa Webpack, por ejemplo, porque normalmente las personas ignoran la
node_modules
carpeta durante el preprocesamientobabel
por razones de rendimiento.Entonces, solo use
gulp
,grunt
o simplemente Node.js para construir unalib
carpeta que sea ES5.Aquí está mi
build-lib.js
script, que guardo./tools/
(nogulp
ogrunt
aquí):Aquí hay un último consejo: debe agregar un .npmignore a su proyecto . Si
npm publish
no encuentra este archivo, lo usará en su.gitignore
lugar, lo que le causará problemas porque normalmente su.gitignore
archivo excluirá./lib
e incluirá./src
, que es exactamente lo contrario de lo que desea cuando publica en NPM. El.npmignore
archivo tiene básicamente la misma sintaxis de.gitignore
(AFAIK).fuente
.npmignore
usted, puede usar elfiles
campo en package.json . Le permite especificar exactamente los archivos que desea publicar, en lugar de buscar archivos aleatorios que no desea publicar..npmignore
, intentepackage.json
en sufiles
lugar, vea: github.com/c-hive/guides/blob/master/js/…Siguiendo el enfoque de José y Marius, (con la actualización de la última versión de Babel en 2019): mantenga los archivos JavaScript más recientes en un directorio src, y compile con el
prepublish
script npm y la salida al directorio lib..npmignore
.gitignore
Instalar Babel (versión 7.5.5 en mi caso)
package.json
Y tengo
src/index.js
que usa la función de flecha:Aquí está el repositorio en GitHub .
Ahora puedes publicar el paquete:
Antes de publicar el paquete en npm, verá que
lib/index.js
se ha generado, que se transpila a es5:[Actualización para el paquete acumulativo]
Como preguntó @kyw, ¿cómo integraría el paquete acumulativo?
Primero, instale
rollup
yrollup-plugin-babel
En segundo lugar, cree
rollup.config.js
en el directorio raíz del proyectoPor último, actualice
prepublish
enpackage.json
Ahora puede ejecutar
npm publish
, y antes de que el paquete se publique en npm, verá que se ha generado lib / index.js, que se transpila a es5:Nota: por cierto, ya no necesitas
@babel/cli
si estás usando el paquete acumulativo. Puede desinstalarlo de manera segura:fuente
Si desea ver esto en acción en un módulo Node de código abierto pequeño muy simple, eche un vistazo al enésimo día (que comencé, también a otros contribuyentes). Busque en el archivo package.json y en el paso de prepublicación que lo llevará a dónde y cómo hacerlo. Si clonas ese módulo, puedes ejecutarlo localmente y usarlo como plantilla para ti.
fuente
Node.js 13.2.0+ es compatible con ESM sin el indicador experimental y hay algunas opciones para publicar paquetes NPM híbridos (ESM y CommonJS) (según el nivel de compatibilidad con versiones anteriores necesario): https://2ality.com/2019 /10/hybrid-npm-packages.html
Recomiendo ir a la compatibilidad con versiones anteriores para facilitar el uso de su paquete. Esto podría verse de la siguiente manera:
El paquete híbrido tiene los siguientes archivos:
mypkg/package.json
Importando desde CommonJS:
Importando desde ESM:
Hicimos una investigación sobre el soporte de ESM en 05.2019 y descubrimos que muchas bibliotecas carecían de soporte (de ahí la recomendación de compatibilidad con versiones anteriores):
.mjs
archivos[email protected]
.mjs
archivos:fuente
Los dos criterios de un paquete NPM es que se puede usar con nada más que
require( 'package' )
ay hace algo de software.Si cumple con estos dos requisitos, puede hacer lo que desee. Incluso si el módulo está escrito en ES6, si el usuario final no necesita saber eso, lo transpilaría por ahora para obtener el máximo soporte.
Sin embargo, si como koa , su módulo requiere compatibilidad con usuarios que usan las funciones de ES6, entonces quizás la solución de dos paquetes sería una mejor idea.
Para llevar
require( 'your-package' )
funcione.fuente
require( 'package' )
trabajar. Editaré mi respuesta para aclarar esto. Dicho esto, la respuesta de José es mucho mejor que la mía.La clave principal en
package.json
decide el punto de entrada al paquete una vez publicado. Por lo tanto, puede colocar la salida de su Babel donde quiera y solo tiene que mencionar la ruta correcta enmain
clave.Aquí hay un artículo bien escrito sobre cómo publicar un paquete npm
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Aquí hay un repositorio de muestra que puede usar como referencia
https://github.com/flexdinesh/npm-module-boilerplate
fuente
import
directamente sin requerir Babel ni ningún otro transpilador.Dependiendo de la anatomía de su módulo, esta solución puede no funcionar, pero si su módulo está contenido dentro de un solo archivo y no tiene dependencias (no hace uso de la importación ), con el siguiente patrón puede liberar su código tal como está , y podrá importarse con import (módulos ES6 del navegador) y requerir (módulos Node CommonJS)
Como beneficio adicional, será adecuado importarlo utilizando un elemento HTML SCRIPT.
main.js :
my-module.js :
package.json : `
Para usar su módulo, ahora puede usar la sintaxis regular ...
Cuando se importa en NODE ...
Cuando se importa en NAVEGADOR ...
O incluso cuando se incluye utilizando un elemento de secuencia de comandos HTML ...
fuente
Algunas notas adicionales para cualquier persona, utilizando módulos propios directamente desde github, sin pasar por los módulos publicados :
El gancho ( ampliamente utilizado ) "prepublish" no está haciendo nada por usted.
Lo mejor que se puede hacer (si planea confiar en repositorios de github, no en cosas publicadas):
src
de .npmignore (en otras palabras: permitirlo). Si no tiene un.npmignore
, recuerde:.gitignore
se utilizará una copia de en su lugar en la ubicación instalada, comols node_modules/yourProject
se mostrará.babel-cli
sea una dependencia en su módulo, no solo un DevDepenceny, ya que realmente está construyendo en la máquina consumidora, también conocida como la computadora de los desarrolladores de aplicaciones, que está utilizando su módulohacer lo de compilación, en el gancho de instalación, es decir:
"install": "babel src -d lib -s"
(sin valor agregado al intentar algo "preinstalar", es decir, puede faltar babel-cli)
fuente
npm pack
salida, 3) verificar la salida de compilación.