Maison >interface Web >Questions et réponses frontales >Quelle est la différence entre AMD et CMD modulaires front-end ?

Quelle est la différence entre AMD et CMD modulaires front-end ?

青灯夜游
青灯夜游original
2020-11-18 09:41:252312parcourir

Différence : AMD et CMD gèrent différemment le timing d'exécution des modules dépendants. AMD préconise la pré-dépendance et déclare les modules dont il dépend lors de la définition d'un module. CMD préconise les dépendances proches, uniquement lorsqu'un certain module est utilisé. Ensuite, allez à require lorsque vous installez le module.

Quelle est la différence entre AMD et CMD modulaires front-end ?

Au début du développement de JavaScript, il s'agissait d'implémenter une logique d'interaction de page simple en quelques mots ; les performances du processeur et du navigateur ont maintenant été considérablement améliorées. Une grande partie de la logique des pages a été migrée vers le client (validation de formulaires, etc.). Avec l'avènement de l'ère du web 2.0, la technologie Ajax a été largement utilisée, des bibliothèques frontales telles que jQuery émergent à l'infini, et des bibliothèques front-end apparaissent à l'infini. le code s'étend de plus en plus

À l'heure actuelle, JavaScript est utilisé comme un langage de script intégré. Le positionnement du langage de script a été ébranlé. JavaScript n'apporte aucune aide évidente à l'organisation du code. Il n'a même pas le concept de classes. , sans parler des modules. Les spécifications extrêmement simples d'organisation du code de JavaScript ne suffisent pas pour gérer une telle échelle de code

Module

Puisque JavaScript ne le peut pas. Pour gérer un code à si grande échelle, nous pouvons apprendre de la façon dont d'autres langages gèrent la programmation à grande échelle - package Les codes logiquement liés sont organisés dans le même package. royaume. Il n’y a pas lieu de s’inquiéter des conflits de noms. Et s’il est utilisé à l’extérieur ? Juste importpackage correspondant

import java.util.ArrayList;

Malheureusement, JavaScript ne fournit pas de fonctions similaires en raison de son positionnement lors de la conception. Les développeurs doivent simuler des fonctions similaires pour isoler et organiser des codes JavaScript complexes.

Un module est un fichier qui implémente une fonction spécifique. Avec un module, nous pouvons utiliser le code d'autres personnes plus facilement et charger le module de notre choix pour la fonction de notre choix. Le développement de modules doit suivre certaines normes, et tout le monde sera gâché s'il fait ce qu'il veut

Le processus de formation de normes est douloureux Les pionniers du front-end ont commencé au stade du slash-and-. brûler l'agriculture et boire du sang, et le développement a commencé à prendre forme maintenant. Comprenons brièvement ce paragraphe Un voyage extraordinaire

Encapsulation de fonctions

Quand nous parlions de fonctions, Nous avons mentionné que l'une des fonctions d'une fonction est de regrouper un ensemble d'instructions pour implémenter une logique spécifique, et la portée de JavaScript est basée sur des fonctions, il est donc naturel d'utiliser des fonctions comme première étape dans l'écriture de plusieurs fonctions liées. un fichier est le premier module

function fn1(){
    statement
}

function fn2(){
    statement
}

De cette façon, vous pouvez le clipser en cas de besoin, appelez simplement la fonction dans le fichier où se trouve la fonction

Les inconvénients de cette approche sont évidents : cela pollue les variables globales, il n'y a aucune garantie que les noms de variables n'entreront pas en conflit avec d'autres modules et il n'y a aucune relation entre les membres du module.

Objet

Afin de résoudre le problème ci-dessus, la méthode d'écriture d'objet a vu le jour. Tous les membres du module peuvent être encapsulés dans un objet

var myModule = {
    var1: 1,

    var2: 2,

    fn1: function(){

    },

    fn2: function(){

    }
}
comme ça On référence le fichier correspondant quand on veut appeler le module, et puis

myModule.fn2();
Cela évite la pollution variable, du moment que le nom du module est unique, et que les membres d'un même module sont également liés

Cela semble être une bonne solution, mais elle présente également des défauts. Les membres externes peuvent modifier les membres internes à volonté

myModel.var1 = 100;
Cela provoquera des problèmes de sécurité inattendus

Exécuter la fonction immédiatement.

Vous pouvez masquer les détails en exécutant des fonctions immédiatement

var myModule = (function(){
    var var1 = 1;
    var var2 = 2;

    function fn1(){

    }

    function fn2(){

    }

    return {
        fn1: fn1,
        fn2: fn2
    };
})();
De cette façon, les variables et les fonctions que nous n'avons pas exposées ne peuvent pas être modifiées en dehors du module

Ce qui précède Cette approche est la base de notre modularisation. Actuellement, il existe deux principaux types de spécifications de modules JavaScript populaires :

et CommonJSAMD

CommonJS

Commençons par CommonJS, car il n'y a pas de modules sur la page Web. Bien que JavaScript sur la page ait une logique complexe, il doit toujours y avoir des modules côté serveur. Par conséquent, même si JavaScript est développé sur le Web depuis de nombreuses années, la première spécification de modularisation populaire a été apportée par les applications JavaScript côté serveur. La spécification CommonJS est reprise par NodeJS, qui marque l'entrée officielle de la programmation modulaire JavaScript sur scène.

  1. Définir un module

    Selon la spécification CommonJS, un seul fichier est un module. Chaque module est 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

  2. Sortie du module : Le

    le module n'a qu'une seule sortie, l'objet
    Nous devons mettre le contenu que le module souhaite afficher dans l'objet module.exports

  3. Charger le module :

    Charger le module en utilisant.
    Méthode, cette méthode lit un fichier et l'exécute, renvoyant l'objet require à l'intérieur du fichier module.exports

