Node.js module.exportsの目的は何ですか、またどのように使用しますか?


1432

Node.js module.exportsの目的は何ですか、またどのように使用しますか?

私はこれに関する情報を見つけることができないようですが、ソースコードでよく見られるので、Node.jsのかなり重要な部分のようです。

Node.jsのドキュメントによると:

モジュール

現在のへの参照 module。特にmodule.exports 、exportsオブジェクトと同じです。詳細についてはsrc/node.js、を参照 してください。

しかし、これは本当に役に立ちません。

正確には何をしmodule.exportsますか、簡単な例は何ですか?

回答:


1590

module.exportsrequire呼び出しの結果として実際に返されるオブジェクトです。

exports変数が最初にその同じオブジェクトに設定されているので、モジュールコードで、(すなわち、それは速記「エイリアス」です)あなたのだろう。このような通常のライトなもの:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

(または「公開」)、内部スコープの関数をエクスポートするmyFunc1myFunc2

そして、あなたが使用する呼び出しコードでは:

const m = require('./mymodule');
m.myFunc1();

最後の行は、結果requireが(通常)プロパティにアクセスできるプレーンオブジェクトである方法を示しています。

注意:上書きexportsすると、を参照しなくなりますmodule.exports。したがって、新しいオブジェクト(または関数参照)をexports割り当てたい場合は、その新しいオブジェクトをmodule.exports


exportsオブジェクトに追加する名前は、追加する値のモジュールの内部スコープ名と同じである必要はないので、次のようにすることができます。

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

に続く:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

119
良い答え-「exposes」の方が「exports」よりも用語の選択として優れていたようです
UpTheCreek

2
@ApopheniaOverload-「exports.func1、exports.func2など」を実行して、1つのファイルから複数の公開メソッドを作成できます。
hellatan 2012

73
モジュールrequireはvar m = require( './ mymodule');である必要があります。、ドットとスラッシュ付き。これにより、Node.jsはローカルモジュールを使用していることを認識します。
Gui Premonsa、

7
必ず使用してください:require( './ module_name')構文。名前のある他のnode.jsモジュールが存在する可能性があるため、独自のモジュールを選択する代わりに、node.jsでインストールされたものを選択します。
サジド2013年

3
@UpTheCreekには、モジュールによって公開されたパブリックシンボルを「エクスポートされた」ものと呼ぶ長い伝統があり、多くのプログラミングシステムや数十年にさかのぼります。これは、Node開発者が発明した新しい用語ではありませんでした。
マークリード

218

これはすでに回答されていますが、いくつかの説明を追加したいと思います...

exportsとの両方を使用して、次のmodule.exportsようにコードをアプリケーションにインポートできます。

var mycode = require('./path/to/mycode');

(たとえば、ExpressJSのサンプルコードで)表示される基本的なユースケースexportsは、.jsファイルのオブジェクトにプロパティを設定し、それを使用してインポートします。require()

したがって、単純なカウントの例では、次のようになります。

(counter.js):

var count = 1;

exports.increment = function() {
    count++;
};

exports.getCount = function() {
    return count;
};

...次に、アプリケーション(web.js、または実際には他の.jsファイル)で:

var counting = require('./counter.js');

console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2

簡単に言えば、必要なファイルを単一のオブジェクトを返す関数と考えることができ、プロパティ(文字列、数値、配列、関数など)をに設定することで、返されるオブジェクトに追加できますexports

require()呼び出しで返されるオブジェクトを、プロパティを持つオブジェクトだけでなく、呼び出し可能な関数にしたい場合があります。その場合module.exports、次のようにも設定する必要があります。

(sayhello.js):

module.exports = exports = function() {
    console.log("Hello World!");
};

(app.js):

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

exportsとmodule.exportsの違いについては、この回答で詳しく説明しています


私のようにいくつかのルートフォルダを持たない他のフォルダからのいくつかのモジュールを要求するにはどうすればよいですか?
イガル

@ user301639相対パスを使用して、ファイルシステム階層をトラバースできます。require実行するフォルダを基準に開始しますnode app.js。明確な回答を得るために、明示的なコード+フォルダ構造の例を使用して新しい質問を投稿することをお勧めします。
ジェドワトソン

1
私はあなたのmodule.exportsサンプルをそれを動かすために微調整しなければなりませんでした。ファイル:var sayHello = require('./ex6_module.js'); console.log(sayHello());およびモジュール:module.exports = exports = function() { return "Hello World!"; }
Jason Lydon 2014

1
インクリメントの例は本当に良いとわかり、これを使用して、エクスポートで何をしているかで負荷がかかるたびに心をリフレッシュしました。
マンキー2014

module.exports = exports = function(){...}2つ目exportsは変数ですよね?言い換えると、それはmodule.exports = abc = function()
Jeb50

60

NodeJSモジュール機構が基づいていることに注意CommonJSのような多くの他の実装でサポートされているモジュールRequireJSが、またSproutCoreCouchDBのWakandaOrientDBArangoDBRingoJSTeaJSSilkJScurl.js、あるいはAdobe Photoshopのビア(なぜならpslib)。既知の実装の完全なリストはここにあります

