2012-07-01 22 views
45

Tengo varias aplicaciones en el nodo que todas comparten algunos módulos que he escrito. Estos módulos no están disponibles a través de npm. Me gustaría poder compartir libremente entre aplicaciones, pero no quiero copiar directorios, ni confiar en que Git lo haga. Y no soy muy bueno en el uso de enlaces simbólicos para hacer esto tampoco.¿Cómo compartir el código entre las aplicaciones node.js?

me gustaría organizar directorios algo como esto:

app1 
server.js 
node_modules 
    (public modules from npm needed for app1) 
lib 
    (my own modules specific to app1) 

app2 
server.js 
node_modules 
    (public modules from npm needed for app2) 
lib 
    (my own modules specific to app2) 

shared_lib 
(my own modules that are used in both app1 and app2) 

El problema que estoy viendo es que los módulos en shared_lib parecen confundirse en cuanto a dónde encontrar los módulos que estarán en las node_modules directorio de la aplicación en la que se están ejecutando. Al menos creo que ese es el problema.

Entonces .... ¿cuál es una buena manera de hacer esto que evita tener duplicados de archivos? (Tenga en cuenta que no me importan los duplicados de cosas en node_modules, ya que esos no son mi código, no los controlo en Git, etc.)

Respuesta

15

Esto funciona teniendo node_modules carpetas en diferentes niveles - el nodo se desplaza automáticamente hacia arriba hasta que encuentra el módulo.

Nota usted no tiene que publicar en la NGP tener un módulo dentro de node_modules - sólo tiene que utilizar:

"private": true 

Dentro de cada uno de sus particulares package.json archivos - para su proyecto que tendría lo siguiente:

app1 
server.js 
node_modules 
    (public modules from npm needed for app1) 
    (private modules locally needed for app1) 

app2 
server.js 
node_modules 
    (public modules from npm needed for app2) 
    (private modules locally needed for app2) 

node_modules 
    (public modules from npm needed for app1 & app2) 
    (private modules locally for app1 & app2) 

El punto es node.js tiene un mecanismo para tratar esto y es increíble. Simplemente combínelo con el truco 'privado no en NPM' y estará listo.

En resumen, un:

require('somemodule') 

De aplicación A o B le cascada hacia arriba hasta que se encontró el módulo - sin importar si vivían más abajo o más arriba. De hecho, esto le permite intercambiar en caliente la ubicación sin cambiar ninguna de las declaraciones require (...).

node.js module documentation

+3

Cuando probé esto, los módulos requeridos por los módulos compartidos no se pudieron resolver. En su estructura, parece que la carpeta node_modules más alta tiene tanto módulos privados (controlados en el control de la fuente) como públicos (npm install'd - not checked in). Normalmente no verifico los módulos públicos en el control de la fuente, ¿cómo te salvaste con esto? –

1

Si mira node.js docs, verá que Node.js también entiende el formato de archivo package.json, al menos de forma resumida.

Básicamente, si usted tiene un directorio llamado foo, y en ese directorio es un archivo package.json con el par clave-valor: "main": "myCode.js", entonces, si usted tratar de require("foo") y se encuentra este directorio con un archivo package.json el interior, lo hará luego use foo/myCode.js para el módulo foo.

lo tanto, con la estructura de directorios, si cada librería compartida tiene su propio directorio con un simple archivo de este tipo package.json el interior, a continuación, sus aplicaciones pueden obtener las librerías compartidas por:

var lib1 = require('../shared_lib/lib1'); 
var lib2 = require('../shared_lib/lib2'); 

Y que deben trabajar para ambos de estas aplicaciones.

4

sólo tiene que utilizar el camino correcto en su requieren llamar

Por ejemplo, en server.js que serían:

var ModuleName = require (' ../ shared_lib/ModuleName/module.js');

Es importante saber que tan pronto como su ruta tenga el prefijo '/', '../' o './', la ruta será relativa al archivo de llamada.

Para más información acerca de los nodos visita módulo de carga: http://nodejs.org/docs/latest/api/modules.html

+4

Pero si hago eso, y después de que el módulo intenta requerir un módulo que viene de la NGP, que se confunde y da errores. – rob

34

Nodo recomienda el uso de npm link para crear sus propios paquetes de Node.js localmente y luego ponerlos a disposición de otras aplicaciones. Es un proceso simple de cuatro pasos.

Procedimiento típico sería crear primero el paquete con la siguiente estructura

hello 
    | index.js 
    | package.json 

aplicación típica de estos archivos sería índice de

.js

exports.world = function() { 
    return('Hello World'); 
    } 

package.json

{ 
    "name": "hello", 
    "version": "0.0.1", 
    "private": true, 
    "main": "index.js", 
    "dependencies": { 
    }, 
    "engines": { 
    "node": "v0.6.x" 
    } 
    } 

'privado: la verdadera' asegura que la NGP se negará a publicarlo en el repositorio. Esta es una forma de evitar la publicación accidental de repositorios privados.

Navegue a la raíz de la carpeta de la aplicación, ejecute el enlace npm para vincular el archivo globalmente para que pueda ser utilizado en otros paquetes.

ahora a utilizar este paquete en otra aplicación, dicen hola-mundo con la siguiente estructura de directorios

hello-world 
| app.js 

navegar a la carpeta hola-mundo y ejecutar

npm link hello 

Ahora lo usan como cualquier otro paquete NPM como

app.js

var http = require('http'); 
    var hello = require('hello'); 

    var server = http.createServer(function(req, res) { 
    res.writeHead(200); 
    res.end(hello.world()); 
    }); 
    server.listen(8080); 
+0

¿Cómo funciona esto cuando se implementa en un entorno PaaS como Heroku o Nodejitsu? –

+0

El enlace npm no funcionará en un entorno PaaS. Heroku respeta los módulos de nodo que se insertan con su código. Entonces esa podría ser una opción. – almypal

+0

Eso es lo que no entiendo: si despliegas en Heroku desde git, no verificas tus node_modules. Además, eso implicaría que copias el código compartido en la carpeta node_modules antes de registrarte. Lo cual parece engorroso y propenso a errores. ¿O me estoy perdiendo algo? ¡Gracias! –

1

Sí, se puede hacer referencia shared_lib de app1, pero luego te encuentras con un problema si desea empaquetar y desplegar app1 a algún otro entorno, como por ejemplo un servidor web en AWS.

En este caso, es mejor instalar sus módulos en shared_lib a app1 y app2 usando "npm install shared_lib/module". También instalará todas las dependencias de los módulos shared_lib en app1 y app2 y tratará los conflictos/duplicados.

ver esto: How to install a private NPM module without my own registry?

Cuestiones relacionadas