Devo verificar em node_modules para git ao criar um aplicativo node.js no Heroku?

Eu segui as instruções básicas de introdução do node.js no Heroku aqui:

https://devcenter.heroku.com/categories/nodejs

Estas instruções não dizem para você criar um .gitignore node_modules e, portanto, implica que node_modules deve ser registrado no git. Quando incluo node_modules no git, meu aplicativo de introdução foi executado corretamente.

Quando segui o exemplo mais avançado em:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server (source)

Ele me instruiu a adicionar node_modules ao .gitignore. Então eu removi node_modules do git, adicionei ele ao .gitignore e reimplantei. Desta vez, o implantado falhou assim:

-----> Heroku receiving push -----> Node.js app detected -----> Resolving engine versions Using Node.js version: 0.8.2 Using npm version: 1.0.106 -----> Fetching Node.js binaries -----> Vendoring node into slug -----> Installing dependencies with npm Error: npm doesn't work with node v0.8.2 Required: node@0.4 || 0.5 || 0.6 at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23 at Object. (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3) at Module._compile (module.js:449:26) at Object.Module._extensions..js (module.js:467:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.require (module.js:362:17) at require (module.js:378:17) at Object. (/tmp/node-npm-5iGk/cli.js:2:1) at Module._compile (module.js:449:26) Error: npm doesn't work with node v0.8.2 Required: node@0.4 || 0.5 || 0.6 at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23 at Object. (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3) at Module._compile (module.js:449:26) at Object.Module._extensions..js (module.js:467:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.require (module.js:362:17) at require (module.js:378:17) at Object. (/tmp/node-npm-5iGk/cli.js:2:1) at Module._compile (module.js:449:26) Dependencies installed -----> Discovering process types Procfile declares types -> mongod, redis, web -----> Compiled slug size is 5.0MB -----> Launching... done, v9 

Correndo “heroku ps” confirma o acidente. Ok, não há problema, então eu reverti a alteração, adicionei node_module de volta ao repository git e o removi de .gitignore. No entanto, mesmo depois de reverter, ainda recebo a mesma mensagem de erro na implantação, mas agora o aplicativo está sendo executado corretamente novamente. Correndo “heroku ps” me diz que o aplicativo está sendo executado.

Então, minha pergunta é qual é o jeito certo de fazer isso? Inclua node_modules ou não? E por que eu ainda estaria recebendo a mensagem de erro quando retroceder? Meu palpite é que o repository git está em mau estado no lado Heroku?

Segunda atualização

A FAQ não está mais disponível.

Da documentação do shrinkwrap :

Se você deseja bloquear os bytes específicos incluídos em um pacote, por exemplo, para ter 100% de confiança em poder reproduzir uma implantação ou compilation, você deve verificar suas dependencies no controle de origem ou seguir algum outro mecanismo que possa verificar conteúdo, em vez de versões.

Shannon e Steven mencionaram isso antes, mas acho que deveria ser parte da resposta aceita.


Atualizar

A fonte listada para a recomendação abaixo foi atualizada . Eles não estão mais recomendando que a pasta node_modules seja confirmada.

Normalmente não. Permita que o npm resolva as dependencies dos seus pacotes.

Para pacotes que você implanta, como sites e aplicativos, você deve usar o npm shrinkwrap para bloquear toda a tree de dependencies:

https://docs.npmjs.com/cli/shrinkwrap


Postagem original

Para referência, o npm FAQ responde à sua pergunta com clareza:

Verifique node_modules no git para coisas que você implementa, como sites e aplicativos. Não marque node_modules no git para bibliotecas e módulos destinados a serem reutilizados. Use npm para gerenciar dependencies em seu ambiente de desenvolvimento, mas não em seus scripts de implementação.

e por algum bom motivo para isso, leia o post de Mikeal Rogers sobre isso .


Fonte: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git

Minha maior preocupação em não verificar node_modules no git é que node_modules a 10 anos, quando o seu aplicativo de produção ainda estiver em uso, o npm pode não estar por perto. Ou npm pode ficar corrompido; ou os mantenedores podem decidir remover a biblioteca na qual você confia em seu repository; ou a versão que você usa pode ser aparada.

Isso pode ser mitigado com os gerenciadores de repo, como maven, porque você sempre pode usar seu próprio Nexus ou Artifactory local para manter um espelho com os pacotes que você usa. Tanto quanto eu entendo, tal sistema não existe para npm. O mesmo vale para gerentes de biblioteca do lado do cliente, como Bower e Jamjs.

Se você tiver enviado os arquivos para o seu próprio repository do git, poderá atualizá-los quando quiser e terá o conforto de compilações repetíveis e o conhecimento de que seu aplicativo não será interrompido devido a alguma ação de terceiros.

Você não deve include node_modules em seu .gitignore (ou melhor, você deve include node_modules em sua origem implementada no Heroku).

Se node_modules :

  • existe então o npm install utilizará essas bibliotecas vendidas e reconstruirá quaisquer dependencies binárias com a npm rebuild .
  • não existe, então o npm install terá que buscar todas as dependencies, o que adiciona tempo à etapa de compilation do slug.

Veja a fonte do buildpack do Node.js para estas etapas exatas

No entanto, o erro original parece ser uma incompatibilidade entre as versões do npm e do node . É uma boa ideia sempre definir explicitamente a seção de engines de seus packages.json acordo com este guia para evitar esses tipos de situações:

 { "name": "myapp", "version": "0.0.1", "engines": { "node": "0.8.x", "npm": "1.1.x" } } 

Isso garantirá a paridade dev / prod e reduzirá a probabilidade de tais situações no futuro.

Eu ia deixar isso depois deste comentário: Devo verificar em node_modules para git ao criar um aplicativo node.js no Heroku?

Mas stackoverflow estava formatando isso estranho. Se você não tem máquinas idênticas e está verificando em node_modules, faça um .gitignore nas extensões nativas. Nosso .gitignore se parece com:

 # Ignore native extensions in the node_modules folder (things changed by npm rebuild) node_modules/**/*.node node_modules/**/*.o node_modules/**/*.a node_modules/**/*.mk node_modules/**/*.gypi node_modules/**/*.target node_modules/**/.deps/ node_modules/**/build/Makefile node_modules/**/**/build/Makefile 

Teste isso primeiro verificando tudo e depois faça outro dev fazer o seguinte:

 rm -rf node_modules git checkout -- node_modules npm rebuild git status 

Assegure-se de que nenhum arquivo seja alterado.

Acredito que o npm install não deve ser executado em um ambiente de produção. Há várias coisas que podem dar errado – a interrupção do npm, o download de novas dependencies (o shrinkwrap parece resolver isso) são duas delas.

Por outro lado, node_modules não deve ser confirmado no git. Além de seu grande tamanho, os compromissos que os incluem podem se tornar uma distração.

As melhores soluções seriam as seguintes: o npm install deve ser executado em um ambiente de CI que seja semelhante ao ambiente de produção. Todos os testes serão executados e um arquivo de lançamento compactado será criado, incluindo todas as dependencies.

Eu tenho usado tanto comprometendo a pasta node_modules quanto o wrapping shrink. Ambas as soluções não me fizeram feliz.

Em resumo: node_modules comprometidos adicionam muito ruído ao repository.
E o shrinkwrap.json não é fácil de administrar e não há garantia de que algum projeto embrulhado por encolhimento seja construído em alguns anos.

Descobri que o Mozilla estava usando um repository separado para um de seus projetos https://github.com/mozilla-b2g/gaia-node-modules

Então, não demorei muito para implementar essa ideia em uma ferramenta de CLI de nó https://github.com/bestander/npm-git-lock

Pouco antes de cada compilation adicionar
npm-git-lock –repo [git@bitbucket.org: seu / dedicated / node_modules / git / repository.git]

Ele irá calcular o hash do seu pacote.json e verificar o conteúdo do node_modules de um repository remoto ou, se for uma primeira compilation para este pacote.json, fará uma npm install limpa do npm install e npm install os resultados para o npm install remoto.

O que funcionou para mim foi explicitamente adicionar uma versão npm ao package.json (“npm”: “1.1.x”) e NÃO verificar em node_modules para git. Pode ser mais lento de implementar (já que ele baixa os pacotes toda vez), mas eu não consegui fazer os pacotes compilarem quando eles foram registrados. O Heroku estava procurando por arquivos que só existiam na minha checkbox local.

Em vez de verificar em node_modules, crie um arquivo package.json para seu aplicativo.

O arquivo package.json especifica as dependencies do seu aplicativo. O Heroku pode então dizer ao npm para instalar todas essas dependencies. O tutorial ao qual você ligou contém uma seção nos arquivos package.json.

Eu estou usando esta solução:

  1. Crie um repository separado que contenha node_modules . Se você tiver módulos nativos que devem ser criados para uma plataforma específica, crie um repository separado para cada plataforma.
  2. Anexe estes repositorys ao seu repository de projetos com o git submodule :

git submodule add .../your_project_node_modules_windows.git node_modules_windows

git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64

  1. Crie um link de node_modules específico da plataforma para o diretório node_modules e inclua node_modules para .gitignore .
  2. Execute a npm install .
  3. Confirme as alterações do repository do submódulo.
  4. Confirme suas alterações no repository de projetos.

Assim, você pode alternar facilmente entre node_modules em plataformas diferentes (por exemplo, se estiver desenvolvendo no OS X e implementando no Linux).

Em https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html :

Edit: O link original foi este, mas agora está morto. Obrigado @Flavio por apontar isso.

Para recapitular

  • Somente checkin node_modules para aplicativos que você implementa, pacotes não reutilizáveis ​​que você mantém.
  • Quaisquer dependencies compiladas devem ter sua fonte registrada, não os destinos de compilation, e devem $ npm reconstruir na implantação.

Minha parte favorita:

Todas as pessoas que adicionaram node_modules ao seu gitignore, removam essa merda, hoje , é um artefato de uma era que estamos muito felizes em deixar para trás. A era dos módulos globais está morta.

http://nodejs.org/api/modules.html

[…] o nó começa no diretório pai do módulo atual e adiciona /node_modules e tenta carregar o módulo a partir desse local.

Se não for encontrado lá, ele será movido para o diretório pai, e assim por diante , até que a raiz da tree seja alcançada.

Se você estiver aplicando seus próprios módulos específicos ao seu aplicativo, poderá mantê-los ( e somente esses ) nos /node_modules seu aplicativo. E mova todas as outras dependencies para o diretório pai.

Este caso de uso de bastante impressionante permite que você mantenha os módulos criados especificamente para o seu aplicativo com o seu aplicativo e não sobrecarregue o aplicativo com dependencies que podem ser instaladas posteriormente.