Maison  >  Article  >  interface Web  >  Explication détaillée des spécifications du module en JS (CommonJS, AMD, CMD)

Explication détaillée des spécifications du module en JS (CommonJS, AMD, CMD)

php是最好的语言
php是最好的语言original
2018-08-07 09:21:442007parcourir

Répondez-moi d'abord : Pourquoi les modules sont-ils importants ?

Réponse : Grâce aux modules, nous pouvons utiliser le code d'autres personnes plus facilement et charger les modules que nous voulons pour les fonctions que nous voulons.
Cependant, il y a un prérequis pour cela, c'est-à-dire que tout le monde doit écrire le module de la même manière, sinon vous avez votre façon d'écrire, et j'ai ma façon d'écrire, ne le feriez-vous pas c'est le bordel !

Les trois modules suivants ont donc été standardisés, et cet article a également été publié (énoncé {couverture du visage et rire}).

Spécification du module en JS (CommonJS, AMD, CMD), si vous avez entendu parler de la modularisation js, alors vous devriez en avoir entendu parler ou CommonJS ou AMD ou même moi. entendu parler de ces réglementations CMD, mais avant, je me contentais de les écouter. Voyons maintenant ce que sont ces spécifications et ce qu’elles font. Cet article reprend les sources de ces trois spécifications et les principes de leurs produits correspondants.

1. CommonJS

1 Au début, tout le monde pensait que JS était une fille sexy. , c'est inutile. L'API officiellement définie ne peut créer que des applications basées sur un navigateur. Vous vous moquez de moi, c'est trop étroit (un mot haut de gamme est utilisé, charlatan n'en peut plus). les API courantes utilisées par les applications (principalement les applications autres que les navigateurs) comblent cette lacune. Son objectif ultime est de fournir une bibliothèque standard similaire à Python, Ruby et Java. Dans ce cas, les développeurs peuvent utiliser l'API CommonJS pour écrire des applications, puis ces applications peuvent s'exécuter dans différents interpréteurs JavaScript et différents environnements hôtes.

Dans les systèmes compatibles avec CommonJS, vous pouvez utiliser JavaScript pour développer les programmes suivants :

Application JavaScript côté serveur<.>

(2). Outil de ligne de commande
(3) Application d'interface graphique
(4). Titanium ou Adobe AIR)
En 2009, le programmeur américain Ryan Dahl a créé le projet node.js pour utiliser le langage javascript pour la programmation côté serveur. Cela marque la naissance officielle de la « programmation modulaire Javascript ». Parce que pour être honnête, dans un environnement de navigateur, ne pas avoir de modules n'est pas un gros problème. Après tout, la complexité des programmes Web est limitée, mais côté serveur, il doit y avoir des modules pour interagir avec le système d'exploitation et les autres applications. sinon il n'y a aucun moyen de programmer. NodeJS est une implémentation de la spécification CommonJS, et webpack est également écrit sous la forme de CommonJS.

Le système de modules de node.js est implémenté en référence à la spécification CommonJS. Dans CommonJS, il existe une méthode globale require() pour charger les modules. En supposant qu'il existe un module mathématique math.js, il peut être chargé comme suit.

var math = require('math');

Ensuite, vous pouvez appeler la méthode fournie par le module :

var math = require('math');

math.add(2,3); 5

Les modules définis par CommonJS sont divisés en : {référence du module (require)} {définition du module (exports)} {identification du module (module)}

require() est utilisé pour introduire des modules externes ; l'objet exports est utilisé pour exporter des méthodes ou des variables du module actuel, le seul port d'export l'objet module représente le module lui-même.

Bien que Node suive les spécifications de CommonJS, il a fait quelques compromis et ajouté de nouvelles choses.

Cependant, après avoir parlé de CommonJS et également de Node, je pense que nous devons d'abord comprendre NPM. En tant que gestionnaire de packages de Node, NPM n'est pas destiné à aider Node à résoudre le problème d'installation des packages dépendants. Il doit également suivre la spécification CommonJS. Il suit la spécification (ou la théorie) du package. CommonJS WIKI parle de son histoire et présente également des modules, des packages, etc.

