JSフロントエンドモジュール化のいくつかの仕様についての簡単な説明

JSフロントエンドモジュール化のいくつかの仕様についての簡単な説明

序文

クライアントが長時間実行されるシナリオがありますが、法務部門とデータ部門はユーザーから何らかの情報を収集する必要があります。この情報は収集された後、適切に処理され、サーバーに報告される必要があります。クライアントは純粋な js 実行エンジンを提供し、WebView コンテナーを必要としません。 iOS には成熟した JavaScriptCore があり、Android では V8 エンジンを使用できます。このようなエンジンには、ネイティブの基本機能とデータ コンピューティング機能にアクセスする SDK が装備されています。これは、追加のデータ処理機能を備えたハイブリッド SDK の去勢バージョンと見ることができます。

問題は解決しましたか?ロジックを処理するときには、cheerio と sql の 2 つのライブラリも必要です。これらはすべて Node プロジェクトであるため、純粋な js 環境で直接実行することはできません。そのため、需要は変化しました。Node プロジェクトを UMD 仕様にパッケージ化するのです。この方法では、純粋な JS 環境で実行できます。次の記事では、さまざまな仕様を分析します。実際、これらはフロントエンドのモジュール化に関する仕様のほんの一部です。

フロントエンドモジュール開発の価値

インターネットの急速な発展に伴い、フロントエンド開発はますます複雑になっています。この記事では、実際のプロジェクトで遭遇した問題から始めて、モジュール化によってどのような問題を解決できるかを説明し、Sea.js を例にフロントエンドのモジュール開発を行う方法を説明します。

厄介な名前の競合

簡単な習慣から始めましょう。プロジェクトに取り組むとき、私はよく、いくつかの共通する低レベルの関数を抽象化して、次のような個別の関数に分離します。