Regardez un exemple

//模块定义 myModel.js

var name = 'Byron';

function printName(){
    console.log(name);
}

function printFullName(firstName){
    console.log(firstName + name);
}

module.exports = {
    printName: printName,
    printFullName: printFullName
}

//加载模块

var nameModule = require('./myModel.js');

nameModule.printName();
Différentes implémentations de la chemin lorsque cela est requis Il existe différentes exigences. Généralement, vous pouvez omettre l'extension

, utiliser un chemin relatif ou utiliser un chemin absolu, ou même omettre le chemin et utiliser directement le nom du module (à condition que le module soit un module intégré). dans le module du système) js

Navigateur maladroit

仔细看上面的代码,会发现require是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块接口。

这在服务器端实现很简单,也很自然,然而, 想在浏览器端实现问题却很多。

浏览器端,加载JavaScript最佳、最容易的方式是在document中插入script 标签。但脚本标签天生异步,传统CommonJS模块在浏览器环境中无法正常加载。

解决思路之一是,开发一个服务器端组件,对模块代码作静态分析,将模块与它的依赖列表一起返回给浏览器端。 这很好使,但需要服务器安装额外的组件,并因此要调整一系列底层架构。

另一种解决思路是,用一套标准模板来封装模块定义,但是对于模块应该怎么定义和怎么加载,又产生的分歧:

AMD

AMD 即Asynchronous Module Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范

由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎RequireJS,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出

requireJS主要解决两个问题

  1. 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
  2. js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长

看一个使用requireJS的例子

// 定义模块 myModule.js
define(['dependency'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }

    return {
        printName: printName
    };
});

// 加载模块
require(['myModule'], function (my){
  my.printName();
});

语法

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

define(id?, dependencies?, factory);
  1. id:可选参数,用来定义模块的标识,如果没有提供该参数,脚本文件名(去掉拓展名)
  2. dependencies:是一个当前模块依赖的模块名称数组
  3. factory:工厂方法,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值

在页面上使用require函数加载模块

require([dependencies], function(){});

require()函数接受两个参数

  1. 第一个参数是一个数组,表示所依赖的模块
  2. 第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块

require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

CMD

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

语法

Sea.js 推崇一个模块一个文件,遵循统一的写法

define

define(id?, deps?, factory)

因为CMD推崇

  1. 一个文件一个模块,所以经常就用文件名作为模块id
  2. CMD推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写

factory有三个参数

function(require, exports, module)

require

require 是 factory 函数的第一个参数

require(id)

require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口

exports

exports 是一个对象,用来向外提供模块接口

module

module 是一个对象,上面存储了与当前模块相关联的一些属性和方法

demo

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

// 加载模块
seajs.use(['myModule.js'], function(my){

});

AMD与CMD区别

关于这两个的区别网上可以搜出一堆文章,简单总结一下

最明显的区别就是在模块定义时对依赖的处理不同

  • AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块

  • CMD推崇就近依赖,只有在用到某个模块的时候再去require

这种区别各有优劣,只是语法上的差距,而且requireJS和SeaJS都支持对方的写法

AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同

Beaucoup de gens disent que requireJS est un module de chargement asynchrone et que SeaJS est un module de chargement synchrone. Cette compréhension est en fait inexacte. En fait, les modules de chargement sont tous asynchrones, mais AMD s'appuie sur le front-end et js peut facilement le savoir. qui est le module dépendant, se charge immédiatement et CMD s'appuie sur les dépendances proches. Vous devez utiliser le module pour le convertir en chaîne et l'analyser à nouveau pour savoir quels modules en dépendent. critiquer CMD. Il sacrifie les performances pour apporter la commodité du développement. En fait, les modules d'analyse utilisent le temps est si court qu'il peut être ignoré

Pourquoi disons-nous que la différence entre les deux est le timing d'exécution différent des dépendants. modules ? Pourquoi beaucoup de gens pensent qu'ADM est asynchrone et CMD est synchrone (sauf pour le nom...)

Les modules sont également chargés de manière asynchrone. AMD exécutera le module modifié après avoir chargé le module. les modules sont chargés et exécutés, il entrera dans la fonction de rappel require et exécutera la logique principale. Cet effet dépend de l'ordre d'exécution des modules. Il peut ne pas être cohérent avec l'ordre d'écriture. En fonction de la vitesse du réseau, celui qui est téléchargé. en premier et lequel est exécuté en premier, mais la logique principale doit être exécutée une fois que toutes les dépendances sont chargées

CMD ne sera pas exécuté après le chargement d'un certain module dépendant. Il s'agit simplement d'un téléchargement une fois que tous les modules dépendants sont chargés. entre dans la logique principale. Le module correspondant n'est exécuté que lorsque l'instruction require est rencontrée. De cette façon, l'ordre d'exécution et l'ordre d'écriture des modules sont complètement cohérents

C'est aussi ce que disent de nombreuses personnes de l'expérience utilisateur AMD. est bon car il n'y a pas de retard et les modules dépendants sont exécutés à l'avance. Les performances CMD sont bonnes car elles ne sont exécutées que lorsque l'utilisateur en a besoin

Pour plus de connaissances sur la programmation, veuillez visiter : Vidéo de programmation. ! !

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