Parlons du principe et de la mise en œuvre simple de commonJS :

1. Parcourir La raison fondamentale pour laquelle le serveur n'est pas compatible avec CommonJS est le manque de quatre variables d'environnement Node.js.

module
  • exportations
  • exiger
  • mondial
Tant que ces quatre variables sont fournies, le navigateur peut charger le module CommonJS.

Voici un exemple simple.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">var module <span class="token operator">= <span class="token punctuation">{<br> exports<span class="token punctuation">: <span class="token punctuation">{<span class="token punctuation">}<br><span class="token punctuation">}<span class="token punctuation">;<br><br><span class="token punctuation">(<span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">) <span class="token punctuation">{<br> exports<span class="token punctuation">.multiply <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(n<span class="token punctuation">) <span class="token punctuation">{ <span class="token keyword">return n <span class="token operator">* <span class="token number">1000 <span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">(module<span class="token punctuation">, module<span class="token punctuation">.exports<span class="token punctuation">)<span class="token punctuation">)<br><br><span class="token keyword">var f <span class="token operator">= module<span class="token punctuation">.exports<span class="token punctuation">.multiply<span class="token punctuation">;<br><span class="token function">f<span class="token punctuation">(<span class="token number">5<span class="token punctuation">)<span class="token comment"> // 5000 <br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Le code ci-dessus fournit deux variables externes, module et exports, à une fonction d'exécution immédiate, et le module est placé ici pour une exécution immédiate à l’intérieur de la fonction. La valeur de sortie du module est placée dans module.exports, réalisant ainsi le chargement du module.

2. Implémentation de BrowserifySi vous connaissez le principe, vous pouvez faire outils . Browserify est actuellement l'outil de conversion de format CommonJS le plus couramment utilisé.

Veuillez voir un exemple où le module main.js charge le module foo.js.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><span class="token comment"><br>// foo.js<br>module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token comment"><br>// main.js<br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
Utilisez la commande suivante pour convertir main.js dans un format utilisable par le navigateur.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browserify main<span class="token punctuation">.js <span class="token operator">> compiled<span class="token punctuation">.js<br/></span></span></span></code></span>
Que fait exactement Browserify ? Installez le décompresseur du navigateur et vous pourrez voir clairement.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ npm install browser<span class="token operator">-unpack <span class="token operator">-g<br/></span></span></code></span>
Ensuite, décompressez le compile.js généré précédemment.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browser<span class="token operator">-unpack <span class="token operator">< compiled<span class="token punctuation">.js<br/><br/><span class="token punctuation">[<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"module.exports = function(x) {\n console.log(x);\n};"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token punctuation">}<br/><span class="token punctuation">}<span class="token punctuation">,<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">2<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"var foo = require(\"./foo\");\nfoo(\"Hi\");"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token string">"./foo"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">}<span class="token punctuation">,<br/><span class="token string">"entry"<span class="token punctuation">:<span class="token boolean">true<br/><span class="token punctuation">}<br/><span class="token punctuation">]<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span>
Comme vous pouvez le voir,browerify place tous les modules dans un tableau, l'attribut id est le numéro du module et le L'attribut source est le code source du module, l'attribut deps est la dépendance du module.

Comme foo.js est chargé dans main.js, l'attribut deps précise ./foo correspondant au module n°1. Pendant l'exécution, lorsque le navigateur rencontre l'instruction require('./foo'), il exécute automatiquement l'attribut source du module n°1 et génère la valeur de l'attribut module.exports exécuté.

3. Petit navigateur requis

Bien que Browserify soit très puissant, il ne peut pas être utilisé dans le navigateur, ce qui est parfois très gênant.

J'ai créé un chargeur de module CommonJS pour navigateur pur tiny-browser-require basé sur l'implémentation interne de mocha. Il n'y a pas du tout besoin de ligne de commande, il suffit de la mettre directement dans le navigateur. Le code entier ne fait que plus de 30 lignes.

