nodeシリーズのmodules

3694 ワード

住所
コンベヤー?ドア
説明
モジュールもnodejsの核心です.各jsファイルはモジュールです.exportを通じて自分の方法を対外開放します.moduleがあるからこそ、nodejsをモジュール化することができます.
機能モジュール
  • は、メインモジュール(最初のディストリビュータ)1.js require 2.jsにアクセスし、2.js require 3.js.3.jsでは、require.mainにアクセスすることによって、1.jsモジュールを得ることができる.
  • // 1.js
    module.exports = {   
      a: 44
    };
    require('./2');
    //3.js
    console.log(require.main.exports);
    // output: {a: 44}
    
    ここで注意したいのは、直接取得したrequire.mainはこのモジュールを指し、module.exportsオブジェクトではない.したがって、プライマリモジュールの外部の属性を取得するには、require.main.exportsを介して実現することができる.したがって、require.mainmoduleであって、module.exportsではない.
  • 循環依存性は一つの原則を覚えています.requireファイルがある場合、循環依存性があるかどうかにかかわらず、このモジュールは現在のmodule.exportsです.たとえば
  • // 1.js
    console.log('1 starting');
    exports.a= 1;
    var b = require('./2.js');
    exports.b= 2;
    
    // 2.js
    console.log('2 starting');
    var b = require('./2.js');
    console.log(b);
    // output:  {a: 1}
    
    1.jsは2.jsをロードする過程で、完全に実行されていない(a属性だけで、b属性がない)ので、2.jsで取得した1.jsは、実はa属性だけです.これらのファイルを全部ロードしてからrequire.cacheを更新します.これまでは半製品でした(キャッシュにも書き込みますが).
    キャッシュメカニズム
    上の話がちょっと乱れていますが、キャッシュの仕組みを整理してみます.このファイルをロードしたばかりの時には、このモジュールはキャッシュrequire.cacheの中に置いてあります.もし修正が続けば、キャッシュも引き続き変化します.たとえば
    console.log(require.cache);   // exports = {};
    module.exports.a = 2;
    console.log(require.cache);  // exports = {a: 2}
    
    これらのステートメントを実行する時、2回の出力を比較してもいいです.キャッシュの対象はすでに存在していますが、その後は変化する可能性があります.次の二つの問題があります.
  • もしモジュールが完全にロードされていないと同時に他のモジュールにロードされるなら、ロードされているデータは違っていますか?A:はい、例えば上記の循環依存例
  • モジュールをロードした後、データを修正してキャッシュを変更してもいいですか?A:
  • var a = require('./other');
    console.log(require.cache);
    a.aaaaa = 33333;
    console.log(require.cache);
    
    上の簡単な例を通して、はい、分かります.変わる.ここで修正したのは参照先のメモリブロックですので、直接修正できます.
    ファイルモジュール
    多くのnodejsオープンソースプロジェクトの中に、あるフォルダの下に、package.jsonファイルがあります.nameおよびmainは、2つの比較的重要なパラメータである.前者はこのモジュールの名前です.後者は、ロードされた時、どこで入り口のファイルを探しますか?たとえば、exampleファイルの下のpackage.json
    {  
      "name": "a6666",  
      "main": "./../test.js"
    }
    
    require('./example') , , main test.js main`パラメータがデフォルトではindex.jsです.問題が来ました.もしあるフォルダの下にexampleフォルダと同名ファイルのexample.jsがあったら、どれをロードしますか?手動で試してみたら分かります.カタログを読み込むと思います.具体的な原因を知りたいなら、モジュールのロードの順番を知ることができます.
    node_をロードするmodulesの順番
    今のノドからmodulesはずっと探していますが、見つけられないなら、父のカタログで探し続けます.見つけられるまでは、見つけられないなら、間違えました.
    ここにグローバルモジュールの概念があります.環境変数の中でnode_を探します.modulesしかし、公式では紹介されていません.これを「歴史の原因」と呼び、しかもスピードが落ちます.直接プロジェクトの現地に置くのがいいと思います.
    モジュール包装器
    これはとても大切なものです.これがあるから、モジュール化がある.各ファイルは包装されています.5つの「グローバル」変数はどうやって来ると思いますか?
    (function (exports, require, module, __filename, __dirname) {
      // Your module code actually lives in here
    });
    
    この階は私達の開発者には感知できません.運行中に包装します.だから私たちは直接これらの変数を使うことができます.これがあったら、グローバル変数を汚染するのは難しいです.
    moduleのいくつかの属性
  • module.children
  • module.parent上の2つの属性は、各モジュールのローディング順序を示すことができる.一つのモジュールは何度もロードできますが、module.parentは一つしかありません.一つのモジュールは一つのモジュールのchildrenだけで、複数のモジュールではありません.なぜなら、初めて読み込む時には、これらの親子の世代関係が明らかになってきたからです.いくら後ろにロードされても、ロードされても、変化はありません.もちろん、手動でキャッシュを修正して除外します.
  • module.loadedは
  • をロードされたことがありますか?
  • module.requireはキャッシュ内のmodule.exportオブジェクトに戻る.
  • module.idキャッシュのkey(一般的にファイルの実際のパス)
  • module.filenameキャッシュモジュールのファイルパス
  • module.exportsが一番多く使われているのはこいつです.説明をやめました
  • 結び目
    nodejsのモジュールシステムはやはりよく設計されています.特にモジュール化されています.比較的興味深いのはモジュールローディング機構です.上のコンベヤーのドアは見られます.私も説明しませんでした.