モジュールがノード固有の機能またはモジュールを使用していない限り、exports代わりにmodule.exports CommonJS標準の一部ではなく、ほとんどが他の実装ではサポートされていないものを使用することを強くお勧めします。

別のNodeJS固有の機能はexports、このスレッドでJed Watsonが提供した最後の例のように、プロパティとメソッドを追加するのではなく、新しいオブジェクトへの参照を割り当てる場合です。CommonJSモジュールメカニズムの循環参照サポート壊すので、私は個人的にこの方法を推奨しません。この場合、すべての実装でサポートされているわけではないため、Jedの例を次のように(または同様の方法で)記述して、より普遍的なモジュールを提供する必要があります。

(sayhello.js):

exports.run = function() {
    console.log("Hello World!");
}

(app.js):

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

またはES6機能を使用する

(sayhello.js):

Object.assign(exports, {
    // Put all your public API here
    sayhello() {
        console.log("Hello World!");
    }
});

(app.js):

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

PS:AppceleratorもCommonJSモジュールを実装しているようですが、循環参照のサポートがありません(参照:AppceleratorおよびCommonJSモジュール(キャッシュおよび循環参照)


35

新しいオブジェクトへの参照をexportsand / orに割り当てる場合に注意する必要があるいくつかの事項modules.exports

1.以前に元のオブジェクトにアタッチされていた、exportsまたはmodule.exportsエクスポートされたオブジェクトが別の新しいオブジェクトを参照するために失われたすべてのプロパティ/メソッド

これは明らかですが、既存のモジュールの最初にエクスポートされたメソッドを追加する場合は、ネイティブのエクスポートされたオブジェクトが最後に別のオブジェクトを参照していないことを確認してください

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)

2.の1つexportsまたはmodule.exports新しい値を参照する場合、それらは同じオブジェクトを参照しなくなります

exports = function AConstructor() {}; // override the original exported object
exports.method2 = function () {}; // exposed to the new exported object

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 

3.トリッキーな結果。あなたは、両方への参照を変更するとexportsしてmodule.exports露出しているAPI言うのは難しい、(それは次のようになりmodule.exports勝利)

// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

29

module.exportsプロパティまたはexportsオブジェクトにより、モジュールはアプリケーションと共有する必要があるものを選択できます

ここに画像の説明を入力してください

ここでmodule_exportに関するビデオを入手できます


18

プログラムコードを複数のファイルに分割する場合module.exportsは、変数と関数をモジュールのコンシューマーに公開するために使用されます。require()ソースファイル内の呼び出しはmodule.exports、モジュールから読み込まれた対応するファイルに置き換えられます。

モジュールを書くときに覚えておいてください

  • モジュールのロードはキャッシュされ、最初の呼び出しのみがJavaScriptを評価します。
  • モジュール内でローカル変数と関数を使用することは可能ですが、すべてをエクスポートする必要はありません。
  • module.exportsオブジェクトはまた、利用可能であるexports速記。ただし、単一の関数を返す場合は、常にを使用しますmodule.exports

モジュールのエクスポートの図

によると:「モジュールパート2-モジュールを書く」


9

参照リンクは次のようになります:

exports = module.exports = function(){
    //....
}

exportsまたはのプロパティmodule.exports関数や変数など)が外部に公開されます

もっと注意しなければならないことがあります:しないでください override輸出。

どうして ?

エクスポートはmodule.exportsの参照のみなので、エクスポートにプロパティを追加できますが、エクスポートを上書きすると、参照リンクが壊れます。

良い手本 :

exports.name = 'william';

exports.getName = function(){
   console.log(this.name);
}

悪い例:

exports = 'william';

exports = function(){
     //...
}

次のように、関数または変数を1つだけ公開したい場合:

// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();

このモジュールは1つの関数のみを公開し、nameのプロパティは外部に対してプライベートです。


6

http、sysなどのnode.jsをダウンロードしてインストールすると、node.jsにいくつかのデフォルトまたは既存のモジュールがあります。

これらはすでにnode.jsにあるため、これらのモジュールを使用する場合、基本的にインポートモジュールのようにします。ですが、なぜですか?それらはすでにnode.jsに存在しているためです。インポートは、node.jsからそれらを取得してプログラムに入れるようなものです。そしてそれらを使用します。

一方、輸出は正反対である、あなたが欲しいモジュールを作成している、聞かせてのは、モジュールaddition.jsとのNode.jsにそのモジュールを置くことは、あなたがそれをエクスポートしてそれを行うと言います。

ここで何かを書く前に、module.exports.additionTwoexports.additionTwoと同じであることを覚えておいてください

ええ、それが理由です、私たちは好きです

exports.additionTwo = function(x)
{return x+2;};

パスに注意してください

あなたがaddition.jsモジュールを作成したとしましょう、

exports.additionTwo = function(x){
return x + 2;
};

これをNODE.JSコマンドプロンプトで実行すると、次のようになります。

node
var run = require('addition.js');

これは言ってエラーになります

エラー:モジュールadditional.jsが見つかりません

