node.jsアプリに外部.jsファイルを含める


97

app.jsノードアプリケーションがあります。このファイルが大きくなり始めているので、コードの一部を他のいくつかのファイルに移動して、app.jsファイルに「必要」または「含め」ます。

私は次のようなことを試みています:

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

car.jsで:

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

エラーが発生しました:

ReferenceError: Schema is not defined

(すべてを同じapp.jsファイルに含めるのではなく)car.jsのコンテンツをロードするように探しているだけです。これをnode.jsで行う特定の方法はありますか?


1
スキーマはそのスコープに存在しません。スキーマを参照するには、エクスポートされた関数を使用してスキーマをcar.jsに渡してみます。または、car.js内にmongooseが必要です。
ロバート

3
Node.jsは、コードをさまざまなモジュールに分割するCommonJSを利用します。大まかに言うと、Nodeアプリのコードのスコープは、それが定義されているファイルです。そのため、car.jsでmongooseを必要とし、car.jsでは、アプリの残りの部分をエクスポートする必要があります。あなたがしているように、メインファイルでそれを必要とします。
Matt Greer、

回答:


100

誰もがvar fooトップレベルで言っていることに重点を置いても、グローバル変数は作成されません。グローバル変数が必要な場合は、と記述しglobal.fooます。でも私たちはみんなグローバルは悪知っています。

あなたがnode.jsプロジェクトでそのようなグローバルを使用している人であれば、私はこれを使用してそれらをリファクタリングします。これにはユースケースがほとんどないためです(いくつかの例外がありますが、これは1つではありません)。

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

car.js

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

module.exports.make = make;

32
読む人のためのヒントは、modules.exports.fooではなく、exports.fooを実行するだけです
Tyler Egeto

9
@TylerEgeto I私は長いバージョンを使用する場合は、常により安全な感じ;)
レイノス

3
例を展開して、メインアプリのcar.js内で定義された変数をどのように使用できるかを示していただけますか?例: `function make(...){... CarModel = mongoose.model( 'Car'、CarSchema); } `アプリ内では、CarModelをどのように使用しますか?
マリウス

:))OK、関数内に複数の変数を設定するときはどうですか?たとえば、複数のモデル、または3つのモデルと2つの何か?オブジェクトの一部として返される必要がありますか?例return {models: {car: CarModel, dealer: CarDealer}, carStuff: carStuff}
マリウス

56

通常、正解はrequireを使用することですが、場合によってはそれが不可能です。

次のコードでうまくいきますが、注意して使用してください:

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

2
これに関する問題は、「実行中のコードはローカルスコープにアクセスできない」です。nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_filename
Petah

これはどのようなもの#includeですか?
Steven Lu

18

短い答え:

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

// app.js
require('./lib.js').your_function();

これは私のために働いていません。エラーが発生しますCannot find module lib.js
Manoj

2
@Manoj lib.jsの前に./を付ける必要があります:require('./lib.js').your_function()
Chris

8

あなたは置くことができます

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

car.jsファイルの先頭に配置して機能させるか、Raynosが言ったことを実行できます。



0

このアプローチはNode.jsで機能しますが、これで問題はありますか?

ファイル「include.js」:

fs = require('fs');

ファイル '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)
    };
})

これは間違っています。「fs」は決してエクスポートされません!ES6のデフォルトである厳密モードでは機能しません
MyUserInStackOverflow 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.