以前、require.js のソースコードを分析しましたが、全体的な分析は少し大雑把で、内容が少し空っぽで、requirejs の依存関係処理の本質が掴めていませんでした。 require.js ソースコードの最も失敗した分析場所。
実装の詳細はよくわかりませんが、ソースコードの構成と基本的なロジックの実行については全体的に理解しています。
この記事は、インターネット上のソースコードを参照し、そのアイデアによって実装された単純なモジュールローダーを分析し、require.js の知識と理解を深めることを目的としています。
まず、次の点が明確です:
require関数が呼び出されるたびに、Contextオブジェクトが作成されます
Moduleオブジェクトはモジュールオブジェクトを表し、基本的な操作は、このオブジェクトのプロトタイプです。メソッド
上記の 2 つのオブジェクトは、この単純なモジュール ローダーの実装の中核です。ロード プロセス中の処理フローは、次の図に示すとおりです。 Module オブジェクトは次のとおりです:
mid: モジュール ID を表します
src: モジュールパス
deps: モジュール依存関係リスト
コールバック: コールバック関数errback: エラー処理関数checkCycle: 循環依存関係を処理し、現在の循環依存関係リストを返しますステータス: モジュールのステータス
fetch: スクリプト ノードを作成し、要素ノードに追加します
Exports: コールバック関数のパラメータ列に対応するモジュール出力
Moduleのプロトタイプオブジェクトには以下のメソッドがあります:
init: Moduleオブジェクトの初期化処理
handleDeps: ハンドル依存関係リスト
changeStatus: モジュールのステータスを変更します。主にモジュールが正常にロードされたかどうかを処理します実行: すべての依存モジュールが正常にロードされた後、パラメータリストを取得する方法実際、依存関係リストの処理はdefineとrequireの処理コードで処理されます。 function と require 関数は次のとおりです:
依存関係リストの処理方法
require(['a', 'b'], function(a, b) { console.log(a, b); });
上記からわかるように、require 関数が呼び出されるときの依存関係リストは ['a', 'b ']、コールバック関数は function(a, b) {console.log( a, b);}
require コードからわかるように、Context コンストラクターを呼び出して Context オブジェクトを作成します。 Context コンストラクターの処理時: let Context = function(deps, callback, errback) {
this.cid = ++contextId; this.init(deps, callback, errback); } ; Context.prototype.init = function(deps, callback, errback) { this.deps = deps; this.callback = callback; this.errback = errback; contexts[this.cid] = this; } ;
次に、依存関係リストを処理する handleDeps 関数を呼び出します。 具体的なコードは次のとおりです: handleDeps: function() {
let depCount = this.deps ? this.deps.length : 0; // require.js中处理循环依赖的处理 let requireInDep = (this.deps || []).indexOf('require'); if (requireInDep !== -1) { depCount--; this.requireInDep = requireInDep; this.deps.splice(requireInDep, 1); } // 处理循环依赖情况 let cycleArray = this.checkCycle(); if (cycleArray) { depCount = depCount - cycleArray.length; } // depCount表示当前模块的依赖模块数,depCount为0表示模块中某一依赖加载完成 this.depCount = depCount; if (depCount === 0) { this.execute(); return; } // 遍历依赖列表,创建Module对象,并且将当前模块与其依赖的关系构建出来maps this.deps.forEach((depModuleName) => { if (!modules[depModuleName]) { let module = new Module(depModuleName); modules[module.name] = module; } if (!maps[depModuleName]) { maps[depModuleName] = []; } maps[depModuleName].push(this); } );
}
循環依存関係の処理
紙の上で完成Jue Qian 氏は、この問題を実装する必要があることを認識しており、単純なモジュール ローダーを実装することで、require.js モジュールのロードの概念と論理処理がより明確になります。 以上がjsを使用して簡単なモジュールローダーを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。 if (requireInDep !== -1) {
depCount--;
this.requireInDep = requireInDep;
this.deps.splice(requireInDep, 1);
}
// 获取循环依赖 let cycleArray = this.checkCycle();
if (cycleArray) {
depCount = depCount - cycleArray.length;
}
// execute函数中代码// 插入require到回调函数的参数列表中if (this.requireInDep !== -1 && this.requireInDep !== undefined) {
arg.splice(this.requireInDep, 0, require);
}
結論