¿Debería registrar node_modules para git al crear una aplicación node.js en Heroku?

368

Seguí las instrucciones básicas de inicio para node.js en Heroku aquí:

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

Estas instrucciones no le dicen que cree un .gitignore node_modules, y por lo tanto implica que node_modules debe registrarse en git. Cuando incluyo node_modules en git, mi aplicación de inicio se ejecutó correctamente.

Cuando seguí el ejemplo más avanzado en:

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

Me dio instrucciones para agregar node_modules a .gitignore. Así que eliminé node_modules de git, lo agregué a .gitignore y luego lo volví a implementar. Esta vez el desplegado falló así:

-----> 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.<anonymous> (/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.<anonymous> (/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.<anonymous> (/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.<anonymous> (/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

Ejecutar "heroku ps" confirma el bloqueo. Ok, no hay problema, así que revertí el cambio, agregué node_module al repositorio git y lo eliminé de .gitignore. Sin embargo, incluso después de revertir, sigo recibiendo el mismo mensaje de error en la implementación, pero ahora la aplicación se está ejecutando correctamente nuevamente. Ejecutar "heroku ps" me dice que la aplicación se está ejecutando.

Entonces mi pregunta es ¿cuál es la forma correcta de hacer esto? ¿Incluir node_modules o no? ¿Y por qué seguiría recibiendo el mensaje de error cuando retrocedo? Supongo que el repositorio de git está en mal estado en el lado de Heroku.

Jason Griffin
fuente
10
Soy el propietario del lenguaje Node en Heroku y la respuesta es simple: No. No se registre node_modulesen las aplicaciones Heroku.
hunterloftis
@hunterloftis '¿No verifique node_modules en ' o 'No ingrese node_modules en '? Para aclarar, como propietario del lenguaje Node en Heroku, ¿quieres que carguemos todos nuestros node_modules a través de nuestro git push o no? Prefiero no hacerlo debido al desperdicio de ancho de banda y al hecho de que Heroku los pondrá en el backend de mi impulso; sin embargo, tuve que editar archivos en mis node_modules manualmente para que Heroku cargue mi aplicación. Por lo tanto, tuve que ignorar node_modules menos el módulo completo que incluía mi archivo editado para que funcione.
ZStoneDPM

Respuestas:

400

Segunda actualización

Las preguntas frecuentes ya no están disponibles.

De la documentación de shrinkwrap:

Si desea bloquear los bytes específicos incluidos en un paquete, por ejemplo, para tener una confianza del 100% en poder reproducir una implementación o compilación, entonces debe verificar sus dependencias en el control de origen o buscar algún otro mecanismo que pueda verificar contenidos en lugar de versiones.

Shannon y Steven mencionaron esto antes, pero creo que debería ser parte de la respuesta aceptada.


Actualizar

La fuente listada para la siguiente recomendación ha sido actualizada . Ya no recomiendan que se node_modulesconfirme la carpeta.

Usualmente no. Permita que npm resuelva dependencias para sus paquetes.

Para los paquetes que implemente, como sitios web y aplicaciones, debe usar npm shrinkwrap para bloquear su árbol de dependencia completo:

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


Publicación original

Como referencia, npm FAQ responde a su pregunta claramente:

Compruebe node_modules en git para ver las cosas que implementa, como sitios web y aplicaciones. No marque node_modules en git para bibliotecas y módulos destinados a ser reutilizados. Use npm para administrar dependencias en su entorno de desarrollo, pero no en sus scripts de implementación.

y para una buena razón para esto, lea la publicación de Mikeal Rogers sobre esto .


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

Kostia
fuente
13
Esto no es correcto, de hecho es una muy mala idea. Si está desarrollando en Windows y luego implementando en Linux, necesitará reconstruir node_modules cuando implemente. Lo que significa - caos. Muchos archivos modificados, y no tengo idea de qué hacer.
user3690202
8
Eso no es posible: algunos de nuestros desarrolladores desarrollan ventanas de orientación, otras apuntan a Linux, pero la misma base de código. El mejor enfoque sería no comprometer los módulos de nodo: ¡vaya!
user3690202
77
@ user3690202 Parece que tiene un caso poco convencional, en lugar de la norma, por lo que decir "esto no es correcto" es probablemente una exageración. Dicho esto, no estoy seguro de cuál es su caso de uso exacto, pero no puedo pensar en ninguna razón para usar Windows y Linux para el desarrollo. Apéguese a uno y ejecute pruebas o control de calidad en todas las plataformas de su soporte.
Kostia
16
@Kostia Nuestro caso de uso es bastante común. Somos voluntarios y utilizamos nuestras propias máquinas, no las de la empresa. Parece una situación bastante común para el código abierto.
Adam
44
@ Adam tangencialmente, ¿podría agregar los archivos que se están compilando .gitignore? De esa manera, la fuente está en Git, y cualesquiera componentes compilados no son, de manera similar a la forma disto outputcarpetas se gitignored en proyectos de gruñir y trago.
Kostia
160

Mi mayor preocupación por no registrarme node_modulesen git es que dentro de 10 años, cuando su aplicación de producción aún esté en uso, es posible que npm no esté disponible. O npm podría corromperse; o los encargados del mantenimiento podrían decidir eliminar la biblioteca en la que confía de su repositorio; o la versión que usa podría recortarse.

Esto se puede mitigar con administradores de repositorios como maven, porque siempre puedes usar tu propio Nexus o Artifactory local para mantener un espejo con los paquetes que usas. Que yo entienda, ese sistema no existe para npm. Lo mismo ocurre con los administradores de bibliotecas del lado del cliente como Bower y Jamjs.

Si ha enviado los archivos a su propio repositorio de git, puede actualizarlos cuando lo desee, y tiene la comodidad de compilaciones repetibles y el conocimiento de que su aplicación no se romperá debido a alguna acción de terceros.

Jonathan
fuente
10
Muchas opciones hoy: Nexus ( issues.sonatype.org/browse/NEXUS-5852 ), Artifactory ( jfrog.com/jira/browse/RTFACT-5143 ), npm_lazy ( github.com/mixu/npm_lazy ), npm-lazy- espejo ( npmjs.org/package/npm-lazy-mirror ), etc.
Johann
44
Cita de las preguntas frecuentes de npmjs: "Si eres paranoico acerca de depender del ecosistema npm, debes ejecutar un espejo npm privado o un caché privado". Creo que esto apunta al problema al que te refieres, ¿verdad?
Taylan
3
Un caso en el punto developers.slashdot.org/story/16/03/23/0652204/…
prototipo
2
Npm no va a desaparecer de la noche a la mañana, por lo que el beneficio no se combina bien con la pérdida de claridad en su historial de confirmaciones y su gran tamaño de paquete. Si alguien está creando una aplicación que cree que seguirá activa en 10 años, es razonable esperar que reciba mucho mantenimiento en el camino. Sin embargo, el punto sobre las interrupciones de NPM es un argumento mucho mejor, aunque probablemente haya mejores maneras de mitigar ese riesgo que comprometerse con la fuente.
Sam P
3
Incluso un mes más adelante es peligroso si no compromete sus dependencias (preferiblemente en un repositorio separado). Como encontré una mañana cuando cloné uno de mis proyectos y encontré que una versión del paquete había sido eliminada de npm. Pasé medio día cambiando todas mis versiones de dependencias en cascada para que la actualización de npm funcione y vuelva a compilar.
Richard
67

No debe incluir node_modules en su .gitignore(o más bien debe incluir node_modules en su fuente implementada en Heroku).

Si node_modules:

  • existe entonces npm installusará esas librerías vendidas y reconstruirá cualquier dependencia binaria connpm rebuild .
  • no existe, entonces npm installtendrá que buscar todas las dependencias, lo que agrega tiempo al paso de compilación de slug.

Consulte la fuente del paquete de compilación Node.js para conocer estos pasos exactos

Sin embargo, el error original parece ser una incompatibilidad entre las versiones de npmy node. Es una buena idea establecer siempre explícitamenteengines sección de packages.jsonacuerdo con esta guía para evitar este tipo de situaciones:

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

Esto asegurará la paridad de desarrollo / producción y reducirá la probabilidad de tales situaciones en el futuro.

Ryan Daigle
fuente
Gracias por la ayuda Ryan. Eso me pasó el error de la versión npm pero ahora falla al compilar el paquete redis. El mensaje de error es "OSError: [Errno 2] No existe dicho archivo o directorio: '/ Users / Jason / tastemade / tastebase / node_modules / redis-url / node_modules / redis / node_modules / hiredis / build'". Parece que está usando una ruta desde mi casilla local en los servidores heroku. ¿Hay ciertos archivos en los node_modules que necesito agregar a .gitignore?
Jason Griffin
No estoy seguro de lo que está sucediendo con esa biblioteca en particular, pero trataría de excluir node_modules de git en este caso y ver si eso ayuda (forzando a npm a buscar todo por sí mismo y asegurando un entorno de compilación nuevo).
Ryan Daigle
@RyanDaigle La mejor práctica ahora (noviembre de 2013) recomendada por npm ( npmjs.org/doc/… ) y heroku ( devcenter.heroku.com/articles/… ) es registrar node_modules en git. ¿Actualizaría su respuesta (ya que tiene una facturación superior)?
Tim Diggins
Mientras empuja a heroku obtendrá el resultado "-----> Almacenamiento en caché del directorio node_modules para futuras compilaciones". Esto es para acortar la futura compilación de babosas.
ph3nx
Tengo un problema que la ruta de archivo node_modules es demasiado larga para confirmar. Git no encontrará los archivos.
Código Faraón
22

Iba a dejar esto después de este comentario: ¿Debería registrar node_modules para git al crear una aplicación node.js en Heroku?

Pero stackoverflow lo estaba formateando de forma extraña. Si no tiene máquinas idénticas y está registrando node_modules, realice un .gitignore en las extensiones nativas. Nuestro .gitignore se ve así:

# 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

Pruebe esto primero revisando todo, y luego haga que otro desarrollador haga lo siguiente:

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

Asegúrese de que no haya archivos modificados.

ibash
fuente
Acabo de agregar esto. Resuelto mi problema El github de Windows seguía fallando al intentar ir más de 7000+ archivos node_module: /
Batman
10

Creo que npm installno debería ejecutarse en un entorno de producción. Hay varias cosas que pueden salir mal: la interrupción de npm, la descarga de dependencias más nuevas (parece que esto se resuelve), son dos de ellas.

Por otro lado, node_modulesno se debe cometer en git. Además de su gran tamaño, los compromisos que los incluyen pueden ser una distracción.

Las mejores soluciones serían las siguientes: npm installdebe ejecutarse en un entorno de CI que sea similar al entorno de producción. Se ejecutarán todas las pruebas y se creará un archivo de lanzamiento comprimido que incluirá todas las dependencias.

usuario2468170
fuente
¿Por qué tendría un paso que se ejecuta en CI que no se ejecutaría como parte de su implementación? ¡Esto significa que no tienes paridad entre los 2 sistemas! Como dice la respuesta anterior: confirme la carpeta simplemente ignore las extensiones nativas, de esa manera estará cubierto por cosas como interrupciones
npm
1
Gracias por tu comentario. Creo que los node_modules que se ejecutan en su servidor de producción deben generarse a partir de una instalación npm, no a partir de lo que hayan comprometido los desarrolladores. La carpeta node_modules de un desarrollador no necesariamente coincide con el contenido de package.json.
user2468170
8

He estado usando tanto la carpeta commit_modules como la envoltura retráctil. Ambas soluciones no me hicieron feliz.

En resumen: commit node_modules agrega demasiado ruido al repositorio.
Y shrinkwrap.json no es fácil de administrar y no hay garantía de que algún proyecto retractilado se construya en unos pocos años.

Descubrí que Mozilla estaba usando un repositorio separado para uno de sus proyectos https://github.com/mozilla-b2g/gaia-node-modules

Por lo tanto, no me llevó mucho tiempo implementar esta idea en una herramienta CLI de nodo https://github.com/bestander/npm-git-lock

Justo antes de cada compilación agregue
npm-git-lock --repo [[email protected]: your / dedicated / node_modules / git / repository.git]

Calculará el hash de su package.json y verificará el contenido de node_modules de un repositorio remoto o, si es una primera compilación para este package.json, realizará una limpieza npm instally enviará los resultados al repositorio remoto.

bestander
fuente
5

Lo que funcionó para mí fue agregar explícitamente una versión npm a package.json ("npm": "1.1.x") y NO registrar node_modules en git. Puede ser más lento de implementar (ya que descarga los paquetes cada vez), pero no pude hacer que los paquetes se compilaran cuando se registraron. Heroku estaba buscando archivos que solo existían en mi caja local.

Jason Griffin
fuente
Si cree que mi respuesta fue la correcta, ¿lo acepta? ¡Gracias!
Ryan Daigle
En caso de que esto todavía esté en debate, echaré un vistazo a esta publicación de stackoverflow que es casi un duplicado de su pregunta anterior: stackoverflow.com/questions/11459733/... Básicamente, parece que la convención es verificar en node_modules, y administre sus versiones de esos módulos localmente. Esto parece bastante razonable, y quizás la explicación más sucinta es esta: mikealrogers.com/posts/nodemodules-in-git.html ¡ Buena suerte!
warriorpostman el
3

En lugar de registrar node_modules, cree un archivo package.json para su aplicación.

El archivo package.json especifica las dependencias de su aplicación. Heroku puede decirle a npm que instale todas esas dependencias. El tutorial al que se vinculó contiene una sección sobre archivos package.json.

matzahboy
fuente
Tengo un package.json. Tiene lo siguiente: {"nombre": "ejemplo de nodo", "versión": "0.0.1", "dependencias": {"express": "2.5.x", "redis-url": "0.1. 0 "," mongodb ":"> = 0.9.9 "}," motores ": {" nodo ":" 0.8.x "}}
Jason Griffin
Lo hice en mi cuadro local para crear el directorio node_modules. Eso es lo que verifiqué, luego eliminé y luego agregué.
Jason Griffin
Después de mirar más el tutorial, parece que están comprometiendo node_modules. En ese caso, no estoy seguro de si hay una manera de no comprometer node_modules. Lo sentimos
matzahboy
3

Estoy usando esta solución:

  1. Crear un repositorio separado que contenga node_modules. Si tiene módulos nativos que deberían construirse para una plataforma específica, cree un repositorio separado para cada plataforma.
  2. Adjunte estos repositorios al repositorio de su proyecto con 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. Cree un enlace desde la plataforma específica node_modulesal node_modulesdirectorio y agréguelo node_modulesa.gitignore .
  2. Ejecutar npm install.
  3. Confirmar cambios en el repositorio de submódulos.
  4. Confirma los cambios en el repositorio de tu proyecto.

Por lo tanto, puede cambiar fácilmente entre node_modulesdiferentes plataformas (por ejemplo, si está desarrollando en OS X e implementando en Linux).

Mixel
fuente
3

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

Editar: el enlace original era este, pero ahora está muerto. Gracias @Flavio por señalarlo.

Recordar.

  • Solo registre node_modules para las aplicaciones que implemente, no los paquetes reutilizables que mantiene.
  • Cualquier dependencia compilada debe tener su fuente registrada, no los destinos de compilación, y debe reconstruirse $ npm al desplegarse.

Mi parte favorita:

Todas las personas que agregaron node_modules a su gitignore, eliminen esa mierda, hoy , es un artefacto de una era que estamos muy felices de dejar atrás. La era de los módulos globales está muerta.

Benjamin Crouzier
fuente
El sitio que vinculó parece haber caducado y ahora está lleno de anuncios fraudulentos. Desearía que esos anuncios fueran "artefactos de una era que todos estaríamos muy felices de dejar atrás".
Flavio Copes
1
@FlavioCopes Actualizó mi respuesta con el enlace de Wayback Machine.
Benjamin Crouzier
2

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

[...] el nodo comienza en el directorio padre del módulo actual y agrega /node_modules e intenta cargar el módulo desde esa ubicación.

Si no se encuentra allí, se mueve al directorio principal, y así sucesivamente , hasta llegar a la raíz del árbol.

Si está implementando sus propios módulos específicos para su aplicación, puede mantenerlos ( y solo aquellos ) en su aplicación/node_modules . Y mueva todas las demás dependencias al directorio padre.

Este caso de uso es bastante impresionante, le permite mantener los módulos que creó específicamente para su aplicación muy bien con su aplicación, y no satura su aplicación con dependencias que se pueden instalar más adelante.

laggingreflex
fuente
1

escenario 1:

Un escenario: utiliza un paquete que se elimina de npm. Si tiene todos los módulos en la carpeta node_modules, entonces no será un problema para usted. Si solo tiene el nombre del paquete en package.json, ya no podrá obtenerlo. Si un paquete tiene menos de 24 horas, puede eliminarlo fácilmente de npm. Si tiene más de 24 horas, debe contactarlos. Pero:

Si contacta a soporte, verificará si eliminar esa versión de su paquete interrumpiría cualquier otra instalación. Si es así, no lo eliminaremos.

Lee mas

Entonces, las posibilidades de esto son bajas, pero hay un escenario 2 ...


escenario 2:

Otro escenario en el que este es el caso: desarrolla una versión empresarial de su software o un software muy importante y escribe en su paquete.json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Usas el método function1(x)de ese paquete.

Ahora los desarrolladores de studpid-paquete de cambiar el nombre del método function1(x)a function2(x)y hacen un fallo ... Cambian la versión de su paquete de 1.0.1a 1.1.0. Eso es un problema porque cuando llames npm installla próxima vez, aceptarás la versión1.1.0 porque usó la tilde ("studpid-package": "~1.0.1" ).

Llamar function1(x)puede causar errores y problemas ahora.


Insertar toda la carpeta node_modules (a menudo más de 100 MB) en su repositorio le costará espacio de memoria. Unos pocos kb (solo package.json) en comparación con cientos de MB (package.json & node_modules) ... Piénselo.

Usted podría hacerlo / debería pensar en ello si:

  • El software es muy importante.

  • te cuesta dinero cuando algo falla.

  • no confías en el registro npm. npm está centralizado y, en teoría, podría cerrarse.

No necesita publicar la carpeta node_modules en el 99.9% de los casos si:

  • Usted desarrolla un software solo para usted.

  • has programado algo y solo quieres publicar el resultado en GitHub porque alguien más podría estar interesado en él.


Si no desea que node_modules esté en su repositorio, simplemente cree un .gitignorearchivo y agregue la línea node_modules.

ndsvw
fuente