Maison > Article > interface Web > Explication détaillée du développement modulaire JavaScript
Dans le développement front-end, au début, il suffit d'intégrer des dizaines ou des centaines de lignes de code dans des balises de script pour obtenir certains effets interactifs de base. Plus tard, js a attiré l'attention et est devenu largement utilisé, y compris jQuery, Ajax et Node.Js. , MVC, MVVM, etc. ont également attiré l'attention sur le développement front-end et rendu les projets front-end de plus en plus complexes. Cependant, JavaScript ne fournit aucune aide évidente pour organiser le code, et il existe. pas même le concept de classes, encore moins de modules, alors qu'est-ce qu'un module ?
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 des modules doit suivre certaines normes, sinon tout sera gâché.
Selon les spécifications AMD, nous pouvons utiliser Defin pour définir des modules et exiger l'appel de modules.
Actuellement, il existe deux principaux types de spécifications de module js : CommonJS et AMD.
AMD est une définition de module asynchrone, et le nom chinois signifie « définition de module asynchrone ». Il s'agit d'une spécification pour le développement modulaire côté navigateur. La spécification côté serveur est que les modules CommonJS
seront chargés de manière asynchrone et que le chargement des modules n'affectera pas l'exécution des instructions suivantes. Toutes les instructions qui dépendent de certains modules sont placées dans des fonctions de rappel.
AMD est la sortie standardisée des définitions de modules pendant le processus de promotion de RequireJS.
La spécification AMD ne définit qu'une seule fonction de définition, qui est une variable globale. La description de la fonction est :
define(id?, dependencies?, factory);
Description du paramètre :
id:指定义中模块的名字,可选;如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。 依赖dependencies:是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。 依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。 工厂方法factory,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
Le nom du module est utilisés pour identifier de manière unique les modules de définition, ils sont également utilisés dans le tableau de dépendances :
模块名是用正斜杠分割的有意义单词的字符串 单词须为驼峰形式,或者".",".." 模块名不允许文件扩展名的形式,如“.js” 模块名可以为 "相对的" 或 "顶级的"。如果首字符为“.”或“..”则为相对的模块名 顶级的模块名从根命名空间的概念模块解析 相对的模块名从 "require" 书写和调用的模块解析
Créer un module nommé "alpha" en utilisant require, exports et un module nommé module « bêta » :
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
nécessite une introduction à l'API : http://www.php.cn/
Spécification AMD version chinoise : http://www.php.cn /(Version chinoise)
Actuellement, les bibliothèques qui implémentent AMD incluent RequireJS, curl, Dojo, Nodules, etc.
CommonJS est une spécification pour les modules côté serveur, et Node.js adopte cette spécification. Node.JS a d'abord adopté le concept de modularité js.
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.
var i = 1; var max = 30; module.exports = function () { for (i -= 1; i++ < max; ) { console.log(i); } max *= 1.1; };
Le code ci-dessus définit une fonction via l'objet module.exports, qui est le pont entre la communication externe et interne du module.
Le chargement des modules utilise la méthode require, qui lit un fichier et l'exécute, et renvoie enfin l'objet module.exports à l'intérieur du fichier.
Spécification CommonJS : http://www.php.cn/
RequireJS a été créée par James Burke, qui est également le fondateur de la spécification AMD . La méthode
define est utilisée pour définir les modules. RequireJS nécessite que chaque module soit placé dans un fichier séparé.
RequireJS et Sea.js sont tous deux des chargeurs de modules, prônant le concept de développement modulaire, et leur valeur fondamentale est de rendre le développement modulaire de JavaScript simple et naturel.
La plus grande différence entre SeaJS et RequireJS :
L'attitude de SeaJS envers les modules est une exécution paresseuse, tandis que l'attitude de RequireJS envers les modules est la pré-exécution
Vous ne comprenez pas ? Jetez un oeil à cet article avec des images et des textes : http://www.php.cn/
API RequireJS : http://www.php.cn/
Utilisation de RequireJS : http :/ /www.php.cn/
Imaginez simplement, si une page Web contient beaucoup de fichiers js, le navigateur chargera d'abord les fichiers js lors du téléchargement du page. Cela arrête le rendu de la page Web. S'il y a plus de fichiers, le navigateur peut ne plus répondre. Deuxièmement, il est nécessaire de garantir la dépendance des fichiers js. Le module (fichier) avec la plus grande dépendance doit être chargé en dernier. Lorsque les dépendances sont complexes, il deviendra difficile d'écrire et de maintenir le code.
RequireJS est né pour résoudre ces deux problèmes :
(1)实现js文件的异步加载,避免网页失去响应; (2)管理模块之间的依赖性,便于代码的编写和维护。
Téléchargement du fichier RequireJS : http://www.php.cn/
Définition du module commun CMD (Common Module Definition). Cette spécification clarifie le format d'écriture de base et les règles d'interaction de base du module. La norme a été élaborée au niveau national. AMD est une dépendance frontale et CMD est chargé à la demande.
Dans la spécification CMD, un module est un fichier. Le format d'écriture du code est le suivant :
define(factory);
Quand factory est une fonction, cela signifie que c'est la méthode de construction du module. L'exécution de cette méthode de construction permet d'obtenir l'interface fournie par le module. Lorsque la méthode factory est exécutée, trois paramètres seront transmis par défaut : require, exports et module :
define(function(require, exports, module) { // 模块代码 });
require est un paramètre qui peut importer d'autres modules, et export peut importer certains des modules. Les propriétés et les méthodes sont exportées.
Adresse de spécification CMD : http://www.php.cn/
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
Pour les modules dépendants, AMD est exécuté à l'avance et CMD est exécuté en retard.
AMD:提前执行(异步加载:依赖先执行)+延迟执行 CMD:延迟执行(运行到需加载,根据顺序执行)
CMD favorise les dépendances à proximité, tandis qu'AMD favorise les dépendances à l'avant. Regardez le code suivant :
// 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() ... })
另外一个区别是:
AMD:API根据使用范围有区别,但使用同一个api接口 CMD:每个API的职责单一
AMD的优点是:异步并行加载,在AMD的规范下,同时异步加载是不会产生错误的。
CMD的机制则不同,这种加载方式会产生错误,如果能规范化模块内容形式,也可以
jquery1.7以上版本会自动模块化,支持AMD模式:主要是使用define函数,sea.js虽然是CommonJS规范,但却使用了define来定义模块
所以jQuery已经自动模块化了
seajs.config({ 'base':'/', 'alias':{ 'jquery':'jquery.js'//定义jQuery文件 } });
define函数和AMD的define类似:
define(function(require, exports, module{ //先要载入jQuery的模块 var $ = require('jquery'); //然后将jQuery对象传给插件模块 require('./cookie')($); //开始使用 $.cookie方法 });
引入sea.js的库
如何变成模块?
define
3.如何调用模块?
-exports -sea.js.use
4.如何依赖模块?
-require <script type="text/javascript"> define(function (require,exports,module) { //exports : 对外的接口 //requires : 依赖的接口 require('./test.js');//如果地址是一个模块的话,那么require的返回值就是模块中的exports })
2cacc6d41bbb37262a98f745aa00fbf0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>鼠标拖拽的模块化开发实践</title> <style type="text/css"> #p1{ width:200px; height:200px; background:black; position:absolute; display:none;} #p2{ width:30px; height:30px; background:yellow; position:absolute; bottom:0; right:0;} #p3{ width:100px; height:100px; background:blue; position:absolute; right:0; top:0;} </style> <script type="text/javascript" src="./sea.js"></script> <script type="text/javascript"> //A同事 : seajs.use('./main.js'); </script> </head> <body> <input type="button" value="确定" id="input1" /> <p id="p1"> <p id="p2"></p> </p> <p id="p3"></p> </body> </html>
//A同事写的main.js: define(function (require,exports,module) { var oInput = document.getElementById('input1'); var op1 = document.getElementById('p1'); var op2 = document.getElementById('p2'); var op3 = document.getElementById('p3'); require('./drag.js').drag(op3); oInput.onclick = function () { op1.style.display = 'block'; require('./scale.js').scale(op1,op2); require.async('./scale.js', function (ex) { ex.scale(op1,op2); }) } });
//B同事写的drag.js: define(function(require,exports,module){ function drag(obj){ var disX = 0; var disY = 0; obj.onmousedown = function(ev){ var ev = ev || window.event; disX = ev.clientX - obj.offsetLeft; disY = ev.clientY - obj.offsetTop; document.onmousemove = function(ev){ var ev = ev || window.event; var L = require('./range.js').range(ev.clientX - disX , document.documentElement.clientWidth - obj.offsetWidth , 0 ); var T = require('./range.js').range(ev.clientY - disY , document.documentElement.clientHeight - obj.offsetHeight , 0 ); obj.style.left = L + 'px'; obj.style.top = T + 'px'; }; document.onmouseup = function(){ document.onmousemove = null; document.onmouseup = null; }; return false; }; } exports.drag = drag;//对外提供接口 });
//C同事写的scale.js: define(function(require,exports,module){ function scale(obj1,obj2){ var disX = 0; var disY = 0; var disW = 0; var disH = 0; obj2.onmousedown = function(ev){ var ev = ev || window.event; disX = ev.clientX; disY = ev.clientY; disW = obj1.offsetWidth; disH = obj1.offsetHeight; document.onmousemove = function(ev){ var ev = ev || window.event; var W = require('./range.js').range(ev.clientX - disX + disW , 500 , 100); var H = require('./range.js').range(ev.clientY - disY + disH , 500 , 100); obj1.style.width = W + 'px'; obj1.style.height = H + 'px'; }; document.onmouseup = function(){ document.onmousemove = null; document.onmouseup = null; }; return false; }; } exports.scale = scale; });
// D同事的range.js--限定拖拽范围 define(function(require,exports,module){ function range(iNum,iMax,iMin){ if( iNum > iMax ){ return iMax; } else if( iNum < iMin ){ return iMin; } else{ return iNum; } } exports.range = range; });
require.config是用来定义别名的,在paths属性下配置别名。然后通过requirejs(参数一,参数二);参数一是数组,传入我们需要引用的模块名,第二个参数是个回调函数,回调函数传入一个变量,代替刚才所引入的模块。
//别名配置 requirejs.config({ paths: { jquery: 'jquery.min' //可以省略.js } }); //引入模块,用变量$表示jquery模块 requirejs(['jquery'], function ($) { $('body').css('background-color','red'); });
引入模块也可以只写require()。requirejs通过define()定义模块,定义的参数上同。在此模块内的方法和变量外部是无法访问的,只有通过return返回才行.
define(['jquery'], function ($) {//引入jQuery模块 return { add: function(x,y){ return x + y; } }; });
将该模块命名为math.js保存。
require(['jquery','math'], function ($,math) { console.log(math.add(10,100));//110 });
如果定义的模块不依赖其他模块,则可以:
define(function () { return { name: "trigkit4", age: "21" } });
AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。
以上就是详解JavaScript模块化开发的内容,更多相关内容请关注PHP中文网(www.php.cn)!