incluir arquivo .js externo no aplicativo node.js

97

Eu tenho um aplicativo de nó app.js. Como este arquivo está começando a crescer, gostaria de mover alguma parte do código em alguns outros arquivos que eu "exigiria" ou "incluiria" no arquivo app.js.

Estou tentando coisas 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');

em car.js:

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

Eu entendi o erro:

ReferenceError: Schema is not defined

Estou apenas procurando ter o conteúdo do car.js carregado (em vez de ter tudo no mesmo arquivo app.js). Existe uma maneira particular de fazer isso no node.js?

Luc
fonte
1
O esquema não existe nesse escopo. Você pode tentar passar Schema para car.js por meio de algum tipo de função exportada, de forma que você possa referenciá-lo. Isso ou requer mangusto dentro de car.js.
Robert,
3
Node.js usa CommonJS, que divide seu código em diferentes módulos. Como regra geral, o escopo do código em um aplicativo Node é o arquivo no qual ele está definido. Portanto, você precisará exigir o mongoose em car.js, e em car.js você precisará exportar o resto do seu aplicativo precisa então requerê-lo em seu arquivo principal como você está fazendo.
Matt Greer

Respostas:

100

Colocar ênfase no que todo mundo está dizendo var foono nível superior não cria uma variável global. Se você quiser uma variável global, escreva global.foo. mas todos nós sabemos que os globais são maus.

Se você é alguém que usa globais como aquele em um projeto node.js em que eu estava, eu os refatoraria porque há poucos casos de uso para isso (há algumas exceções, mas este não é um).

// 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);

em 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
fonte
32
Dica para qualquer pessoa que esteja lendo, você pode apenas fazer exportações.foo, em vez de module.exports.foo
Tyler Egeto
9
@TylerEgeto Sempre me sinto mais seguro se usar a versão mais longa;)
Raynos
3
Você poderia expandir o exemplo para mostrar como é possível usar variáveis ​​definidas em car.js no aplicativo principal? por exemplo, `função make (...) {... CarModel = mongoose.model ('Car', CarSchema); } `Dentro do aplicativo, como usar CarModel?
Marius de
:)) Ok, que tal definir várias vars dentro da função? por exemplo, vários modelos, ou mesmo 3 modelos e 2 algo mais? Eles devem ser retornados como parte de um objeto? por exemploreturn {models: {car: CarModel, dealer: CarDealer}, carStuff: carStuff}
Marius
56

A resposta correta geralmente é usar require, mas em alguns casos não é possível.

O código a seguir resolverá o problema, mas use-o com 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
fonte
2
O problema é: "O código em execução não tem acesso ao escopo local." nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_filename
Petah
Como é isso #include?
Steven Lu
18

Resposta curta:

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

// app.js
require('./lib.js').your_function();
Dorian
fonte
Isso não está funcionando para mim. Estou recebendo um erro Cannot find module lib.js.
Manoj
2
@Manoj você tem que prefixar lib.js com ./ assim:require('./lib.js').your_function()
Chris
8

você pode colocar

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

na parte superior do seu arquivo car.js para que funcione, ou você pode fazer o que Raynos disse para fazer.

Stephen
fonte
4

Se você deseja apenas testar uma biblioteca na linha de comando, pode fazer:

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

Essa abordagem funciona para mim em Node.js, há algum problema com este ?

Arquivo 'include.js':

fs = require('fs');

Arquivo '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
fonte
Isto está errado. "fs" nunca é exportado! Não funcionaria no modo estrito que é o padrão no ES6
MyUserInStackOverflow