これは、パスについては言及しなかったため、node.jsプロセスでは、addition.jsを実行できないためです。したがって、NODE_PATHを使用してパスを設定できます

set NODE_PATH = path/to/your/additon.js

これで、これはエラーなしで正常に実行されるはずです!!

さらに、NODE_PATHを設定せずに、additions.jsファイルを実行して、nodejsコマンドプロンプトに戻ることもできます。

node
var run = require('./addition.js');

ここでは現在のディレクトリにあると言ってパスを提供しているため、./これも正常に実行されるはずです。


1
それは輸出ですか、それとも輸出ですか?
rudrasiva86 2017

助けてくれてありがとう:)
JumpMan

3

モジュールは、関連するコードを単一のコード単位にカプセル化します。モジュールを作成するとき、これはすべての関連する関数をファイルに移動すると解釈できます。

2つの関数を含むHello.jsファイルがあるとします。

sayHelloInEnglish = function() {
  return "Hello";
};
sayHelloInSpanish = function() {
  return "Hola";
};

コードのユーティリティが複数の呼び出しである場合にのみ、関数を記述します。

関数のユーティリティを別のファイルWorld.jsに増やしたいとします。この場合、ファイルをエクスポートすると、module.exportsで取得できる画像になります。

以下のコードで両方の関数をエクスポートできます

var anyVariable={
 sayHelloInEnglish = function() {
      return "Hello";
    };
  sayHelloInSpanish = function() {
      return "Hola";
    }; 
}
module.export=anyVariable;

これらの関数を使用するには、World.jsにファイル名を要求するだけです。

var world= require("./hello.js");

ありがとうそれがあなたを助けてくれたなら私の答えを受け入れてください:)
Shantanu Madane

1
パーティー仲間には少し遅れます:)
Ben Taliadoros

@BenTaliadoros私も彼が遅れていると思いますし、彼のanyVariableオブジェクトにも多くのエラーがあると思います。sayHelloInSpanishメソッドの上の行はセミコロン(;)で終わってはならず、sayHelloInSpanish = functionは間違っています。このオブジェクトにはすべての問題があります。私は彼の答えを編集します
神聖な

1
編集は無効です。この回答でalphadoggは他に何を編集しましたか?
神聖な

フォーマットするだけです。私が遭遇していないいくつかのクレイジーなes6のこと、そしてそうでないと確信しているのでない限り、それはまったく有効なJSではありません
Ben Taliadoros

2

その意図は:

モジュラープログラミングは、プログラムの機能を独立した交換可能なモジュールに分離することを強調するソフトウェア設計手法であり、それぞれに必要な機能の1つの側面のみを実行するために必要なすべてが含まれています。

ウィキペディア

モジュラー/再利用可能なコードなしで大きなプログラムを書くのが難しくなると思います。nodejsでは、module.exports公開するものの定義を利用してモジュール式プログラムを作成し、プログラムを作成できますrequire

この例を試してください:

fileLog.js

function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;

stdoutLog.js

function log(string) { console.log(string); }

module.exports = log;

program.js

const log = require('./stdoutLog.js')

log('hello world!');

実行する

$ノードprogram.js

こんにちは世界!

./stdoutLog.js./fileLog.jsに交換してください


1

モジュールシステムの目的は何ですか?

次のことを実行します。

  1. ファイルが肥大化するのを防ぎ、非常に大きなサイズにします。たとえば5000行のコードを含むファイルは、通常、開発中に処理するのが非常に困難です。
  2. 懸念の分離を強制します。コードを複数のファイルに分割すると、すべてのファイルに適切なファイル名を付けることができます。このようにして、すべてのモジュールが何をしてどこでそれを見つけるかを簡単に識別できます(まだあなたの責任である論理ディレクトリ構造を作成したと仮定します)。

モジュールがあると、コードの特定の部分を見つけやすくなり、コードの保守が容易になります。

どのように機能しますか?

NodejS 次のように動作するCommomJSモジュールシステムを使用します。

  1. ファイルが何かをエクスポートしたい場合は、module.export構文を使用して宣言する必要があります
  2. ファイルが何かをインポートしたい場合は、require('file')構文を使用して宣言する必要があります

例:

test1.js

const test2 = require('./test2');    // returns the module.exports object of a file

test2.Func1(); // logs func1
test2.Func2(); // logs func2

test2.js

module.exports.Func1 = () => {console.log('func1')};

exports.Func2 = () => {console.log('func2')};

知っておくと便利なこと:

  1. モジュールはキャッシュされています。同じモジュールを2つの異なるファイルにロードする場合、モジュールは一度だけロードする必要があります。require()同じモジュールで2回目にa が呼び出されると、キャッシュからプルされます。
  2. モジュールは同期で読み込まれます。この動作は必須です。非同期の場合、require()すぐに取得したオブジェクトにアクセスできません。

-3
let test = function() {
    return "Hello world"
};
exports.test = test;

4
これは、受け入れられた回答の最初のスニペットと同様の例です(return "Hello world"違いはありません)が、説明はありません。回答する前に、回答が件名に何か追加されることを確認してください。
barbsan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.