La logique est très simple, c'est-à-dire que le module est lu dans le tableau et que le chemin de chargement est l'identifiant du module.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">function <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">var path <span class="token operator">= require<span class="token punctuation">.<span class="token function">resolve<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var mod <span class="token operator">= require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">]<span class="token punctuation">;<br><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">) <span class="token keyword">throw <span class="token keyword">new <span class="token class-name">Error<span class="token punctuation">(<span class="token string">'failed to require "' <span class="token operator">+ p <span class="token operator">+ <span class="token string">'"'<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">.exports<span class="token punctuation">) <span class="token punctuation">{<br> mod<span class="token punctuation">.exports <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br> mod<span class="token punctuation">.<span class="token function">call<span class="token punctuation">(mod<span class="token punctuation">.exports<span class="token punctuation">, mod<span class="token punctuation">, mod<span class="token punctuation">.exports<span class="token punctuation">, require<span class="token punctuation">.<span class="token function">relative<span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<br><span class="token keyword">return mod<span class="token punctuation">.exports<span class="token punctuation">;<br><span class="token punctuation">}<br><br>require<span class="token punctuation">.modules <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.resolve <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">var orig <span class="token operator">= path<span class="token punctuation">;<br><span class="token keyword">var reg <span class="token operator">= path <span class="token operator">+ <span class="token string">'.js'<span class="token punctuation">;<br><span class="token keyword">var index <span class="token operator">= path <span class="token operator">+ <span class="token string">'/index.js'<span class="token punctuation">;<br><span class="token keyword">return require<span class="token punctuation">.modules<span class="token punctuation">[reg<span class="token punctuation">] <span class="token operator">&& reg<br><span class="token operator">|| require<span class="token punctuation">.modules<span class="token punctuation">[index<span class="token punctuation">] <span class="token operator">&& index<br><span class="token operator">|| orig<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.register <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">, fn<span class="token punctuation">)<span class="token punctuation">{<br> require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">] <span class="token operator">= fn<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.relative <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(parent<span class="token punctuation">) <span class="token punctuation">{<br><span class="token keyword">return <span class="token keyword">function<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">if <span class="token punctuation">(<span class="token string">'.' <span class="token operator">!<span class="token operator">= p<span class="token punctuation">.<span class="token function">charAt<span class="token punctuation">(<span class="token number">0<span class="token punctuation">)<span class="token punctuation">) <span class="token keyword">return <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var path <span class="token operator">= parent<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">'/'<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var segs <span class="token operator">= p<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">'/'<span class="token punctuation">)<span class="token punctuation">;<br> path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br><br><span class="token keyword">for <span class="token punctuation">(<span class="token keyword">var i <span class="token operator">= <span class="token number">0<span class="token punctuation">; i <span class="token operator">945e8d4292ce0af7e515c6c2ee692956<br><br>3f1c4e4b6b16bbbd69b2ee476dc4f83a<br>require.register("moduleId", function(module, exports, require){<br> // Module code goes here<br>});<br>var result = require("moduleId");<br>2cacc6d41bbb37262a98f745aa00fbf0<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

 还是以前面的 main.js 加载 foo.js 为例。

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br>require<span class="token punctuation">.<span class="token function">register<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">, <span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">, require<span class="token punctuation">)<span class="token punctuation">{<br> module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;<br><br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

 注意,这个库只模拟了 require 、module 、exports 三个变量,如果模块还用到了 global 或者其他 Node 专有变量(比如 process),就通过立即执行函数提供即可。

二、AMD

基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上面的代码,如果在浏览器中运行,会有一个很大的问题,你能看出来吗?

  var math = require('math');

  math.add(2, 3);

 第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到 require 是同步的。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

 因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

  require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:

  require(['math'], function (math) {

    math.add(2, 3);

  });

math.add() et le chargement du module mathématique ne sont pas synchronisés et le navigateur ne se fige pas. Alors évidemment, AMD est plus adapté à l’environnement navigateur. Actuellement, il existe deux bibliothèques Javascript principales qui implémentent la spécification AMD : require.js et curl.js.

RequireJS implémente la spécification AMD.

Résumé détaillé : Ce qui suit utilise RequireJS comme exemple pour illustrer la spécification AMD

1. Pourquoi utiliser require .js ?

Au début, tous les codes Javascript étaient écrits dans un seul fichier, et il suffisait de charger ce seul fichier. Plus tard, il y a eu de plus en plus de codes, et un seul fichier ne suffisait plus. Il fallait le diviser en plusieurs fichiers et les charger séquentiellement. Je pense que beaucoup de gens ont vu le code de page Web suivant

 82aa3526d91a1e63399c31e3e88e82b62cacc6d41bbb37262a98f745aa00fbf0
 971749f558e9aa1fbc82591b103db9852cacc6d41bbb37262a98f745aa00fbf0
 847a2b365bb3326fcac7e8b83c77b8e1a74876beb1451ad9c5a8fbbfbd323c6b2cacc6d41bbb37262a98f745aa00fbf0
 a5b5ffe2660156a5fc46b07e767cb8819429d6e1efad07153846e528605c447e
 6b211ef2cac820d88c79506423962afa2cacc6d41bbb37262a98f745aa00fbf0

Ce code charge plusieurs fichiers js en séquence.

Cette façon d'écrire présente de gros inconvénients. Tout d'abord, lors du chargement, le navigateur cessera de restituer la page Web. Plus il y a de fichiers chargés, plus la page Web perdra de réponse. Deuxièmement, en raison des dépendances entre les fichiers js, l'ordre de chargement doit être strictement garanti (tel que). comme dans l'exemple ci-dessus) 1.js doit être devant 2.js), et le module avec la plus grande dépendance doit être chargé en dernier. Lorsque les dépendances sont complexes, l'écriture et la maintenance du code deviendront difficiles.

