incluir un archivo .js externo en la aplicación node.js

97

Tengo una aplicación de nodo app.js. A medida que este archivo comienza a crecer, me gustaría mover parte del código en otros archivos que "requeriría" o "incluiría" en el archivo app.js.

Estoy probando cosas como:

// Declare application
var app = require('express').createServer();

// Declare usefull stuff for DB purposes
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

// THE FOLLOWING REQUIRE DOES NOT WORK
require('./models/car.js');

en car.js:

// Define Car model
CarSchema = new Schema({
  brand        : String,
  type : String
});
mongoose.model('Car', CarSchema);

Me sale el error:

ReferenceError: Schema is not defined

Solo estoy buscando tener el contenido de car.js cargado (en lugar de tener todo en el mismo archivo app.js) ¿Hay alguna forma particular de hacer esto en node.js?

Luc
fuente
1
El esquema no existe en ese ámbito. Puede intentar pasar Schema en car.js a través de algún tipo de función exportada, de esa manera puede hacer referencia a él. Eso o requiere mangosta dentro de car.js.
Robert
3
Node.js usa CommonJS, que divide su código en diferentes módulos. La regla general es que el alcance del código en una aplicación de nodo es el archivo en el que está definido. Por lo tanto, necesitará mongoose en car.js, y en car.js deberá exportar el resto de su aplicación. necesita entonces requerirlo en su archivo principal como lo está haciendo.
Matt Greer

Respuestas:

100

Poner énfasis en lo que todos los demás han estado diciendo var fooen el nivel superior no crea una variable global. Si desea una variable global, escriba global.foo. pero todos sabemos que los globales son malos.

Si usted es alguien que usa globales como ese en un proyecto de node.js en el que estaba, los refactorizaría, ya que hay muy pocos casos de uso para esto (hay algunas excepciones, pero este no es uno).

// Declare application
var app = require('express').createServer();

// Declare usefull stuff for DB purposes
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

require('./models/car.js').make(Schema, mongoose);

en car.js

function make(Schema, mongoose) {
    // Define Car model
    CarSchema = new Schema({
      brand        : String,
      type : String
    });
    mongoose.model('Car', CarSchema);
}

module.exports.make = make;
Raynos
fuente
32
Sugerencia para cualquiera que esté leyendo, puede simplemente exportar.foo, en lugar de module.exports.foo
Tyler Egeto
9
@TylerEgeto Siempre me siento más seguro si uso la versión más larga;)
Raynos
3
¿Podría ampliar el ejemplo para mostrar cómo se pueden usar las variables definidas dentro de car.js en la aplicación principal? eg `function make (...) {... CarModel = mongoose.model ('Car', CarSchema); } `Dentro de la aplicación, ¿cómo se usa CarModel?
Marius
:)) Ok, ¿qué tal cuando configuras varias variables dentro de la función? por ejemplo, varios modelos, o incluso 3 modelos y 2 algo más? ¿Deberían devolverse como parte de un objeto? Ej .return {models: {car: CarModel, dealer: CarDealer}, carStuff: carStuff}
Marius
56

La respuesta correcta suele ser requerir, pero en algunos casos no es posible.

El siguiente código funcionará, pero utilícelo con cuidado:

var fs = require('fs');
var vm = require('vm');
var includeInThisContext = function(path) {
    var code = fs.readFileSync(path);
    vm.runInThisContext(code, path);
}.bind(this);
includeInThisContext(__dirname+"/models/car.js");
Kybernetikos
fuente
2
El problema con esto es: "El código en ejecución no tiene acceso al alcance local". nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_filename
Petah
¿Cómo es esto #include?
Steven Lu
18

Respuesta corta:

// lib.js
module.exports.your_function = function () {
  // Something...
};

// app.js
require('./lib.js').your_function();
dorio
fuente
Esto no me está funcionando. Recibo un error Cannot find module lib.js.
Manoj
2
@Manoj tienes que prefijar lib.js con ./ así:require('./lib.js').your_function()
Chris
8

puedes poner

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

en la parte superior de su archivo car.js para que funcione, o puede hacer lo que Raynos dijo que hiciera.

Stephen
fuente
4

Si solo desea probar una biblioteca desde la línea de comando, puede hacer:

cat somelibrary.js mytestfile.js | node
Bouke Versteegh
fuente
0

Este enfoque me funciona en Node.js, ¿hay algún problema con este ?

Archivo 'include.js':

fs = require('fs');

Archivo 'main.js':

require('./include.js');

fs.readFile('./file.json', function (err, data) {
    if (err) {
        console.log('ERROR: file.json not found...')
    } else {
        contents = JSON.parse(data)
    };
})
Marcio Pamplona
fuente
Esto está mal. ¡"fs" nunca se exporta! No funcionaría en modo estricto que es predeterminado en ES6
MyUserInStackOverflow