ホームページ >ウェブフロントエンド >jsチュートリアル >フロントエンドのモジュール性を理解する (CommonJs、AMD、CMD)
フロントエンド モジュールの仕様には、CommonJs、AMD、CMD の 3 つがあります。
サーバーサイドではCommonJs、ブラウザ環境ではAMDとCMDを使用します。
AMDは、RequireJSのプロモーションプロセス中のモジュール定義の標準化された出力です。
CMDは、SeaJSのプロモーションプロセスにおけるモジュール定義の標準化された出力です。
AMD: 早期実行 (非同期ロード: 依存関係が最初に実行される) + 遅延実行
CMD: 遅延実行 (実行からロード、順番に実行)
関数 記述方法
function f1(){ //... } function f2(){ //... }
module は、特定の関数を実装するファイルです。ファイルに複数の関数を入れると、モジュールが形成されます。必要に応じてこのファイルをロードし、そのファイル内の関数を呼び出します。
しかし、これを行うとグローバル変数が汚染され、他のモジュールの変数名と競合しないという保証はなく、モジュールメンバー間の関係もありません。
オブジェクトの書き方
var module = { star : 0, f1 : function (){ //... }, f2 : function (){ //... } }; module.f1(); module.star = 1;
モジュールはオブジェクトとして記述され、モジュールのメンバーはオブジェクトの中にカプセル化されており、オブジェクトのプロパティを呼び出すことでモジュールのメンバーにアクセスして使用することができます。ただし、モジュールのメンバーも公開されるため、モジュールの内部状態が外部から変更される可能性があります。
関数をすぐに実行する
var module = (function(){ var star = 0; var f1 = function (){ console.log('ok'); }; var f2 = function (){ //... }; return { f1:f1, f2:f2 }; })(); module.f1(); //ok console.log(module.star) //undefined
内部のプライベート変数には外部からアクセスできない
CommonJSはサーバーサイドモジュールの仕様であり、Nodeによって推進され、使用されます。サーバー側のプログラミングは複雑であるため、モジュールなしではオペレーティング システムや他のアプリケーションと対話するのは困難です。使い方は以下の通りです:
math.js exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; increment.js var add = require('math').add; exports.increment = function(val) { return add(val, 1); }; index.js var increment = require('increment').increment; var a = increment(1); //2
CommonJS仕様によると:
単一のファイルがモジュールです。各モジュールには個別のスコープがあります。つまり、モジュール内で定義された変数は、グローバル オブジェクトの属性として定義されない限り、他のモジュールから読み取ることができません。
モジュール変数をエクスポートする最良の方法は、 module.exports オブジェクトを使用することです。
require メソッドを使用してモジュールをロードします。このメソッドは、ファイルを読み取って実行し、ファイル内の module.exports オブジェクトを返します
上記のコードを注意深く見ると、require が同期していることがわかります。モジュール システムは、モジュール ファイルの内容を同期的に読み取り、コンパイルして実行し、モジュール インターフェース を取得する必要があります。
しかし、これにはブラウザ側に多くの問題があります。
ブラウザ側で JavaScript をロードする最も簡単な方法は、ドキュメントに 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを挿入することです。ただし、スクリプト タグは本質的に非同期であり、従来の CommonJS モジュールをブラウザ環境に正常にロードすることはできません。
解決策の 1 つは、サーバー側コンポーネントを開発し、モジュール コードで静的分析を実行し、モジュールとその依存関係リストをブラウザーに返すことです。 これはうまく機能しますが、追加のコンポーネントをサーバーにインストールする必要があるため、基盤となるアーキテクチャを多数調整する必要があります。
別の解決策は、標準テンプレートのセットを使用してモジュール定義をカプセル化することです:
define(function(require, exports, module) { // The module code goes here });
このテンプレート コードのセットは、モジュール コードを実行する前に静的に分析し、依存関係リストを動的に生成する機会をモジュール ローダーに提供します。 。
math.js define(function(require, exports, module) { exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; }); increment.js define(function(require, exports, module) { var add = require('math').add; exports.increment = function(val) { return add(val, 1); }; }); index.js define(function(require, exports, module) { var inc = require('increment').increment; inc(1); // 2 });
AMDとは「Asynchronous Module Definition」の略で、「非同期モジュール定義」を意味します。 JavaScript ではネイティブにサポートされていないため、AMD 仕様を使用したページ開発には、有名な RequireJS である対応するライブラリ関数を使用する必要があります。実際、AMD は、RequireJS のプロモーション プロセス中にモジュール定義の標準化された出力を使用します。メソッドを使用してモジュールをロードする場合、モジュールのロードは後続のステートメントの実行には影響しません。このモジュールに依存するすべてのステートメントは、
コールバック関数で定義されます。このコールバック関数は、読み込みが完了するまで実行されません。 RequireJS は主に 2 つの問題を解決します
最初のパラメーター [module] は、
配列 内のメンバーはロードされるモジュールです。2 番目のパラメーター callback は、ロードが成功した後のコールバック関数です。 Math.add() と数学モジュールの読み込みは同期されず、ブラウザはフリーズしません。 require([module], callback);
require([increment'], function (increment) {
increment.add(1);
});
RequireJS定义了一个函数 define,它是全局变量,用来定义模块: define(id?, dependencies?, factory); 参数说明: id:指定义中模块的名字,可选;如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。 依赖dependencies:是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。 工厂方法factory,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。 来举个例子看看: RequireJs使用例子 require.config是用来定义别名的,在paths属性下配置别名。然后通过requirejs(参数一,参数二);参数一是数组,传入我们需要引用的模块名,第二个参数是个回调函数,回调函数传入一个变量,代替刚才所引入的模块。 引入模块也可以只写require()。requirejs通过define()定义模块,定义的参数上同。在此模块内的方法和变量外部是无法访问的,只有通过return返回才行. 将该模块命名为math.js保存。 main.js引入模块方法 CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。 在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下: require是可以把其他模块导入进来的一个参数;而exports是可以把模块内的一些属性和方法导出的;module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。 AMD是依赖关系前置,在定义模块的时候就要声明其依赖的模块; CMD是按需加载依赖就近,只有在用到某个模块的时候再去require: seajs使用例子
依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});
main.js
//别名配置
requirejs.config({
paths: {
jquery: 'jquery.min' //可以省略.js
}
});
//引入模块,用变量$表示jquery模块
requirejs(['jquery'], function ($) {
$('body').css('background-color','red');
});
math.js
define('math',['jquery'], function ($) {//引入jQuery模块
return {
add: function(x,y){
return x + y;
}
};
});
require(['jquery','math'], function ($,math) {
console.log(math.add(10,100));//110
});
CMD
define(function(require, exports, module) {
// 模块代码
});
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
})
// 定义模块 myModule.js
define(function(require, exports, module) {
var $ = require('jquery.js')
$('p').addClass('active');
exports.data = 1;
});
// 加载模块
seajs.use(['myModule.js'], function(my){
var star= my.data;
console.log(star); //1
});
以上がフロントエンドのモジュール性を理解する (CommonJs、AMD、CMD)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。