JavaScriptは、世界で最も頻繁に使用されるプログラミング言語の1つです。これは、Web世界の共通言語であり、すべてのブラウザで使用されています。 JavaScriptの誕生はNetscapeの時代にさかのぼり、そのコアコンテンツはMicrosoftと戦い、当時のFierce Browser Warに参加するために急いで開発されました。早期のリリースにより、その貧弱な特徴のいくつかは必然的に生じました。
開発時間は短いですが、JavaScriptには、各スクリプトのグローバルネームスペースを共有する機能を除いて、まだ多くの強力な機能があります。
WebページにJavaScriptコードがロードされると、グローバルネームスペースに挿入され、他のすべてのロードされたスクリプトと同じアドレス空間を共有します。
しかし、ありがたいことに、Nodeはサーバー側JavaScriptの仕様を設定しており、CommonJSモジュール標準も実装しています。この標準では、各モジュールには独自のコンテキストがあり、他のモジュールと区別されます。これは、いわゆるグローバルスコープがまったくなく、モジュールが互いに干渉しないため、モジュールがグローバルな範囲を汚染しないことを意味します。
この章では、いくつかの異なるモジュールとそれらをロードする方法について学びます。
コードを明確に定義された一連のモジュールに分割すると、アプリケーションを制御できます。以下に、独自のモジュールを作成および使用する方法を学びます。
ノードがモジュールをロードする方法を学びます
ノードでは、モジュールはファイルパスまたはモジュール名を介して参照できます。非コアモジュールが名前で参照されている場合、ノードは最終的にモジュール名を対応するモジュールファイルパスに暗示します。また、コア関数を含むこれらのコアモジュールは、ノードが起動するとプリロードされます。
非コアモジュールには、NPM(ノードパッケージマネージャー)を使用してインストールされたサードパーティモジュール、およびお客様または同僚が作成したローカルモジュールが含まれます。
現在のスクリプトによってインポートされた各モジュールは、露出したAPIのセットをプログラマーに公開します。モジュールを使用する前に、次のように、必要な関数を使用してインポートする必要があります。
コードコピーは次のとおりです。
var module = require( 'module_name')
上記のコードは、module_nameという名前のモジュールをインポートします。これは、npmでインストールされたコアモジュールまたはモジュールの場合があります。要求関数は、モジュールのすべてのパブリックAPIを含むオブジェクトを返します。モジュールに応じて、返されたオブジェクトは任意のJavaScript値である場合があり、関数、または一連の属性(関数、配列、またはJavaScriptオブジェクト)を含むオブジェクトである場合があります。
エクスポートモジュール
CommonJSモジュールシステムは、ノードの下のファイル間でオブジェクトと関数を共有する唯一の方法です。非常に複雑なプログラムの場合、いくつかのクラス、オブジェクト、または機能を、明確に定義された一連の再利用可能なモジュールに再構築する必要があります。モジュールユーザーの場合、モジュールは指定したコードのみを外の世界に公開します。
次の例では、ノードでは、ファイルとモジュールが1つずつ対応することを理解できます。 Circle.jsというファイルを作成しました。これは、Circleコンストラクターを外側にのみエクスポートします。
コードコピーは次のとおりです。
関数円(x、y、r){
関数r_squared(){
return math.pow(r、2);
}
関数領域(){
return math.pi * r_squared();
}
return {エリア:エリア};
}
module.exports = circle;
コードで最も重要なことは、モジュールが外部にエクスポートするものを定義する最後の行です。モジュールは、現在のモジュール自体を表す特別な変数であり、モジュール。Exportsはモジュールからエクスポートされるオブジェクトです。任意のオブジェクトにすることができます。この例では、モジュールユーザーがこのモジュールを使用してサークルインスタンスを作成できるように、サークルコンストラクターをエクスポートします。
複雑なオブジェクトをエクスポートすることもできます。モジュール.Exportsは空のオブジェクトに初期化され、モジュールの属性として外部世界に公開するものはすべてエクスポートします。たとえば、一連の関数を外部に公開するモジュールを設計しました。
コードコピーは次のとおりです。
function printa(){
console.log( 'a');
}
function printb(){
console.log( 'b');
}
function printc(){
console.log( 'c');
}
module.exports.printa = printa;
module.exports.printb = printb;
module.exports.pi = math.pi;
このモジュールは、2つの関数(printaとprintb)と数(pi)をエクスポートし、呼び出しコードは次のようになります。
コードコピーは次のとおりです。
var mymodule2 = require( './ mymodule2');
mymodule2.printa(); //-> a
mymodule2.printb(); //-> b
console.log(mymodule2.pi); //-> 3.141592653589793
ロードモジュール
前述のように、必要な関数を使用してモジュールをロードすることができます。ノードにはグローバルネームスペースの概念がないため、コードの呼び出しがグローバルネームスペースに影響することを心配する必要はありません。モジュールが構文や初期化エラーなしで存在する場合、要求関数はモジュールオブジェクトを返し、このオブジェクトをローカル変数に割り当てることもできます。
いくつかの異なるタイプのモジュールがあり、コアモジュール、ローカルモジュール、NPMまでにインストールされるサードパーティモジュールに大まかに分割できます。モジュールの種類によると、モジュールを参照する方法はいくつかあります。以下のこれらの知識について学びましょう。
コアモジュールのロード
ノードには、コアモジュールと呼ばれるバイナリファイルにコンパイルされたいくつかのモジュールがあります。それらはパスで参照することはできず、モジュール名でのみ使用できます。コアモジュールの優先度が最も高く、同じ名前のサードパーティモジュールが既に存在していても、コアモジュールが最初にロードされます。
たとえば、HTTPコアモジュールをロードして使用する場合は、これを行うことができます。
コードコピーは次のとおりです。
var http = require( 'http');
これにより、ノードAPIドキュメントで定義されているHTTPモジュールのAPIを含むHTTPモジュールを含むオブジェクトが返されます。
ファイルモジュールのロード
絶対パスを使用して、ファイルシステムからモジュールをロードすることもできます。
コードコピーは次のとおりです。
var mymodule = require( '/home/pedro/my_modules/my_module');
現在のファイルに基づいて相対パスを使用することもできます。
コードコピーは次のとおりです。
var mymodule = require( '../ my_modules/my_module');
var mymodule2 = require( './ lib/my_module_2');
上記のコードに注意してください。ファイル名の拡張子を省略できます。 Nodeがこのファイルを見つけることができない場合、ファイル名の後にJS接尾辞を追加して再度検索しようとします(実際、JSに加えて、JSとノードも探します。詳細については、公式Webサイトのドキュメントを見ることができます)。したがって、現在のディレクトリにmy_module.jsというファイルが存在する場合、2つの読み込み方法があります。
コードコピーは次のとおりです。
var mymodule = require( './ my_module');
var myModule = require( './ my_module.js');
ディレクトリモジュールのロード
ディレクトリパスを使用してモジュールをロードすることもできます。
コードコピーは次のとおりです。
var mymodule = require( './ mymoduledir');
ノードは、このディレクトリがモジュールパッケージであると想定し、このディレクトリでパッケージ定義ファイルパッケージを検索しようとします。
見つかっていない場合、ノードはパッケージのエントリポイントがindex.jsファイルであると想定します(翻訳者の注:index.jsに加えて、index.nodeも探し、.nodeファイルはノードのバイナリ拡張機能パッケージです。詳細については公式ドキュメントを参照してください)。例として、ノードは./mymoduledir/index.jsファイルを見つけようとします。
それどころか、package.jsonファイルが見つかった場合、ノードはそれを解析し、パッケージ定義のメイン属性を探してから、メイン属性の値をエントリポイントの相対パスとして使用しようとします。この例では、package.jsonが次のように定義されている場合:
コードコピーは次のとおりです。
{
「名前」:「mymodule」、
「メイン」:「./lib/mymodule.js」
}
ノードは、./mymoduledir/lib/mymodule.jsファイルをロードしようとします
node_modulesディレクトリからロードします
要件関数のパラメーターが相対パスまたはコアモジュール名でない場合、ノードは現在のディレクトリのnode_modulesサブディレクトリで検索されます。たとえば、次のコードでは、ノードはファイルを見つけようとします。/node_modules/mymodule.js:
コードコピーは次のとおりです。
var mymodule = require( 'mymodule.js');
見つからない場合、ノードは引き続き上部ディレクトリのnode_modulesフォルダーで検索します。見つからない場合は、対応するモジュールが見つかるかルートディレクトリに到達するまで、上部ディレクトリで検索を続けます。
この機能を使用して、node_modulesディレクトリのコンテンツまたはモジュールを管理できますが、モジュール管理タスクをNPMに引き渡すことをお勧めします(第1章を参照)。ローカルnode_modulesディレクトリは、NPMインストールモジュールのデフォルトの場所です。このデザインは、ノードとNPMを結び付けます。通常、開発者として、この機能についてあまり気にする必要はありません。 NPMを使用してパッケージをインストール、更新、削除するだけで、node_modulesディレクトリを維持するのに役立ちます。
キャッシュモジュール
モジュールは、最初の成功したロードの後にキャッシュされます。つまり、モジュール名が同じファイルパスに解決された場合、要求するすべての呼び出し( 'mymodule')はまったく同じモジュールを返します。
たとえば、次のコンテンツを含むmy_module.jsというモジュールがあります。
コードコピーは次のとおりです。
console.log( 'モジュールmy_module初期化...');
module.exports = function(){
console.log( 'hi!');
};
console.log( 'my_module initialized。');
次に、次のコードを使用してモジュールをロードします。
コードコピーは次のとおりです。
var mymoduleinstance1 = require( './ my_module');
次の出力を生成します。
コードコピーは次のとおりです。
モジュールmy_module初期化...
my_module初期化
2回インポートする場合:
コードコピーは次のとおりです。
var mymoduleinstance1 = require( './ my_module');
var mymoduleinstance2 = require( './ my_module');
出力はまだです:
コードコピーは次のとおりです。
モジュールmy_module初期化...
my_module初期化
つまり、モジュールの初期化コードは1回だけ実行されます。独自のモジュールを構築するとき、モジュールの初期化コードに副作用がある可能性のあるコードが含まれている場合、この機能に特に注意する必要があります。
まとめ
ノードはJavaScriptのデフォルトのグローバル範囲をキャンセルし、代わりにCommonJSモジュールシステムを採用したため、コードをより適切に整理し、多くのセキュリティ問題やバグを回避できます。必要な関数を使用して、コアモジュール、サードパーティモジュール、またはファイルやディレクトリから独自のモジュールをロードすることもできます。
相対パスまたは絶対パスを使用して、非コアモジュールをロードすることもできます。モジュールをnode_modulesディレクトリまたはnpmでインストールしたモジュールに配置すると、モジュール名を直接使用して読み込むこともできます。
翻訳者のメモ:
読者は公式文書のモジュール章を読むことをお勧めします。私は個人的には著者より明確だと感じています。非常に代表的な例が添付されています。これは、ノードモジュールの読み込みを理解するのに非常に役立ちます。以下も引用されています。
コードコピーは次のとおりです。
(x)を使用して、パスyの下でモジュールをロードします
1. xがコアモジュールの場合、
a。コアモジュールをロードして返します
b。終わり
2。xが './'または '/'または 'で始まる場合
a。 load_as_file(y + x)
b。 load_as_directory(y + x)
3。Load_node_modules(x、dirname(y))
4。例外を投げる:「見つかりません」
load_as_file(x)
1. xがファイルの場合、xをJavaScriptスクリプトとしてロードし、ロード後に終了します
2. X.JSがファイルの場合、JavaScriptスクリプトとしてX.JSをロードし、ロード後に終了します
3. X.Nodeがファイルの場合、X.Nodeをノードバイナリプラグインとしてロードし、ロード後に終了します。
load_as_directory(x)
1. x/package.jsonファイルが存在する場合、
a。 x/package.jsonを解析し、「メイン」フィールドを見つけます。
b。また、m = x +(メインフィールドの値)
c。 load_as_file(m)
2。x/index.jsファイルが存在する場合、x/index.jsをJavaScriptスクリプトとしてロードし、ロード後に終了します。
3. x/index.nodeファイルが存在する場合、x/index.nodeをノードバイナリプラグインとしてロードし、ロード後に終了します。
load_node_modules(x、start)
1. dirs = node_modules_paths(start)
2。各ディレクトリ監督の下で次の操作を実行します。
a。 load_as_file(dir/x)
b。 load_as_directory(dir/x)
node_modules_paths(start)
1。また、パーツ=パス分割(開始)
2。また、root =「node_modules」の最初のインスタンスのインデックス、または0
3。また、i =パーツのカウント-1
4. dirs = []
5。> root、
a。 parts [i] = "node_modules"の場合、フォローアップ操作が継続されます。
c。 dir = path join(parts [0 .. i] + "node_modules")
b。 dirs = dirs + dir
c。また、i = i -1
6。監督に戻ります