require.js est né pour résoudre ces deux problèmes :

 

 (1) Implémenter le chargement asynchrone des fichiers js pour éviter que les pages Web ne perdent de réponse

 (2) Gestion entre modules Les dépendances facilitent l'écriture de code ; et l'entretien.

2. Chargement de require.js

Utiliser require.js La première étape consiste à se rendre sur le site officiel pour télécharger la dernière version.

Après le téléchargement, on suppose que vous le placez dans le sous-répertoire js et qu'il peut être chargé.

 7c439788e166f531c8ad0b30265c71032cacc6d41bbb37262a98f745aa00fbf0

Certaines personnes peuvent penser que le chargement de ce fichier peut également entraîner une perte de réponse de la page Web. Il y a deux solutions, l'une est de le charger en bas de la page web, et l'autre est de l'écrire comme suit :

 < ;script src=" js/require.js" defer async="true" >2cacc6d41bbb37262a98f745aa00fbf0

L'attribut async indique que ce fichier doit être chargé de manière asynchrone pour éviter que la page Web ne réponde. IE ne prend pas en charge cet attribut et ne prend en charge que defer, donc defer est également écrit.

Après avoir chargé require.js, l'étape suivante consiste à charger notre propre code. Supposons que notre propre fichier de code soit main.js et soit également placé dans le répertoire js. Ensuite, écrivez-le simplement comme suit :

 35be17e58c59207c30045b58673f385a< ;

L'attribut data-main est utilisé pour spécifier le module principal du programme Web. Dans l'exemple ci-dessus, il s'agit de main.js sous le répertoire js. Ce fichier sera d'abord chargé par require.js. Étant donné que l'extension de fichier par défaut de require.js est js, main.js peut être abrégé en main.

3. Comment écrire le module principal

main.js du précédent section, je l'appelle le "module principal", ce qui signifie le code d'entrée pour l'ensemble de la page Web. C'est un peu comme la fonction main() en langage C, tout le code commence à s'exécuter à partir d'ici.

Voyons comment écrire main.js.

Si notre code ne dépend d'aucun autre module, nous pouvons écrire directement du code javascript.

// main.js

alert("Chargement réussi !");

Mais dans ce cas, il n'est pas nécessaire d'utiliser require.js. Une situation très courante est que le module principal dépend d'autres modules, auquel cas la fonction require() définie par la spécification AMD doit être utilisée.

