この記事では主に、単純なモジュール ローダーの requireJS 実装について詳しく説明します。それを皆さんと共有し、参考にしてください。
前の記事では、モジュール型プログラミングの重要性と、それによって解決できる問題を何度も強調しました:
① 単一ファイル変数の名前の競合の問題を解決する
② フロントエンドの複数のファイルの問題を解決する人とのコラボレーション
③ ファイルの依存関係の問題を解決する
④ オンデマンドでロードする (この記述は実際には非常に誤りです)
⑤...
ローダーをより深く理解するために、私は、 requireJS のソースコードですが、多くの学生にとって、ローダーの実装はまだあまり明確ではありません
実際、ライブラリやフレームワークを読むだけで理解したい場合は、部分的な理解しかできないので、今日は簡単なローダーを実装します
ローダーの原理の分析
分割と結合
実際、プログラムを実行するには完全なモジュールが必要です。例:
//求得绩效系数 var performanceCoefficient = function () { return 0.2; }; //住房公积金计算方式 var companyReserve = function (salary) { return salary * 0.2; }; //个人所得税 var incomeTax = function (salary) { return salary * 0.2; }; //基本工资 var salary = 1000; //最终工资 var mySalary = salary + salary * performanceCoefficient(); mySalary = mySalary - companyReserve(mySalary) - incomeTax(mySalary - companyReserve(mySalary)); console.log(mySalary);
完全な給与の場合、会社は成果報酬を持っていますが、そのアルゴリズムは非常に複雑である可能性があり、その中には出席、修了などが含まれる可能性がありますが、当面は気にしません増加する場合は減少するため、住宅積立金を支払い、最終的には私の給与になります。上記のプロセスは必要不可欠ですが、各機能は異なります。非常に複雑で、お金に関係することも複雑なので、会社の業績だけでコードが1,000行を超える可能性があります
そこで、ここで分割を開始します:
<script src="companyReserve.js" type="text/javascript"></script> <script src="incomeTax.js" type="text/javascript"></script> <script src="performanceCoefficient.js" type="text/javascript"></script> <script type="text/javascript"> //基本工资 var salary = 1000; //最终工资 var mySalary = salary + salary * performanceCoefficient(); mySalary = mySalary - companyReserve(mySalary) - incomeTax(mySalary - companyReserve(mySalary)); console.log(mySalary); </script>上記のコードは、「分割」されていることを示していますしかし、実際には、「マージ」の問題も発生します。結局、その中のファイルはまだ残っている可能性があります。依存関係に関して言えば、require と define が登場します。
フロントエンドモジュールにはリクエストが含まれるため、モジュールの 1 つはパス js ファイルに対応し、残りは対応するモジュールをロードすることになります。したがって、この書き方:
var pathCfg = { 'companyReserve': 'companyReserve', 'incomeTax': 'incomeTax', 'performanceCoefficient': 'performanceCoefficient' };
は、どこかで行われているのを見たとしても、そこにはいくつかの「トリック」があるはずです: companyReserve = requile('companyReserve');
は次のとおりです。標準的な requireJS の書き方。最初にモジュールとそのパス マッピングを定義し、依存関係を定義します
require.config({ 'companyReserve': 'companyReserve', 'incomeTax': 'incomeTax', 'performanceCoefficient': 'performanceCoefficient' }); require(['companyReserve', 'incomeTax', 'performanceCoefficient'], function (companyReserve, incomeTax, performanceCoefficient) { //基本工资 var salary = 1000; //最终工资 var mySalary = salary + salary * performanceCoefficient(); mySalary = mySalary - companyReserve(mySalary) - incomeTax(mySalary - companyReserve(mySalary)); console.log(mySalary); });
シンプルで完全なモジュール ローダーは基本的に次のようになります。最初は依存関係の配列、2 番目はコールバックです。コールバックには必要なものがあります。すべての依存関係は実行前にロードされる必要があり、コールバックのパラメーターは依存関係の実行結果であるため、定義モジュールには通常、戻り値が必要です
ソリューションが利用可能になったので、実装方法を説明します。それ?
実装計画モジュールの読み込みに関して、人々の最初の反応は ajax です。モジュール ファイルの内容を取得できる場合、それがモジュール化の基礎になりますが、ajax メソッドだけでは十分ではないからです。クロスドメインの問題
があり、モジュール型ソリューションでは必然的にクロスドメインの問題に対処する必要があるため、動的に作成されたスクリプトタグを使用して js ファイルをロードすることが第一の選択肢となっていますが、ajax を使用しないソリューションの実装は困難です。まだ要件があると言われています
追記: 実際の作業では、HTML テンプレート ファイルを読み込むシーンもあります。これについては後ほど説明します通常、これをスケジュール JavaScript のプログラムの入り口として使用します。その後、各モジュールはロードするスクリプト タグをサイレントに作成し、require 内のすべての依存モジュールのロードが完了したことを require モジュール キューに報告します。原理はほぼ同じで、残りは具体的な実装です。そして、この理論が信頼できるかどうかを証明します
ローダー去勢実装
コアモジュール
上記の理論に従って、まず全体的に話しましょう。とりわけ、入り口の 3 つの基本機能について説明しましょう
require(depArr, callback)
これら 3 つのモジュールは不可欠です:
① config はモジュールとパス間のマッピングを設定するために使用され、または他の用途があります
② require はプログラムの入り口です
③ 各モジュールを設計し、require のスケジューリングに応答するために定義します
次に、ここで script タグを作成するメソッドを用意し、その onLoad イベントをリッスンします
④ loadScript
次に、script タグをロードした後、ロードされたモジュールを保存するためのグローバル モジュール オブジェクトである必要があるため、ここで提案します 2 つの要件が満たされています:
⑤ require.moduleObj モジュール ストレージ オブジェクト
⑥ モジュール、モジュール コンストラクター
上記のコア モジュールを使用して、以下を形成しましたコード:
var require = function () { }; require.config = function () { }; require.define = function () { };
そのため、次のステップは具体的な実装です。実装プロセスでは、利用できないインターフェイスや詳細が補完されることが多く、最終的な実装は元の設計とは何の関係もないことがよくあります...
コードの実装这块最初实现时,本来想直接参考requireJS的实现,但是我们老大笑眯眯的拿出了一个他写的加载器,我一看不得不承认有点妖
于是这里便借鉴了其实现,做了简单改造:
(function () { //存储已经加载好的模块 var moduleCache = {}; var require = function (deps, callback) { var params = []; var depCount = 0; var i, len, isEmpty = false, modName; //获取当前正在执行的js代码段,这个在onLoad事件之前执行 modName = document.currentScript && document.currentScript.id || 'REQUIRE_MAIN'; //简单实现,这里未做参数检查,只考虑数组的情况 if (deps.length) { for (i = 0, len = deps.length; i < len; i++) { (function (i) { //依赖加一 depCount++; //这块回调很关键 loadMod(deps[i], function (param) { params[i] = param; depCount--; if (depCount == 0) { saveModule(modName, params, callback); } }); })(i); } } else { isEmpty = true; } if (isEmpty) { setTimeout(function () { saveModule(modName, null, callback); }, 0); } }; //考虑最简单逻辑即可 var _getPathUrl = function (modName) { var url = modName; //不严谨 if (url.indexOf('.js') == -1) url = url + '.js'; return url; }; //模块加载 var loadMod = function (modName, callback) { var url = _getPathUrl(modName), fs, mod; //如果该模块已经被加载 if (moduleCache[modName]) { mod = moduleCache[modName]; if (mod.status == 'loaded') { setTimeout(callback(this.params), 0); } else { //如果未到加载状态直接往onLoad插入值,在依赖项加载好后会解除依赖 mod.onload.push(callback); } } else { /* 这里重点说一下Module对象 status代表模块状态 onLoad事实上对应requireJS的事件回调,该模块被引用多少次变化执行多少次回调,通知被依赖项解除依赖 */ mod = moduleCache[modName] = { modName: modName, status: 'loading', export: null, onload: [callback] }; _script = document.createElement('script'); _script.id = modName; _script.type = 'text/javascript'; _script.charset = 'utf-8'; _script.async = true; _script.src = url; //这段代码在这个场景中意义不大,注释了 // _script.onload = function (e) {}; fs = document.getElementsByTagName('script')[0]; fs.parentNode.insertBefore(_script, fs); } }; var saveModule = function (modName, params, callback) { var mod, fn; if (moduleCache.hasOwnProperty(modName)) { mod = moduleCache[modName]; mod.status = 'loaded'; //输出项 mod.export = callback ? callback(params) : null; //解除父类依赖,这里事实上使用事件监听较好 while (fn = mod.onload.shift()) { fn(mod.export); } } else { callback && callback.apply(window, params); } }; window.require = require; window.define = require; })();
首先这段代码有一些问题:
没有处理参数问题,字符串之类皆未处理
未处理循环依赖问题
未处理CMD写法
未处理html模板加载相关
未处理参数配置,baseUrl什么都没有搞
基于此想实现打包文件也不可能
......
但就是这100行代码,便是加载器的核心,代码很短,对各位理解加载器很有帮助,里面有两点需要注意:
① requireJS是使用事件监听处理本身依赖,这里直接将之放到了onLoad数组中了
② 这里有一个很有意思的东西
document.currentScript
这个可以获取当前执行的代码段
requireJS是在onLoad中处理各个模块的,这里就用了一个不一样的实现,每个js文件加载后,都会执行require(define)方法
执行后便取到当前正在执行的文件,并且取到文件名加载之,正因为如此,连script的onLoad事件都省了......
demo实现
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> </body> <script src="require.js" type="text/javascript"></script> <script type="text/javascript"> require(['util', 'math', 'num'], function (util, math, num) { num = math.getRadom() + '_' + num; num = util.formatNum(num); console.log(num); }); </script> </html>
//util define([], function () { return { formatNum: function (n) { if (n < 10) return '0' + n; return n; } }; });
//math define(['num'], function (num) { return { getRadom: function () { return parseInt(Math.random() * num); } }; });
//math define(['num'], function (num) { return { getRadom: function () { return parseInt(Math.random() * num); } }; });
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
详细介绍在Vue2.0中v-for迭代语法的变化(详细教程)
以上がrequireJS はモジュールローダーをどのように実装しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

WebStorm Mac版
便利なJavaScript開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ホットトピック









