現在のアプリケーションを補うCommonjs規範採用Node.jsのモジュールメカニズムは、Node.jsのがmodule.exportsはにより求めることができるJavaクラスファイルに似た大きな欠陥の標準のJavaScript開発、Pythonでインポートメカニズム、ではない、必要とし、モジュールの導入。
ローディング機構のモジュールにおいて、Node.jsのローディングは、それが中にbinding_cache付けします完了した後にロードされるシステムモジュールの場合にのみ使用される負荷の遅延の戦略を使用します。
インタビューガイド
require的加载机制?
参考:モジュールローディング機構module.exports与exports的区别
参考:研究の間でのオブジェクトの参照関係假设有a.js、b.js两个模块相互引用,会有什么问题?是否为陷入死循环?
、参照テキスト「循環参照モジュール1」a模块中的undeclaredVariable变量在b.js中是否会被打印?
、参照テキスト「循環参照モジュール2」模块在require的过程中是同步还是异步?
参考テキストモジュールのローディング機構「ファイルモジュール」
分類モジュール
システムモジュール
必要で、一般的に、ネイティブモジュールに使用される組み込みの組み込みモジュール、として知られているC / C ++モジュールは、呼び出さ
組み込みモジュールのNode.jsのHTTP、バッファ、FS、等、とも呼ばれる底の開発に使用される(C / C ++)ネイティブモジュール。
サードパーティ製のモジュール
自モジュール内のモジュール、実際には分割ファイルパス(中Node.jsのサードパーティのモジュールを非呼ば.
、..
、/
(例えばmoment.js等エクスプレス、KOAフレームなど)から開始)とカスタムモジュール
JavaScriptのモジュール:例えば
hello.js
JSONモジュール:例えば
hello.json
C / C ++モジュール:例えば、.nodeファイルという名前の拡張モジュールをコンパイルした後、
hello.node
ディレクトリ構造
いくつかのNode.js├──ベンチマーク性能試験コードは ├──のNode.jsが依存しているのDEP ├──ドキュメントの文書を Node.jsの外国人は、JSモジュールのソースコードを公開libに├── ├──C / C ++ソースファイルのSRCのNode.js 、組み込みモジュール ├──テストユニットテスト のコンパイル時に使用するツール├──ツール ドキュメントAPIドキュメント├── 勝利プラットフォームのメイクファイルvcbuild.batを├── ├──node.gypノード-GYPビルドコンパイルタスクの設定ファイル ...
モジュールのローディング機構
面试中可能会问到能说下require的加载机制吗?
通常のNode.jsにロードされたモジュールは、3つのステップを経ます路径分析
、文件定位
、编译执行
。
分類モジュールによれば、優先度負荷の次のシーケンスを実行します。
システムキャッシュ:モジュールは最初のキャッシュが最初にロードされ、キャッシュ後に実行されますが、キャッシュの値かどうかを決定します。
システムモジュール:すなわち一次モジュール、キャッシュのロード後優先、コアモジュールの一部を省略バイナリにコンパイルされている
路径分析
、文件定位
に直接適用メモリ、LIBのNode.jsソースで定義されたシステム・モジュールは、とすることができます見に行きます。ファイルモジュール:優先順位のロード
.
、..
、/
始めて、拡張子を持つファイルがない場合は、順番に続く.js
、が.json
、.node
それは、拡張子を作るしようとしていた存在するファイルを決定するために、同期ブロッキングモードにもしようとする過程であるから、パフォーマンスを最適化見ての角度は.json
、.node
ファイルの拡張子を追加する必要があります。モジュールとしてディレクトリ:これは、ときにファイルモジュールのロード処理を発生しますが、見つけることができませんでしたが、ディレクトリの場合であることが判明し、ディレクトリがうとして、この時間
包
に扱うことは、ノードは、Commonjsに最初の意志をこの仕様を使用しています主な特性は、外のファイルで定義され、プロジェクトのルートディレクトリにpackage.jsonファイルを検索し("main":"lib/hello.js")
、それがデフォルトのエラーがスローされます、ファイルの説明をロードするための入り口、またにロードされます。エラー:モジュールが見つかりません「のlib / hello.js」負荷にディレクトリをnode_modules:システムモジュールの場合、モジュールは、Node.jsのは、根系まで、現在のモジュールの親ディレクトリから検索され、ファイルへのパスを見つけることができません
図は、タイミングモジュールのロードを必要とします
どこキャッシュモジュール
上記ローディング機構モジュールを説明し、初期ロード後に途中で言及したモジュールがキャッシュされます、キャッシュモジュールことは間違いありませんか?
次のようにNode.jsのrequire.cacheのAPIモジュールのキャッシュされたビューを提供し、戻り値は、簡単なテストをするためにここで、検証するために、オブジェクトです。
新しいテストmodule.jsファイル
ここで私は、変数やメソッドをエクスポート
module.exports={
a : 1,
test : () => { }
}
新test.jsファイル
require('./test-module.js');
console.log(require.cache);
このファイルのロードテストmodule.jsファイル、返されたものを見内側に印刷した後require.cache?以下の結果は非常に明確にする必要があり参照してください、モジュール名、住所、データをエクスポート非常に明確です。
モジュールの循環参照
質問1
二つのモジュールが相互に参照するb.js、そこa.jsとし、問題は何ですか?それは無限ループであるかどうか?次の例を見てください
// a.js
console.log('a模块start');
exports.test = 1;
undeclaredVariable = 'a模块未声明变量'
const b = require('./b');
console.log('a模块加载完毕: b.test值:',b.test);
// b.js
console.log('b模块start');
exports.test = 2;
const a = require('./a');
console.log('undeclaredVariable: ', undeclaredVariable);
console.log('b模块加载完毕: a.test值:', a.test);
質問2
モジュールundeclaredVariable変数がでb.jsで印刷されますかどうか?
コンソールは、node a.js
結果を表示します:
a模块start
b模块start
undeclaredVariable: a模块未声明变量
b模块加载完毕: a.test值: 1
a模块加载完毕: b.test值: 2
質問1は、起動a.js
時に、ロードされますb.js
、その後、b.js
彼はまたロードされa.js
、今回a.js
のモジュールが実行されていないが、返すa.js
モジュールexports
オブジェクトがさ未完成的副本
に与えられたb.js
モジュール(したがって、デッドサイクルをキャッチされません)。次いでb.js
、ローディングが完了した後にexports
物体が供給されるa.js
モジュール
質問2、としてundeclaredVariable
グローバル変数にリンクされている宣言されていない変数、で、その後、他の場所では、もちろん、あなたが得ることができます。
コードの実行前に、コードを使用すると、次の例に示すように、ラッパーを封入Node.jsのであろう。
(function(exports, require, module, __filename, __dirname) {
// 模块的代码
});
研究間のオブジェクトの参照関係
差module.exportsは、輸出:おそらく、ほとんどの問題を調べインタビュー?
ショートカットの輸出同等module.exportsは、次のとおりです。
const exports = modules.exports;
私たちがすることができます。しかし、輸出のポイントを変更しないように注意して、exports.test='a'
このようなオブジェクトにエクスポートすることが、直接、次の例に割り当てることができない、それは輸出のポイントを変更します
// 错误的写法 将会得到 undefined
exports = {
'a': 1,
'b': 2
}
// 正确的写法
modules.exports = {
'a': 1,
'b': 2
}
関係をよりよく理解するには、JavaScriptの参照内のオブジェクトを参照することができます https://www.nodejs.red/#/javascript/object?
ソース
より転載 Nodejsテクノロジ・スタック