関数each(arr){
// 実装コード} 

関数log(str) {
// 実装コード}

私はこれらのコードを抽出して util.js に統合し、必要な場所にファイルをインポートしました。見た目は素晴らしく、チームの同僚たちはこのような便利なツールキットを提供してくれたことにとても感謝してくれました。

チームが大きくなり、人々が不満を言い始めるまで

Xiao Yang: オブジェクトを反復処理するために each メソッドを定義しましたが、util.js にはすでに each メソッドがあります。メソッド名を毎回変更する必要があるため、eachObject メソッドと呼ぶことしかできません。 <br>張三: ログメソッドを定義しましたが、王武のコードに問題があります。誰か調べてもらえますか?

苦情はどんどん増えていき、最終的に Java のアプローチを参考にして名前空間を導入し、問題を解決しました。 util.jsのコードは

var org = {};

org.utils = {};

org.Utils.each = 関数 (arr) {

// 実装コード};

org.Utils.log = 関数 (str) {

// 実装コード};

コードは低レベルに見えるかもしれませんが、実際には、フロントエンド分野における名前空間の伝道者は Yahoo! です。 YUI2 プロジェクトは、以下のコードを見ると、Yahoo! です。オープンソースプロジェクト

if (org.cometd.Utils.isString(応答)) {

org.cometd.JSON.fromJSON(レスポンス) を返します。

}

if (org.cometd.Utils.isArray(応答)) {

応答を返します。

}

名前空間は競合の問題を大幅に解決できますが、メソッドが呼び出されるたびに、名前空間に関連するコードを大量に記述する必要があり、コーディングの楽しさが失われます。

これを行う別の方法は、自己実行関数を使用することです。

(関数 (引数) {

//...

})(これ);

面倒なファイル依存関係

上記のシナリオを続けると、多くの場合、プロジェクト チームが車輪の再発明をしなくても済むように、UI レイヤーで共通コンポーネントを開発する必要があります。最も頻繁に使用されるコンポーネントの1つはdialog.jsです。

<script src="util.js"></script>

<script src="dialog.js"></script>

<スクリプト>

org.Dialog.init({ /* 設定を渡す */ });

</スクリプト>

公開グループでは使用方法のドキュメントを作成し、メンバー全員に通知するメール(プロジェクトアドレス、使用方法など)を送信しますが、それでも「なぜdialog.jsに問題があるのか​​」と尋ねる人がいます。調査の最終結果は、基本的にutil.jsは導入されていないというものです。

<script src="dialog.js"></script>

<スクリプト>

org.Dialog.init({ /* 設定を渡す */ });

</スクリプト>

名前の競合とファイルの依存関係は、フロントエンド開発における 2 つの典型的な問題です。開発者による継続的な思考と研究の結果、モジュール式のソリューションが生まれました。CMD を例に挙げてみましょう。

定義(関数(require, exports) {

exports.each = 関数 (配列) {

// ...

};

exports.log = 関数(メッセージ) {

// ...

};

});

エクスポートを通じて、外部へのインターフェースを提供することができます。dialog.jsのコードは

定義(関数(require, exports) {

var util = require('./util.js')

  

exports.init = 関数(){

// ...

};

});

これを使用すると、 require('./util.js') を介して util.js 内のエクスポートによって公開されるインターフェースを取得できます。 requireメソッドは他の多くの言語でも解決策があります: include、

モジュール化の利点

1. モジュールのバージョン管理: エイリアスなどの設定やビルドツールを使用することで、モジュールのバージョン管理を簡単に実現できます。

2. 保守性の向上: モジュール化により、各ファイルに対して単一の責任を実現できるため、コードの保守に非常に役立ちます。

3. フロントエンドのパフォーマンス最適化: フロントエンド開発では、モジュールの非同期読み込みがページのパフォーマンスに非常に役立ちます。

4. 環境間でモジュールを共有する: CMD モジュール定義仕様は NodeJS モジュール仕様と非常に似ているため、Sea.JS の NodeJS バージョンを使用すると、サーバーやブラウザー間でモジュールを簡単に共有できます。

CommonJS 仕様

CommonJS はサーバー側モジュールの仕様です。 NodeJS はこの仕様を採用しています。 CommonJS はモジュールを同期的にロードするため、後続の操作はロードが完了した後にのみ実行できます。

サーバーの特性上、ロードされたモジュール ファイルは一般的にローカル ハードディスクに保存されるため、非同期方式を考慮せずに高速にロードされます。

CommonJS モジュール仕様では、各ファイルは独立したスコープ、変数、メソッドを持つモジュールであり、他のモジュールからは見えません。 CommonJS 仕様では、各モジュール内で、 module 変数が現在のモジュールを表すことが規定されています。これはオブジェクトであり、その exports 属性は外部インターフェイスです。モジュールをロードするには、実際にはモジュールの module.exports 属性をロードします。モジュールをロードするには、 require メソッドを使用します。

// パーソン.js

関数Person(){

this.eat = 関数 () {

console.log('何か食べる')

}

  

this.sleep = 関数 () {

コンソールログ('スリープ')

}

}

  

var person = 新しい Person();

exports.person = 人;

exports.name = 名前;

  

// インデックス.js

person = require('./Person').person; とします。

人.食べる()

CommonJS と ES6 モジュールの違い

1. CommonJSモジュールは値のコピーを出力しますが、ES6モジュールは値への参照を出力します。

2. CommonJSモジュールは実行時にロードされますが、ES6モジュールはコンパイル時に出力インターフェースになります。

CommonJS モジュールはオブジェクト (module.exports プロパティ) をエクスポートしますが、これはスクリプトの実行後にのみ生成されます。

ES6 のモジュール メカニズムは、JS エンジンがスクリプトの静的解析を実行するときに、モジュール読み込みコマンドの import に遭遇すると読み取り専用参照を生成します。スクリプトが実際に実行されると、この読み取り専用参照を使用して、読み込まれたモジュールから値を取得します。

AMD仕様

AMD (Asynchronous Module Definition) は、Require.JS を推進する過程でのモジュール定義の標準化された出力です。 AMD はフロントエンドの依存性を主張しています。これは、ブラウザで動作する CommonJS モジュール化仕様のスーパーセットです。その機能は非同期であり、ブラウザの同時実行機能を活用してモジュール依存関係のブロックを削減します。

AMD API

定義(ID?、依存関係?、ファクトリー);

id はモジュールの名前であり、オプションのパラメーターです。依存関係は、モジュールが依存するモジュールのリストを指定します。これは配列であり、オプションのパラメータです。各依存モジュールの出力は、順番にパラメータとしてファクトリに渡されます。

require([モジュール], コールバック)

AMD 仕様では、出力モジュールを CommonJS 仕様と互換性を持たせることができます。この場合、定義メソッドは次のようになります。

定義(['モジュール1', 'モジュール2'], 関数(モジュール1, モジュール2) {

関数foo(){

// ...

}

戻り値: foo;

});


定義(関数(require, exports, module) {

var 要求されたモジュール1 = require('./module1')

var 要求されたモジュール2 = require('./module2')

関数foo(){

// ...

}

戻り値: foo;

});

利点: ブラウザ環境でモジュールをロードするのに適しており、複数のモジュールを並行してロードできます。

デメリット: 開発コストが増大し、オンデマンドでロードできず、すべての依存関係を事前にロードする

CMD仕様

CMD は、Sea.JS プロモーションのプロセスにおけるモジュール定義の標準化された出力です。 CMD は近接性に頼ることを提唱しています。

CMD 仕様は可能な限りシンプルに保たれており、CommonJS 仕様のモジュールと互換性があります。CMD 仕様を使用して記述されたモジュールは、NodeJS で実行できます。

CMDモジュール定義仕様

CMD では、require 依存関係の記述で配列が使用されている場合、非同期的に読み込まれます。単一の依存関係で文字列が使用されている場合は、同期的に読み込まれます。

AMD は RequireJS の推進時に標準化されたモジュール定義の出力であり、CMD は SeaJS の推進時に広く認識されています。 SeaJS は中国の Ant Financial YuBo から生まれました。両者の違いについて、Yu Bo 氏は 2012 年に次のように述べています。

RequireJS と SeaJS はどちらも非常に優れたモジュール ローダーです。両者の違いは次のとおりです。

  • 両者の位置づけには違いがあります。 RequireJS はブラウザ用のモジュール ローダーになることを目指しており、Rhino/Node などの環境用のモジュール ローダーにもなりたいと思っています。 SeaJSはWebブラウザ側に重点を置いており、Node拡張機能を通じてNodeサーバー側で簡単に実行できます。
  • 両者が従う基準には違いがあります。 RequireJS は AMD (Asynchronous Module Definition) 仕様に準拠し、SeaJS は CMD (Common Module Definition) 仕様に準拠しています。仕様の違いは API の違いにつながります。 SeaJS はより簡潔でエレガントであり、CommonJS Modules/1.1 および Node Modules 仕様に近いです。
  • 両者のコミュニティ概念には違いがあります。 RequireJS は、サードパーティのライブラリに RequireJS をサポートするように修正してもらおうとしていますが、それを採用しているコミュニティはごくわずかです。 SeaJS は、何かを強制するのではなく、「すべての川と海を包含する」独立したパッケージング アプローチを採用しており、現在、比較的成熟したパッケージング戦略を採用しています。
  • 両者のコード品質には違いがあります。 RequireJS には明らかなバグはなく、SeaJS にも明らかなバグはありません。
  • 両者にはデバッグのサポートなどに違いがあります。 SeaJS はプラグインを通じて Fiddler での自動マッピング機能を実現できるほか、自動コンボなどの機能も実現できるので非常に便利です。 RequireJS ではこれはサポートされていません。
  • 両者のプラグインの仕組みは異なります。 RequireJS は、プラグイン用に記述されたコードが残されたソース コード内にインターフェースを予約する形式をとります。 SeaJS が採用しているプラ​​グイン メカニズムは、Node 自体のオープン方法と一致しており、プラグイン開発者が直接アクセスしたり変更したりできるため、非常に柔軟で、さまざまな種類のプラグインを実装できます。

UMD仕様

UMD (Universal Module Definition) は、大規模なフロントエンドのトレンドに合わせて作成され、フロントエンドとバックエンドにクロスプラットフォーム ソリューション (AMD、CMD、CommonJS モジュール メソッドをサポート) を提供することを目指しています。

実施原則:

1. まず、Node.jsモジュール形式がサポートされているかどうか(エクスポートが存在するかどうか)を確認します。サポートされている場合は、Node.jsモジュール形式を使用します。

2. AMD モジュール形式がサポートされているかどうか (定義が存在するかどうか) を確認します。存在する場合は、AMD モジュール形式を使用します。

3. 最初の2つが存在しない場合は、モジュールをグローバル(ウィンドウまたはグローバル)に公開します。

// モジュールに依存関係がない場合、上記のパターンは次のように簡略化できます。

(関数 (ルート、ファクトリー) {

if (typeof define === 'function' && define.amd) {

// AMD。匿名モジュールとして登録します。

ファクトリーを定義します。

} そうでない場合 (typeof exports === 'object') {

// Node. 厳密なCommonJSでは動作しませんが、

// module.exportsをサポートするCommonJSのような環境のみ、

// Node のように。

モジュールをエクスポートします。

} それ以外 {

// ブラウザのグローバル(ルートはウィンドウ)

ルート.returnExports = ファクトリ();

}

}(これ、関数() {

  

// モジュールのエクスポートを定義する値を返すだけです。

// この例ではオブジェクトを返しますが、モジュール

// エクスポートされた値として関数を返すことができます。

戻る {};

}));

上記の判決文にAMDと書いてあるのに、なぜCMDと書いてないのかと疑問に思う人もいるかもしれません。フロントエンド構築ツールのwebpackはCMD仕様を認識しないため、CMDを使用するにはSea.JSなどの参照ツールが必要です。

正直に言うと、CMD を判断したい場合、UMD コードをどのように記述しますか?

(関数(ルート、ファクトリー) {

if (typeof define === 'function' && define.amd) {

// AMD。匿名モジュールとして登録します。

ファクトリーを定義します。

} そうでない場合 (typeof define === 'function' && define.cmd) {

//コマンド

定義(関数(require, exports, module) {

module.exports = ファクトリー()

})

} そうでない場合 (typeof exports === 'object') {

// Node. 厳密なCommonJSでは動作しませんが、

// module.exportsをサポートするCommonJSのような環境のみ、

// Node のように。

モジュールをエクスポートします。

} それ以外 {

// ブラウザのグローバル(ルートはウィンドウ)

ルート.returnExports = ファクトリ();

}

}(これ、関数() {

// モジュールのエクスポートを定義する値を返すだけです。

// この例ではオブジェクトを返しますが、モジュール

// エクスポートされた値として関数を返すことができます。

戻る {};

}))

話題に戻る

Cheerio が通常の JS 実行環境にパッケージ化される方法。

webpack の助けを借りて、umd 標準パッケージを簡単に生成できます。

モジュール.エクスポート = {

エントリ: './src/cheerio.js',

出力: {

ファイル名: 'cheerio.js',

// AMD、CommonJS、またはウィンドウにエクスポート

ライブラリターゲット: 'umd',

// ウィンドウにエクスポートされる名前

ライブラリ: 'cheerio'、

グローバルオブジェクト: 'this'

}

}

要約する

モバイル フォン (iOS または Android) の基盤となるレンダリング カーネルは、Chrome v8 エンジンに似ています。 v8 エンジンが JS コードを実行する場合、まず MacroAssembler アセンブリ ライブラリを使用してコードをメモリ内でマシン コードにコンパイルし、その後 CPU に送信して実行します。他の JS エンジンのように行ごとに解析して実行することはありません。したがって、静的にロードされた ES6 モジュール仕様は、V8 エンジンがその価値を実現するのにさらに役立ちます。実行時にロードされる CommonJS、AMD、CMD 仕様は、V8 エンジンのパフォーマンス向上には役立ちません。

NodeJS 開発プロジェクトでは、Node9 はすでに ES6 構文をサポートしており、ES6 モジュール仕様を完全に使用できます。 NodeJS の誕生は Google の v8 エンジンに基づいています。v8 の最大の可能性を考慮しない理由はありません。

ブラウザ JS 開発プロジェクトでは、サーバーからファイルを読み込むのに時間がかかるため、CommonJS 仕様を使用することは絶対に適切ではありません。ネイティブ ES モジュール仕様を使用するか Sea.js を使用するかは、特定のシナリオによって異なります。ページの読み込みをできるだけ早く行いたい場合は Sea.js が適しています。シングルページの Web サイトの場合は、ネイティブ ES6 モジュール仕様を使用するのが適しています。もう1つのポイントは、ブラウザがChromeだけではないということです。v8エンジンを使用していないブラウザの場合、ES6ネイティブ仕様を使用する利点は少し減ります。

上記は、JS フロントエンドのモジュール化に関するいくつかの仕様の詳細について簡単に説明したものです。JS フロントエンドのモジュール化の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Node.js のモジュール性、npm パッケージ マネージャーの説明
  • NodeJSのモジュール性に関する詳細な説明
  • JavaScriptのモジュール性を理解する方法
  • Jsモジュール化の動作原理とソリューションの詳細な説明
  • モジュール管理を実現するための JavaScript でのエクスポートとインポートに関するチュートリアル
  • JavaScript のモジュール性の説明

<<:  Nginx 転送ソケットポート設定の詳細な説明

>>:  時間に基づいて日付をクエリするためのMySQL最適化テクニック

推薦する

MySQL トランザクション制御フローと ACID 特性

目次1. ACIDの特性トランザクション制御構文3. トランザクション同時実行例外1. ダーティリー...

JavaScript でオブジェクトをエレガントに扱う 6 つの方法

目次序文1. オブジェクト.freeze() 2. オブジェクト.seal() 3. オブジェクト....

Vue3.0 における Ref と Reactive の違いの詳細な分析

目次参照と反応参照反応的RefとReactiveの違いshallowRef と shallowRea...

this.parentNode.parentNode (親ノードの親ノード) はどういう意味ですか?

親ノードの親ノード、例えば、このような段落がありますHTML:コードをコピーコードは次のとおりです。...

CSS セレクターの重みの理解(個人テスト)

コードをコピーコードは次のとおりです。 <スタイル タイプ="text/css&qu...

相同性とクロスドメイン、jsonp(関数カプセル化)、CORS原則の詳細な分析

目次同一起源ポリシーAjax リクエストの制限: Ajaxは自身のサーバーにのみリクエストを送信でき...

Golang を使って Docker API を実際に操作する

目次SDKのインストールローカル Docker の管理コンテナの実行バックグラウンドでコンテナを実行...

ショートビデオ(Douyin)の透かし除去ツールの実装コード

目次1. まず最初のリンクを取得する2. ブラウザでこのリンクを開いてください3. アドレスを開くと...

HTML の基礎必読 - CSS スタイルシートの包括的な理解

CSS (カスケーディング スタイル シート) は、HTML Web ページを美しくするために使用さ...

HTML5+CSS3 ヘッダー作成例と更新

前回、私たちは 2 つのヘッダー レイアウト (フレックスボックス 1 つとフロート 1 つ) を考...

フォーム入力ボックスに関するWebデザインのヒント

この記事では、Web デザインにおけるフォーム入力ボックスに関するヒントとコードをいくつか紹介します...

フロントエンド JavaScript でローカルあいまい検索機能を実装する方法の例

目次1. プロジェクトの見通し2. 知識ポイントObject.assign() の使用法filter...

Dockerがコンテナを起動するたびに、IPとホストが指定した操作が実行されます。

序文Dockerを使ってHadoopクラスタを起動するたびに、ネットワークカードの再バインド、IPの...

MySQL 8.0.21 無料インストール版 設定方法 グラフィックチュートリアル

MySQLをインストールする6つの手順(インストールパッケージのみがインストール場所を選択できます)...

vue-router のハッシュモードと履歴モードの違い

vue-routerには2つのモードがありますハッシュモード履歴モード1. シングルページアプリケー...