ほぼすべてのnode.js開発者は、「必要() `関数が何をするかを伝えることができますが、それがどのように機能するかを本当に知っている人は何ですか?ライブラリとモジュールをロードするために毎日それを使用していますが、その動作は私たちにとって謎です。
好奇心から、私はエンジンの下で何が起こったのかを調べるために、ノードのコアコードを掘り下げました。しかし、これは単一の関数ではありません。ノードモジュールシステムでModule.jsを見つけました。このファイルには、各ファイルの読み込み、コンパイル、キャッシュを制御する驚くほど強力で比較的馴染みのないコアモジュールが含まれています。 `require()`、その出現は氷山の一角にすぎません。
module.js
コードコピーは次のとおりです。
関数モジュール(ID、親){
this.id = id;
this.exports = {};
this.parent = parent;
// ...
module.jsでは、主にnode.js内で2つの役割を再生します。まず、すべてのnode.jsモジュールの基盤を提供します。各ファイルは、ベースモジュールの新しいインスタンスであり、ファイルが実行された後でも存在します。これが、プロパティをmodule.Exportsに接続し、必要に応じてそれらを返すことができる理由です。
このモジュールの2番目の主要なタスクは、ノードのモジュール負荷メカニズムを処理することです。使用する「要求」関数の独立した操作は、実際には抽象的な概念モジュールであり、それ自体がモジュールの単純なカプセル化です。_load関数。このロードメソッドは、各ファイルの実際のロードを処理し、そこから旅を開始します。
module._load
コードコピーは次のとおりです。
module._load = function(request、parent、ismain){
//1。モジュールを確認してください。_Cacheはキャッシュモジュールをします。
// 2。キャッシュが空の場合は、新しいモジュールインスタンスを作成します。
// 3。キャッシュに保存します。
//4。指定されたファイル名でmodule.load()を呼び出します。
//これは、ファイルの内容を読み取った後、module.compile()を呼び出します。
// 5。ファイルの読み込み/解析がエラーが発生した場合、
//キャッシュから悪いモジュールを削除します
//6。Module.Exportsを返します
};
Module._Loadは、新しいモジュールのロードとモジュールキャッシュの管理を担当します。各モジュールがロードされたキャッシュは、冗長ファイルの読み取り数を減らし、アプリケーションを大幅に高速化できます。さらに、共有モジュールインスタンスにより、シングルトンの特性を持つモジュールがプロジェクトの州に留まることができます。
モジュールがキャッシュに存在しない場合、module._loadはファイルの新しいベースモジュールを作成します。次に、モジュールにモジュールに送信する前に、新しいファイルの内容を読み取るように指示します。_compile。 [1]
上記のステップ#6に気付いた場合、module.exportsがユーザーに返されたことがわかります。これが、Public Interfaceの使用を定義するときに、Module._Loadが必要のコンテンツを返すため、ExportsとModule.Exportsを使用する理由です。ここにはこれ以上の機能がなかったことに驚きましたが、あればそれが良いでしょう。
module._compile
コードコピーは次のとおりです。
module.prototype._compile = function(content、filename){
// 1。スタンドアロンを作成するには、module.requireを呼び出す関数が必要です。
// 2。要求する他のヘルパーメソッドを添付します。
// 3。JSコードを要求を提供する関数に包みます、
//モジュールなど。モジュールスコープにローカルに変数。
//4。その関数を実行します
};
・これが本当の奇跡が起こる場所です。まず、モジュール用に特別な独立した運用要件機能が作成されます。これは私たちが必要とする機能であり、すべて精通しています。関数自体は、モジュールのカプセル化にすぎません。requireには、使用が簡単なあまり知られていない補助方法も含まれています。
sequire():外部モジュールをロードします
corse.resolve():モジュール名を絶対パスに解析します
corse.main:メインモジュール
cache.cache:すべてのキャッシュモジュール
heers.extensions:extensions:その拡張機能に従って各有効なファイルタイプに使用できるコンピレーション方法
要件の準備ができたら、ロードされたソースコード全体が新しい関数にカプセル化され、必要性、モジュール、エクスポート、その他すべての露出変数をパラメーターとして受け入れることができます。これは、node.js環境との競合を防ぐためにモジュールをカプセル化するためだけに作成された関数です。
コードコピーは次のとおりです。
(function(exports、require、module、__filename、__dirname){
//ここにコードが挿入されました!
});
module._compileメソッドは同期的に実行されるため、モジュールへの呼び出しは、コードが実行され、module.exprtsをユーザーに返すまでのみ待機できます。
結論は
そのため、私たちはすでに必要の完全なコードを理解しており、それがどのように機能するかについて予備的な理解を持っています。
あなたがそれをずっとやったなら、あなたは最後の秘密の準備ができています:要求( 'モジュール')。これは正しい、モジュールシステム自体をモジュールシステムを介してロードできます。インセプション。これは奇妙に聞こえるかもしれませんが、ユーザースペースがnode.jsコアを掘り下げることなくモジュールロードシステムと対話できるようになります。一般的なモジュールはすべてこのように構築されています。 [2]
詳細を知りたい場合は、module.jsソースコードを自分で確認してください。あなたがしばらく頭痛を感じるのに十分なことはまだたくさんあります。最初のものは、node_module_contextsとは何か、そしてそれが追加される理由を教えてください。
[1] module._compileメソッドは、JavaScriptファイルの実行にのみ使用されます。 jsonファイルはjson.parse()を介して解析し、返される必要があります
[2]ただし、両方のモジュールは、モジュールなどのプライベートモジュールメソッドに基づいて構築されています。これはそれほど良くないと思うことができます...