// main.js

require(['moduleA', 'moduleB', ' moduleC'], fonction (moduleA, moduleB, moduleC){

    // du code ici

 });

La fonction require() accepte deux paramètres. Le premier paramètre est un tableau, indiquant les modules dont il dépend. L'exemple ci-dessus est ['moduleA', 'moduleB', 'moduleC'], c'est-à-dire que le module principal dépend de ces trois modules. fonction. Actuellement, il sera appelé une fois que tous les modules spécifiés ci-dessus auront été chargés avec succès. Les modules chargés seront transmis à cette fonction en tant que paramètres, afin que ces modules puissent être utilisés dans la fonction de rappel.

require() charge moduleA, moduleB et moduleC de manière asynchrone, et le navigateur ne perdra pas la réponse ; la fonction de rappel qu'il spécifie ne sera utilisée qu'après les modules précédents ; sont chargés avec succès, s’exécuteront, résolvant le problème de dépendance.

Ci-dessous, regardons un exemple pratique.

En supposant que le module principal dépend des trois modules jquery, underscore et backbone, main.js peut s'écrire comme ceci :

require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){

// du code ici

 });

require.js chargera d'abord jQuery, le trait de soulignement et le backbone, puis exécutera la fonction de rappel. Le code du module principal est écrit dans la fonction de rappel.

4. Chargement du module

Dans le dernier exemple de la section précédente, le main Les modules dépendants du module sont ['jquery', 'underscore', 'backbone']. Par défaut, require.js suppose que ces trois modules se trouvent dans le même répertoire que main.js, les noms de fichiers étant jquery.js, underscore.js et backbone.js, puis les charge automatiquement.

En utilisant la méthode require.config(), nous pouvons personnaliser le comportement de chargement du module. require.config() est écrit en tête du module principal (main.js). Le paramètre est un objet, et l'attribut paths de cet objet spécifie le chemin de chargement de chaque module.

require.config({

chemins : {

"jquery" : "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"

 }

});

Le code ci-dessus donne trois Le fichier nom d'un module. Le chemin par défaut est le même répertoire que main.js (sous-répertoire js). Si ces modules se trouvent dans d'autres répertoires, comme le répertoire js/lib, il existe deux manières de les écrire. La première consiste à spécifier les chemins un par un.

require.config({

chemins : {

  "jquery": "lib/jquery.min",
  "underscore": "lib/underscore.min",
  "backbone": " lib/backbone.min"

  }

 });

L'autre consiste à changer directement le répertoire de base (baseUrl).

require.config({

baseUrl : "js/lib",

Chemins : {

"jquery": "jquery.min",
"underscore": "underscore.min ",
 "backbone": "backbone.min"

  }

 });

Si un module est sur un autre hébergeur, vous pouvez également préciser directement son URL, par exemple :

require.config({

Chemins : {

 "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"

 }

 });

require.js nécessite que chaque module soit un fichier js distinct. Dans ce cas, si plusieurs modules sont chargés, plusieurs requêtes HTTP seront émises, ce qui affectera la vitesse de chargement de la page Web. Par conséquent, require.js fournit un outil d'optimisation une fois le module déployé, vous pouvez utiliser cet outil pour fusionner plusieurs modules en un seul fichier afin de réduire le nombre de requêtes HTTP.

5. Comment écrire le module AMD

Le module chargé par require.js est utilisé les spécifications AMD. En d'autres termes, le module doit être écrit conformément aux réglementations AMD.

Plus précisément, le module doit être défini à l'aide d'une fonction définie () spécifique. Si un module ne dépend pas d'autres modules, il peut être défini directement dans la fonction définir().

Supposons qu'il existe un fichier math.js, qui définit un module mathématique. Ensuite, math.js doit être écrit comme ceci :

  // math.js

define(function (){

 var add = function (x,y){

   return x+y;

} ;

return {

ajouter : ajouter

 });

La méthode de chargement est la suivante :

// main.

require(['math'], function (math){

alert(math.add(1,1));

 });

Si ce module dépend également d'autres modules, alors la fonction definition() Le premier paramètre doit être un tableau indiquant les dépendances du module.

Define(['myLib'], function(myLib){

function foo(){

myLib.doSomething();

 }

return {

   foo : foo

  };

 }); 🎜>

Lorsque la fonction require() charge le module ci-dessus, le fichier myLib.js sera chargé en premier.

6. Chargement des modules non standards

Théoriquement, les modules chargés par require.js doivent être des modules définis avec la fonction definition() conformément aux spécifications AMD. Mais en réalité, même si certaines bibliothèques de fonctions populaires (telles que jQuery) sont déjà conformes à la spécification AMD, de nombreuses autres bibliothèques ne le sont pas. Alors, require.js peut-il charger des modules non standard ?

La réponse est oui.

Avant de charger de tels modules avec require(), vous devez d'abord utiliser la méthode require.config() pour définir certaines de leurs caractéristiques.

Par exemple, les deux bibliothèques underscore et backbone ne sont pas écrites en utilisant les spécifications AMD. Si vous souhaitez les charger, vous devez au préalable définir leurs caractéristiques.

require.config({

shim : {

'soulignement' :{
exports : '_'
},

'backbone' : {
deps : ['underscore', 'jquery'],
exports : 'Backbone'
}

  }

 });

require.config() accepte un objet de configuration Cet objet. En plus de l'attribut paths mentionné précédemment, il existe également un attribut shim, spécialement utilisé pour configurer des modules incompatibles. Plus précisément, chaque module doit définir (1) la valeur exports (nom de la variable de sortie), qui indique le nom du module lorsqu'il est appelé en externe ; (2) le tableau deps, qui indique les dépendances du module ;

Par exemple, un plug-in jQuery peut être défini comme ceci :

shim : {

 'jquery.scroll' : {

  deps : ['jquery'],

exports : 'jQuery .fn.scroll'

  }

 }

7. Le plug-in require.js

require.js fournit également une série de plug-ins pour implémenter certaines fonctions spécifiques.

le plug-in domready permet à la fonction de rappel de s'exécuter après le chargement de la structure DOM de la page.

require(['domready!'], function (doc){

// appelée une fois le DOM prêt

 });

les plug-ins de texte et d'image permettent à require.js de charger du texte et des images document.

 définir([

    'text!review.txt',

    'image!cat.jpg'

    ],

    function(review,cat){

      console.log(review);

      document.body.appendChild(cat);

    }

  );

 类似的插件还有json和mdown,用于加载json文件和markdown文件。(完)

 另一个人的概括(有点简单):

AMD就只有一个接口:define(id?,dependencies?,factory);

 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:

1 define([&#39;dep1&#39;,&#39;dep2&#39;],function(dep1,dep2){...});

 要是没什么依赖,就定义简单的模块,下面这样就可以啦:

<span style="font-family:&#39;幼圆&#39;;font-size:16px;">1 define(function(){<br/>2     var exports = {};<br/>3     exports.method = function(){...};<br/>4     return exports;<br/>5 });</span>

 咦,这里有define,把东西包装起来啦,那Node实现中怎么没看到有define关键字呢,它也要把东西包装起来呀,其实吧,只是Node隐式包装了而已.....

这有AMD的WIKI中文版,讲了很多蛮详细的东西,用到的时候可以查看:AMD的WIKI中文版

三、CMD

大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:seajs官方doc

1 define(function(require,exports,module){...});

用过seajs吧,这个不陌生吧,对吧。

前面说AMD,说RequireJS实现了AMD,CMD看起来与AMD好像呀,那RequireJS与SeaJS像不像呢?

虽然CMD与AMD蛮像的,但区别还是挺明显的,官方非官方都有阐述和理解,我觉得吧,说的都挺好:

官方阐述SeaJS与RequireJS异同

SeaJS与RequireJS的最大异同(这个说的也挺好)

相关推荐:

理解前端模块化(CommonJs,AMD和CMD)

JavaScript模块规范之AMD规范和CMD规范

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