Maison  >  Article  >  interface Web  >  Comprendre la modularité front-end (CommonJs, AMD et CMD)

Comprendre la modularité front-end (CommonJs, AMD et CMD)

怪我咯
怪我咯original
2017-04-05 13:50:154072parcourir

Il existe trois spécifications de modules front-end : CommonJs, AMD et CMD.

CommonJs est utilisé côté serveur, AMD et CMD sont utilisés dans l'environnement du navigateur.

AMD est la sortie standardisée des définitions de modules pendant le processus de promotion de RequireJS.

CMD est le résultat standardisé de la définition du module pendant le processus de promotion de SeaJS.

AMD : Exécution anticipée (chargement asynchrone : les dépendances sont exécutées en premier) + exécution différée

CMD : Exécution différée (exécuter pour charger, exécutée dans l'ordre)

Module

Fonction Écriture

function f1(){
    //...
}
function f2(){
    //...
}

Un module est un fichier qui implémente une fonction spécifique. Il consiste à mettre plusieurs fonctions dans un seul fichier. .un module. Chargez ce fichier si nécessaire et appelez les fonctions qu'il contient.

Mais cela polluerait la variable globale, il n'y a aucune garantie qu'il n'y aura pas de conflit de nom de la variable avec d'autres modules, et il n'y a aucune relation entre les modules membres.

 ObjetÉcriture

var module = {
  star : 0,
  f1 : function (){
    //...
  },
  f2 : function (){
    //...
  }
};
module.f1();
module.star = 1;

Le module est écrit en tant qu'objet et les membres du module sont encapsulés dans l'objet en appelant l'objetattribut<.>, vous pouvez accéder au module membre. Mais en même temps, les membres du module sont exposés et l'état interne du module peut être modifié par le monde extérieur.

Exécuter la fonction immédiatement

var module = (function(){
    var star = 0;
    var f1 = function (){
      console.log(&#39;ok&#39;);
    };
    var f2 = function (){
      //...
    };
       return {
          f1:f1,
          f2:f2
       };
  })();
module.f1();  //ok
console.log(module.star)  //undefined
Impossible d'accéder en externe aux variables privées internes

CommonJs

CommonJS est une spécification pour les modules côté serveur, promue et utilisée par Noeud. En raison de la complexité de la programmation côté serveur, il est difficile d'interagir avec le système d'exploitation et d'autres applications sans modules. L'utilisation est la suivante :

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
Selon la spécification CommonJS :

  • Un seul fichier est un module. Chaque module a une portée distincte, c'est-à-dire que les variables définies dans le module ne peuvent pas être lues par d'autres modules à moins qu'elles ne soient définies comme attributs de l'objet global.

  • La meilleure façon d'exporter des variables de module est d'utiliser l'objet module.exports.

  • Chargez le module en utilisant la méthode require, qui lit un fichier et l'exécute, en renvoyant l'objet module.exports à l'intérieur du fichier

Regardez attentivement le code ci-dessus, vous remarquerez que require est synchrone. Le système de modules doit lire le contenu du fichier de module de manière synchrone, le compiler et l'exécuter pour obtenir l'interface

du module .

Cependant, cela pose de nombreux problèmes du côté du navigateur.

Côté navigateur, le moyen le meilleur et le plus simple de charger JavaScript est d'insérer la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a Cependant, les balises de script sont intrinsèquement asynchrones et les modules CommonJS traditionnels ne peuvent pas être chargés normalement dans l'environnement du navigateur.

L'une des solutions consiste à développer un composant côté serveur, à effectuer une analyse statique sur le code du module et à renvoyer le module et sa liste de dépendances au navigateur. Cela fonctionne bien, mais nécessite l'installation de composants supplémentaires sur le serveur et donc un certain nombre d'ajustements de l'architecture sous-jacente.

Une autre solution consiste à utiliser un ensemble de modèles standards pour encapsuler la définition du module :

define(function(require, exports, module) {

  // The module code goes here

});
Cet ensemble de code de modèle offre la possibilité au chargeur de module de charger le fichier Avant l'exécution, le le code du module est analysé statiquement et la liste des dépendances est générée dynamiquement.

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 est l'abréviation de « Asynchronous Module Definition », qui signifie « définition de module asynchrone ». Comme il n'est pas supporté nativement par JavaScript, le développement de pages utilisant les spécifications AMD nécessite l'utilisation des fonctions de bibliothèque correspondantes, qui est le fameux RequireJS. En fait, AMD est la sortie standardisée des définitions de modules lors du processus de promotion de RequireJS

Il utilise Le module est chargé de manière asynchrone et le chargement du module n'affecte pas l'exécution des instructions suivantes. Toutes les instructions qui dépendent de ce module sont définies dans une

fonction de rappel

Cette fonction de rappel ne s'exécutera pas tant que le chargement n'est pas terminé.  RequireJS résout principalement deux problèmes

    Plusieurs fichiers js peuvent avoir des dépendances, et les fichiers dépendants doivent être chargés dans le navigateur plus tôt que les fichiers qui en dépendent
  • Le navigateur arrêtera le rendu de la page lorsque js sera chargé. Plus il y a de fichiers chargés, plus la page perdra du temps de réponse
  • RequireJs également. utilise require() L'instruction charge le module, mais contrairement à CommonJS, elle nécessite deux paramètres :

Le premier paramètre [module] est un

tableau

, et les membres à l'intérieur sont les modules à chargé; le deuxième paramètre Le rappel du paramètre est la fonction de rappel après un chargement réussi. Math.add() et le chargement du module mathématique ne sont pas synchronisés et le navigateur ne se fige pas.

 
require([module], callback);

require([increment&#39;], function (increment) {
    increment.add(1);
});
Fonction 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
});

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn