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
srcdirectorio y construir sus cosas en la publicación previa de npm en ellibdirectorio.Necesitará un archivo .npmignore, similar a .gitignore pero ignorando en
srclugar 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..npmignoreusted, puede usar elfilescampo 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-clilocalmente 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
scriptshabránode_modules/.binagregado a su$PATHy desde quebabel-cliinstala un binarionode_modules/.bin/babelno hay necesidad de hacer referencia al comando por ruta.prepublishes problemático porque podría ejecutarse en el momento de la instalación ( github.com/npm/npm/issues/3059 ), prefiera elversiongancho de script más idiomático ( docs.npmjs.com/cli/version )prepublishsigue ahí. Por el momento creo que compilar manualmente elsrcdirectorio ynpm publishes el camino a seguir.prepublishOnlysecuencia 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.prepublishejecuta 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
importmó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 (
.mjsarchivos conimport/export) han sido soportados desde el Nodo v8.5.0 llamandonodecon la--experimental-modulesbandera. 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
.mjsextensiones 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-modulesy 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/exporty 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
maincampo enpackage.jsonel.mjsarchivo, 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
.mjsarchivos.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
*.jsel nombre de la salida a.mjs, un problema conocido que, con suerte, se solucionará pronto para quetscpueda enviar.mjsarchivos directamente.fuente
mjsarchivos. 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_modulescarpeta durante el preprocesamientobabelpor razones de rendimiento.Entonces, solo use
gulp,grunto simplemente Node.js para construir unalibcarpeta que sea ES5.Aquí está mi
build-lib.jsscript, que guardo./tools/(nogulpogruntaquí):Aquí hay un último consejo: debe agregar un .npmignore a su proyecto . Si
npm publishno encuentra este archivo, lo usará en su.gitignorelugar, lo que le causará problemas porque normalmente su.gitignorearchivo excluirá./libe incluirá./src, que es exactamente lo contrario de lo que desea cuando publica en NPM. El.npmignorearchivo tiene básicamente la misma sintaxis de.gitignore(AFAIK).fuente
.npmignoreusted, puede usar elfilescampo en package.json . Le permite especificar exactamente los archivos que desea publicar, en lugar de buscar archivos aleatorios que no desea publicar..npmignore, intentepackage.jsonen sufileslugar, 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
prepublishscript 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.jsque 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.jsse 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
rollupyrollup-plugin-babelEn segundo lugar, cree
rollup.config.jsen el directorio raíz del proyectoPor último, actualice
prepublishenpackage.jsonAhora 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/clisi 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.jsonImportando 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):
.mjsarchivos[email protected].mjsarchivos: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.jsondecide 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 enmainclave.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
importdirectamente 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):
srcde .npmignore (en otras palabras: permitirlo). Si no tiene un.npmignore, recuerde:.gitignorese utilizará una copia de en su lugar en la ubicación instalada, comols node_modules/yourProjectse mostrará.babel-clisea 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 packsalida, 3) verificar la salida de compilación.