Maison  >  Article  >  interface Web  >  Compréhension approfondie de la modularisation de JavaScript

Compréhension approfondie de la modularisation de JavaScript

黄舟
黄舟original
2017-03-24 14:56:281378parcourir

La

La modularisation est très importante dans un projet. Un projet complexe doit avoir de nombreux modules fonctionnels similaires. Si vous devez réécrire les modules à chaque fois, cela prendra certainement du temps et du travail. Cependant, la condition préalable pour citer d'autres personnes pour écrire des modules est d'avoir une « posture d'ouverture » unifiée. Si chacun a sa propre façon d'écrire, ce sera certainement chaotique.

La modularisation est très importante dans un projet. Un projet complexe doit avoir de nombreux modules fonctionnels similaires. Si vous devez réécrire les modules à chaque fois, cela prendra certainement du temps et du travail. Cependant, la condition préalable pour citer d'autres personnes pour écrire des modules est d'avoir une « posture d'ouverture » unifiée. Si chacun a sa propre façon d'écrire, ce sera certainement chaotique.

1 : Premier processus de modularisation : balise de script

C'est la méthode de chargement de fichier JavaScript la plus originale si chaque fichier est considéré comme un. module, alors leurs interfaces sont généralement exposées dans la portée globale, c'est-à-dire définies dans la fenêtre objet Les appels d'interface des différents modules sont tous dans la même portée. Certains frameworks complexes utiliseront le concept de <.>namespace est utilisé pour organiser les interfaces de ces modules.

Inconvénients :

1 Polluer la portée mondiale

2. Dépendances des bibliothèques

3. Les fichiers ne peuvent être chargés que dans l'ordre dans lequel les balises de script sont écrites

4. Diverses ressources sont difficiles à gérer dans les grands projets et des problèmes accumulés à long terme entraînent des problèmes. une base de code chaotique

Deux : Processus de modularisation deux : spécification CommonJS

L'idée principale de cette spécification est de permettre aux modules de charger de manière synchrone d'autres modules dont ils dépendent via la méthode

require, puis exportez les interfaces qui doivent être exposées via exports ou module.exports.

require("module");
require("../file.js");
exports.doStuff = function(){};
module.exports = someValue;

Avantages :

1. Simples et faciles à utiliser

2. à réutiliser

Inconvénients :

1. La méthode de chargement synchrone du module n'est pas adaptée à l'environnement du navigateur. les ressources sont asynchrones. Chargé

2. Plusieurs modules ne peuvent pas être chargés en parallèle de manière non bloquante

La différence entre module.exports et exports

1. exports est une référence à module.exports

2. La valeur initiale de module.exports est un objet vide {}, donc la valeur initiale de exports est également {}

3. require() renvoie C'est module.exports au lieu d'exports

Exemple d'exportation :

// app.js
var circle = require(&#39;./circle&#39;);
console.log(circle.area(4));
// circle.js
exports.area = function(r){
 return r * r * Math.PI;
}
exemple de module.exports :

// app.js
var area = require(&#39;./area&#39;);
console.log(area(4));
// area.js
module.exports = function(r){
 return r * r * Math.PI;
}
Cas d'erreur :

// app.js
var area = require(&#39;./area&#39;);
console.log(area(4));
// area.js
exports = function(r){
 return r * r * Math.PI;
}
écrase en fait les exports, ce qui signifie que les exports pointe vers une nouvelle mémoire (le contenu est une

fonction qui calcule l'aire d'un cercle), ce qui signifie que exports et module.exports ne pointent plus vers le même morceau de mémoire, ce qui signifie que exports et module.exports n'ont aucune connexion pour le moment. Cela signifie que la mémoire pointée par module.exports n'a pas été modifiée. de toute façon. C'est toujours un objet vide {}, ce qui signifie que Area.js est exporté. Un objet vide, donc lorsque nous appelons Area(4) dans app.js, un TypeError: object n'est pas. une erreur de fonction sera signalée.

Résumé : Lorsque nous voulons que le module exporte un objet, les deux exportations et module.exports peuvent être utilisés (mais les exportations ne peuvent pas être écrasées comme une nouvelle) objet), et lorsque nous voulons exporter une interface non-objet, nous devons et pouvons uniquement remplacer module.exports.

Trois : Processus de modularisation trois : Spécification AMD

Étant donné que les modules côté navigateur ne peuvent pas être chargés de manière synchrone, cela affectera le chargement et l'exécution des modules suivants, donc AMD ( La spécification Asyn

chronous Module Definition (Asynchronous Module Definition) était née.

Les deux API suivantes sont définies dans la norme AMD

1 require([module], callback);

2. 🎜 >
L'interface require est utilisée pour charger une série de modules, et l'interface de définition est utilisée pour définir et exposer un module.

Exemple :

define("module", ["dep1", "dep2"], function(d1, d2){
 return someExportedValue;
});
require(["module", "../file"], function(module, file){ /* ... */ });

Avantages : Adapté au chargement asynchrone de modules dans un environnement de navigateur

2. Plusieurs modules peuvent être chargés en parallèle

Inconvénients : Augmentation des coûts de développement, de lecture et d'écriture de code. C'est plus difficile et la sémantique de la méthode de définition du module n'est pas fluide

2. Elle n'est pas conforme à la façon de penser modulaire générale et constitue une implémentation compromise

Quatre : Processus de modularisation quatre : spécification CMD

CMD(Common Module Definition)规范和AMD很相似,尽量保持简单,并与CommonJS和Node.js的 Modules 规范保持了很大的兼容性。在CMD规范中,一个模块就是一个文件。

示例:

define(function(require, exports, module){
 var $ = require(&#39;jquery&#39;);
 var Spinning = require(&#39;./spinning&#39;);
 exports.doSomething = ...
 module.exports = ...
})

优点:

1、依赖就近,延迟执行

2、可以很容易在 Node.js 中运行

缺点:

1、依赖 SPM 打包,模块的加载逻辑偏重

AMD和CMD的区别

AMD和CMD起来很相似,但是还是有一些细微的差别,让我们来看一下他们的区别在哪里:

1、对于依赖的模块,AMD是提前执行,CMD是延迟执行。

2、AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。看代码:

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

3、AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。

五:模块化进程五:ES6模块化

EcmaScript6标准增加了JavaScript语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时确定这些东西。

在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。需要说明的是,ES6的这套标准和目前的标准没有直接关系,目前也很少有JS引擎能直接支持。因此Babel的做法实际上是将不被支持的import翻译成目前已被支持的require。

尽管目前使用import和require的区别不大(本质上是一回事),但依然强烈推荐使用import关键字,因为一旦JS引擎能够解析ES6的import关键字,整个实现方式就会和目前发生比较大的变化。如果目前就开始使用import关键字,将来代码的改动会非常小。

示例:

import "jquery";
export functiondoStuff(){}
module "localModule" {}

优点:

1、容易进行静态分析

2、面向未来的 EcmaScript 标准

缺点:

1、原生浏览器端还没有实现该标准

2、全新的命令字,新版的 Node.js才支持

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