Eu estava prestes a publicar um módulo no NPM, quando pensei em reescrevê-lo no ES6, para prepará-lo para o futuro e aprender o ES6. Eu usei o Babel para transpilar para o ES5 e executar testes. Mas não tenho certeza de como proceder:
- Transpile e publico a pasta resultante / out no NPM?
- Incluo a pasta de resultados no meu repositório do Github?
- Ou mantenho 2 repositórios, um com o código ES6 + script gulp para o Github e outro com os resultados transpilados + testes para o NPM?
Resumindo: quais etapas eu preciso seguir para publicar um módulo escrito no ES6 para o NPM, enquanto ainda permito que as pessoas navegem / bifurcem o código original?
javascript
node.js
npm
ecmascript-6
babeljs
Travelling Tech Guy
fonte
fonte
Respostas:
O padrão que eu vi até agora é manter os arquivos es6 em um
src
diretório e criar suas coisas na pré-publicação do npm nolib
diretórioVocê precisará de um arquivo .npmignore, semelhante ao .gitignore, mas ignorando em
src
vez delib
.fonte
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Isso deve garantir que as instalações não falhem ao implantar em novos ambientes..npmignore
você pode usar ofiles
campo em package.json . Permite especificar exatamente os arquivos que você deseja publicar, em vez de procurar arquivos aleatórios que não deseja publicar.Eu gosto da resposta do José. Notei que vários módulos já seguem esse padrão. Veja como você pode implementá-lo facilmente com o Babel6. Eu instalo
babel-cli
localmente para que a compilação não seja interrompida se eu mudar minha versão global do babel..npmignore
.gitignore
Instale Babel
package.json
fonte
scripts
serãonode_modules/.bin
adicionados aos seus$PATH
e, comobabel-cli
instala um binário,node_modules/.bin/babel
não há necessidade de referenciar o comando pelo caminho.prepublish
é problemática porque poderia correr no momento da instalação ( github.com/npm/npm/issues/3059 ), preferem o mais idiomáticaversion
gancho de roteiro ( docs.npmjs.com/cli/version )prepublish
ainda está lá. No momento, penso que compila manualmente osrc
diretório enpm publish
é o caminho a percorrer.prepublishOnly
gancho de script (consulte docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Observe que na versão 5 do npm isso deve funcionar conforme o esperado, mas por enquanto (supondo que você esteja usando o npm v4 +) isso deve funcionar.prepublish
é executado antespublish
(obv.), Que envia as coisas para npm (ou onde quer que você configure). Então é para a construção o que se passa no pacote NPM, mesmo se não for o check-in.TL; DR - não, até ~ outubro de 2019. O Node.js Módulos equipe tem perguntou :
Atualização de maio de 2019
Desde 2015, quando essa pergunta foi feita, o suporte a JavaScript para módulos amadureceu significativamente e, espero, permanecerá oficialmente estável em outubro de 2019. Todas as outras respostas agora estão obsoletas ou muito complicadas. Aqui está a situação atual e as melhores práticas.
Suporte ES6
99% do ES6 (também conhecido como 2015) é suportado pelo Node desde a versão 6 . A versão atual do Node é 12. Todos os navegadores perenes suportam a grande maioria dos recursos do ES6. O ECMAScript está agora na versão 2019 , e o esquema de versão agora favorece o uso de anos.
Módulos ES (também conhecidos como módulos ECMAScript) nos navegadores
Todos os verdes navegadores foram apoiar
import
-ing módulos ES6 desde 2017. importações dinâmicos são suportados pelo Chrome (+ garfos como Opera e Samsung Internet) e Safari. O suporte ao Firefox está previsto para a próxima versão, 67.Você não precisa mais do Webpack / rollup / Parcel etc. para carregar os módulos. Eles ainda podem ser úteis para outros fins, mas não são necessários para carregar seu código. Você pode importar diretamente URLs apontando para o código dos módulos ES.
Módulos ES no Nó
Os módulos ES (
.mjs
arquivos comimport
/export
) são suportados desde o Nó v8.5.0 chamandonode
com o--experimental-modules
sinalizador. O nó v12, lançado em abril de 2019, reescreveu o suporte aos módulos experimentais. A mudança mais visível é que a extensão do arquivo precisa ser especificada por padrão ao importar:Observe as
.mjs
extensões obrigatórias por toda parte. Correr como:O lançamento do nó 12 é também quando a Equipe de Módulos perguntou desenvolvedores de não publicar pacotes de módulos ES destinado ao uso por Node.js até que uma solução seja encontrada para o uso de pacotes via tanto
require('pkg')
eimport 'pkg'
. Você ainda pode publicar módulos ES nativos destinados a navegadores.Suporte ao ecossistema de módulos ES nativos
Em maio de 2019, o suporte ao ecossistema para os Módulos ES é imaturo. Por exemplo, estruturas de teste como Jest e Ava não suportam
--experimental-modules
. Você precisa usar um transpiler e, em seguida, deve decidir entre usar aimport { symbol }
sintaxe import ( ) nomeada (que ainda não funcionará com a maioria dos pacotes npm) e a sintaxe padrão de importação (import Package from 'package'
), que funciona, mas não quando Babel a analisa. para pacotes criados no TypeScript (graphql-tools, node-influx, faast etc.) No entanto, existe uma solução alternativa que funciona com--experimental-modules
e se Babel transpila seu código para que você possa testá-lo com Jest / Ava / Mocha etc:Indiscutivelmente feio, mas dessa maneira você pode escrever seu próprio código de módulo ES com
import
/export
e executá-lo comnode --experimental-modules
, sem transpilers. Se você tiver dependências que ainda não estão preparadas para o ESM, importe-as como acima, e poderá usar estruturas de teste e outras ferramentas via Babel.Resposta anterior à pergunta - lembre-se, não faça isso até o Node resolver o problema de solicitação / importação, esperamos que em outubro de 2019.
Publicando módulos ES6 para npm, com compatibilidade com versões anteriores
Para publicar um módulo ES no npmjs.org para que ele possa ser importado diretamente, sem Babel ou outros transpilers, basta apontar o
main
campopackage.json
para o.mjs
arquivo, mas omita a extensão:Essa é a única mudança. Ao omitir a extensão, o Node procurará primeiro um arquivo mjs se for executado com --experimental-modules. Caso contrário, ele retornará ao arquivo .js, portanto, seu processo de transpilação existente para suportar versões mais antigas do Node funcionará como antes - apenas aponte Babel para o
.mjs
(s) arquivo (s).Aqui está a fonte de um módulo ES nativo com compatibilidade com versões anteriores para o Nó <8.5.0 que publiquei no NPM. Você pode usá-lo agora mesmo, sem Babel ou qualquer outra coisa.
Instale o módulo:
Crie um arquivo de teste test.mjs :
Execute o nó (v8.5.0 +) com o sinalizador --experimental-modules:
TypeScript
Se você desenvolver no TypeScript, poderá gerar o código ES6 e usar os módulos ES6:
Em seguida, é necessário renomear a
*.js
saída para.mjs
, um problema conhecido que, esperançosamente, será corrigido em breve paratsc
que os.mjs
arquivos sejam gerados diretamente.fonte
mjs
arquivos. O Node.js planeja lançar o suporte oficial em outubro de 2019, que é o primeiro que eu revisitaria seriamente.@Jose está certo. Não há nada de errado em publicar o ES6 / ES2015 no NPM, mas isso pode causar problemas, especialmente se a pessoa que usa o seu pacote estiver usando o Webpack, por exemplo, porque normalmente as pessoas ignoram a
node_modules
pasta durante o pré-processamentobabel
por motivos de desempenho.Então, é só usar
gulp
,grunt
ou simplesmente Node.js para construir umalib
pasta que é ES5.Aqui está o meu
build-lib.js
script, que eu mantenho./tools/
(nãogulp
ougrunt
aqui):Aqui está um último conselho: você precisa adicionar um .npmignore ao seu projeto . Se
npm publish
não encontrar esse arquivo, ele será usado.gitignore
, o que causará problemas, porque normalmente o.gitignore
arquivo será excluído./lib
e incluído./src
, exatamente o oposto do que você deseja ao publicar no NPM. o.npmignore
arquivo tem basicamente a mesma sintaxe de.gitignore
(AFAIK).fonte
.npmignore
você pode usar ofiles
campo em package.json . Permite especificar exatamente os arquivos que você deseja publicar, em vez de procurar arquivos aleatórios que não deseja publicar..npmignore
, tentepackage.json
, emfiles
vez disso, consulte: github.com/c-hive/guides/blob/master/js/…Seguindo a abordagem de José e Marius, (com atualização da versão mais recente de Babel em 2019): Mantenha os arquivos JavaScript mais recentes em um diretório src e construa com o
prepublish
script e a saída do npm no diretório lib..npmignore
.gitignore
Instale o Babel (versão 7.5.5 no meu caso)
package.json
E eu tenho
src/index.js
que usa a função de seta:Aqui está o repositório no GitHub .
Agora você pode publicar o pacote:
Antes que o pacote seja publicado no npm, você verá que
lib/index.js
foi gerado, que é transpilado para es5:[Atualização para empacotador de rollup]
Conforme solicitado pelo @kyw, como você integraria o empacotador de Rollup?
Primeiro, instale
rollup
erollup-plugin-babel
Segundo, crie
rollup.config.js
no diretório raiz do projetoPor fim, atualize
prepublish
empackage.json
Agora você pode correr
npm publish
e, antes que o pacote seja publicado no npm, você verá que lib / index.js foi gerado, transpilado para es5:Nota: a propósito, você não precisa mais
@babel/cli
se estiver usando o empacotador de Rollup. Você pode desinstalá-lo com segurança:fonte
Se você quiser ver isso em ação em um módulo Node de código aberto pequeno e muito simples, dê uma olhada no enésimo dia (que eu iniciei - também em outros colaboradores). Procure no arquivo package.json e na etapa de pré-publicação, que o levará a onde e como fazer isso. Se você clonar esse módulo, poderá executá-lo localmente e usá-lo como modelo para você.
fonte
O Node.js. 13.2.0+ suporta o ESM sem o sinalizador experimental e existem algumas opções para publicar pacotes NPM híbridos (ESM e CommonJS) (dependendo do nível de compatibilidade com versões anteriores necessário): https://2ality.com/2019 /10/hybrid-npm-packages.html
Eu recomendo seguir a maneira completa de compatibilidade com versões anteriores para facilitar o uso do seu pacote. Isso pode ter a seguinte aparência:
O pacote híbrido possui os seguintes arquivos:
mypkg/package.json
Importando do CommonJS:
Importando do ESM:
Fizemos uma investigação sobre o suporte ao ESM em 05.2019 e descobrimos que muitas bibliotecas estavam sem suporte (daí a recomendação para compatibilidade com versões anteriores):
.mjs
arquivos[email protected]
.mjs
arquivos:fonte
Os dois critérios de um pacote NPM é que ele é utilizável com nada mais que
require( 'package' )
ae faz algo que é software-ish.Se você cumprir esses dois requisitos, poderá fazer o que quiser. Mesmo que o módulo seja escrito no ES6, se o usuário final não precisar saber disso, eu o transpilaria por enquanto para obter o máximo suporte.
No entanto, se, como o koa , seu módulo exigir compatibilidade com usuários que usam os recursos do ES6, talvez a solução com dois pacotes seja uma idéia melhor.
Leve embora
require( 'your-package' )
trabalho.fonte
require( 'package' )
trabalho. Vou editar minha resposta para deixar isso mais claro. Dito isto, a resposta de Jose é muito melhor que a minha.A chave principal
package.json
decide o ponto de entrada para o pacote, uma vez publicado. Assim, você pode colocar a saída do seu Babel onde quiser e apenas mencionar o caminho certo namain
chave.Aqui está um artigo bem escrito sobre como publicar um pacote npm
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Aqui está um exemplo de repositório que você pode usar como referência
https://github.com/flexdinesh/npm-module-boilerplate
fonte
import
capazes diretamente, sem a necessidade de Babel ou outros transpiladores.Dependendo da anatomia do seu módulo, esta solução pode não funcionar, mas se o seu módulo estiver contido em um único arquivo e não tiver dependências (não utiliza importação ), usando o padrão a seguir, você pode liberar seu código como está. , e poderá ser importado com a importação (Módulos do Navegador ES6) e exigir (Módulos CommonJS do Nó)
Como bônus, será possível importar com o uso de um elemento HTML SCRIPT.
main.js :
my-module.js :
package.json : `
Para usar seu módulo, agora você pode usar a sintaxe regular ...
Quando importado no NODE ...
Quando importado no BROWSER ...
Ou mesmo quando incluído usando um elemento de script HTML ...
fonte
Algumas notas extras para qualquer pessoa, usando módulos próprios diretamente do github, sem passar pelos módulos publicados :
O gancho "pré-publicar" ( amplamente utilizado ) não está fazendo nada por você.
A melhor coisa que se pode fazer (se planeja confiar nos repositórios do github, não nas coisas publicadas):
src
a partir .npmignore (em outras palavras: permitir que ele). Se você não tiver um.npmignore
, lembre-se: Uma cópia.gitignore
será usada no local instalado, comols node_modules/yourProject
será mostrado.babel-cli
é uma dependência do seu módulo, não apenas uma devDepenceny, pois você está realmente desenvolvendo a máquina consumidora, também conhecida no computador dos desenvolvedores de aplicativos, que está usando o seu módulofaça o build, no gancho de instalação, ou seja:
"install": "babel src -d lib -s"
(nenhum valor agregado ao tentar algo "pré-instalação", ou seja, pode estar faltando babel-cli)
fonte
npm pack
saída, 3) verificar a saída da compilação.