ホームページ >ウェブフロントエンド >jsチュートリアル >フロントエンドのモジュール性を理解する (CommonJs、A​​MD、CMD)

フロントエンドのモジュール性を理解する (CommonJs、A​​MD、CMD)

怪我咯
怪我咯オリジナル
2017-04-05 13:50:154111ブラウズ

フロントエンド モジュールの仕様には、CommonJs、A​​MD、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

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(&#39;math&#39;).add;
exports.increment = function(val) {
    return add(val, 1);
};

index.js
var increment = require(&#39;increment&#39;).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(&#39;math&#39;).add;
  exports.increment = function(val) {
    return add(val, 1);
  };
});

index.js
define(function(require, exports, module) {
  var inc = require(&#39;increment&#39;).increment;
  inc(1); // 2
});

AMD

AMDとは「Asynchronous Module Definition」の略で、「非同期モジュール定義」を意味します。 JavaScript ではネイティブにサポートされていないため、AMD 仕様を使用したページ開発には、有名な RequireJS である対応するライブラリ関数を使用する必要があります。実際、AMD は、RequireJS のプロモーション プロセス中にモジュール定義の標準化された出力を使用します。メソッドを使用してモジュールをロードする場合、モジュールのロードは後続のステートメントの実行には影響しません。このモジュールに依存するすべてのステートメントは、

コールバック関数

で定義されます。このコールバック関数は、読み込みが完了するまで実行されません。 RequireJS は主に 2 つの問題を解決します

    複数の js ファイルには依存関係がある可能性があり、依存ファイルは依存するファイルよりも早くブラウザに読み込まれる必要があります
  • js がロードされると、ブラウザはページのレンダリングを停止しますロードされると、ロードされるファイルが増えるほど、ページの応答時間は長くなります
  • RequireJs も、モジュールをロードするために require() ステートメントを使用しますが、CommonJS とは異なり、2 つのパラメーターが必要です:

最初のパラメーター [module] は、

配列

内のメンバーはロードされるモジュールです。2 番目のパラメーター callback は、ロードが成功した後のコールバック関数です。 Math.add() と数学モジュールの読み込みは同期されず、ブラウザはフリーズしません。

require([module], callback);

require([increment&#39;], function (increment) {
    increment.add(1);
});

define()関数

  RequireJS定义了一个函数 define,它是全局变量,用来定义模块:

  define(id?, dependencies?, factory);

  参数说明:

  • id:指定义中模块的名字,可选;如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。

  • 依赖dependencies:是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
    依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。

  • 工厂方法factory,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

  来举个例子看看:

define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
       exports.verb = function() {
           return beta.verb();
           //Or:
           return require("beta").verb();
       }
   });

  RequireJs使用例子

  require.config是用来定义别名的,在paths属性下配置别名。然后通过requirejs(参数一,参数二);参数一是数组,传入我们需要引用的模块名,第二个参数是个回调函数,回调函数传入一个变量,代替刚才所引入的模块。

main.js
//别名配置
requirejs.config({
    paths: {
        jquery: &#39;jquery.min&#39; //可以省略.js
    }
});
//引入模块,用变量$表示jquery模块
requirejs([&#39;jquery&#39;], function ($) {
    $(&#39;body&#39;).css(&#39;background-color&#39;,&#39;red&#39;);
});

  引入模块也可以只写require()。requirejs通过define()定义模块,定义的参数上同。在此模块内的方法和变量外部是无法访问的,只有通过return返回才行.

math.js
define(&#39;math&#39;,[&#39;jquery&#39;], function ($) {//引入jQuery模块
    return {
        add: function(x,y){
            return x + y;
        }
    };
});

  将该模块命名为math.js保存。

require([&#39;jquery&#39;,&#39;math&#39;], function ($,math) {
    console.log(math.add(10,100));//110
});

  main.js引入模块方法

 CMD

  CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。

  在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下:

define(function(require, exports, module) {

  // 模块代码

});

  require是可以把其他模块导入进来的一个参数;而exports是可以把模块内的一些属性和方法导出的;module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。

  AMD是依赖关系前置,在定义模块的时候就要声明其依赖的模块;

  CMD是按需加载依赖就近,只有在用到某个模块的时候再去require:

// CMD
define(function(require, exports, module) {
  var a = require(&#39;./a&#39;)
  a.doSomething()
  // 此处略去 100 行
  var b = require(&#39;./b&#39;) // 依赖可以就近书写
  b.doSomething()
  // ... 
})

// AMD 默认推荐的是
define([&#39;./a&#39;, &#39;./b&#39;], function(a, b) { // 依赖必须一开始就写好
  a.doSomething()
  // 此处略去 100 行
  b.doSomething()
  ...
})

  seajs使用例子

// 定义模块  myModule.js
define(function(require, exports, module) {
  var $ = require(&#39;jquery.js&#39;)
  $(&#39;p&#39;).addClass(&#39;active&#39;);
  exports.data = 1;
});

// 加载模块
seajs.use([&#39;myModule.js&#39;], function(my){
    var star= my.data;
    console.log(star);  //1
});

以上がフロントエンドのモジュール性を理解する (CommonJs、A​​MD、CMD)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。