Модульный метод разработки может улучшить скорость повторного использования кода и облегчить управление кодом. Обычно файл представляет собой модуль, который имеет свой собственный охват, и только подвергает определенные переменные и функции. В настоящее время популярные спецификации Modularization JS включают в себя Commandjs, AMD, CMD и Module Module. Смотрите статью Руан Yifengmodule-loader.
1. ОбщийJS
Node.js является основным практиком спецификации commonJS и имеет четыре важные переменные среды для поддержки модульной реализации:module
,exports
,require
,global
. Фактическое использование, сmodule.exports
Определите внешний выходной интерфейс текущего модуля (не рекомендуется использовать его напрямуюexports
),использоватьrequire
Загрузите модуль.
// 定义模块math.js
var basicNum = 0;
function add(a, b) {
return a + b;
}
module.exports = { //在这里写上需要向外暴露的函数、变量
add: add,
basicNum: basicNum
}
// 引用自定义的模块时,参数包含路径,可省略.js
var math = require('./math');
math.add(2, 5);
// 引用核心模块时,不需要带路径
var http = require('http');
http.createService(...).listen(3000);
commonJS загружает модули синхронно. На стороне сервера файлы модулей хранятся на локальном диске и читаются очень быстро, так что проблем с этим не будет. Но со стороны браузера, ограниченного сетевыми причинами, более разумным решением является использование асинхронной загрузки.
2. AMD и require.js
Спецификация AMD использует асинхронный метод для загрузки модулей, и загрузка модулей не влияет на работу следующих за ней операторов. Все операторы, которые зависят от этого модуля, определяются в функции обратного вызова, которая не будет выполняться до тех пор, пока загрузка не будет завершена. Вот введение в использование require.js для реализации модуляризации спецификации AMD:require.config()
Укажите ссылочный путь и т. д. с помощьюdefine()
определить модуль сrequire()
Загрузите модуль.
Сначала нам нужно ввести файл require.js и файл входа main.js. Конфигурация в main.jsrequire.config()
И указать основные модули, используемые в проекте.
/** 网页中引入require.js及main.js **/
<script src="js/require.js" data-main="js/main"></script>
/** main.js 入口文件/主模块 **/
// 首先用config()指定各模块路径和引用名
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min", //实际路径为js/lib/jquery.min.js
"underscore": "underscore.min",
}
});
// 执行基本操作
require(["jquery","underscore"],function($,_){
// some code here
});
При ссылке на модуль мы помещаем имя модуля в[]
в качествеreqiure()
Первый параметр; если мы определяем сам модуль полагаться на другие модули, то вам нужно поставить их в[]
в качествеdefine()
первый параметр .
// 定义math.js模块
define(function () {
var basicNum = 0;
var add = function (x, y) {
return x + y;
};
return {
add: add,
basicNum :basicNum
};
});
// 定义一个依赖underscore.js的模块
define(['underscore'],function(_){
var classify = function(list){
_.countBy(list,function(num){
return num > 30 ? 'old' : 'young';
})
};
return {
classify :classify
};
})
// 引用模块,将模块放在[]内
require(['jquery', 'math'],function($, math){
var sum = math.add(10,20);
$("#sum").html(sum);
});
3. CMD и sea.js
require.js загрузит и выполнит код в модуле между первым при объявлении зависимого модуля:
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
// 等于在最前面声明并初始化了要用到的所有模块
if (false) {
// 即便没用到某个模块 b,但 b 还是提前执行了
b.foo()
}
});
CMD — еще одно решение для модуляризации js, очень похожее на AMD, разница в том, что AMD выступает за предварительное доверие и раннее выполнение, а CMD — за близость и отложенное выполнение. Эта спецификация фактически создается во время продвижения sea.js.
/** AMD写法 **/
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
// 等于在最前面声明并初始化了要用到的所有模块
a.doSomething();
if (false) {
// 即便没用到某个模块 b,但 b 还是提前执行了
b.doSomething()
}
});
/** CMD写法 **/
define(function(require, exports, module) {
var a = require('./a'); //在需要时申明
a.doSomething();
if (false) {
var b = require('./b');
b.doSomething();
}
});
/** sea.js **/
// 定义模块 math.js
define(function(require, exports, module) {
var $ = require('jquery.js');
var add = function(a,b){
return a+b;
}
exports.add = add;
});
// 加载模块
seajs.use(['math.js'], function(math){
var sum = math.add(1+2);
});
4. Модуль ES6
На уровне языковых стандартов ES6 реализует модульную функцию, и реализация достаточно проста, чтобы стать общим модульным решением для браузеров и серверов. Его функция модуля в основном состоит из двух команд:export
а такжеimport
.export
Команда используется для указания внешнего интерфейса модуля,import
Команды используются для ввода функций, предоставляемых другими модулями.
/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
return a + b;
};
export { basicNum, add };
/** 引用模块 **/
import { basicNum, add } from './math';
function test(ele) {
ele.textContent = add(99 + basicNum);
}
Как и в примере выше, используйтеimport
При выполнении команды пользователю необходимо знать имя загружаемой переменной или функции. Фактически, ES6 также обеспечиваетexport default
команда, которая указывает вывод по умолчанию для модуля, соответствующийimport
В операторе не нужно использовать фигурные скобки. Это также ближе к ссылке на ADM.
/** export default **/
//定义输出
export default { basicNum, add };
//引入
import math from './math';
function test(ele) {
ele.textContent = math.add(99 + math.basicNum);
}
Модули ES6 не являются объектами,import
Команда будет статически проанализирована движком JavaScript, и код модуля будет введен во время компиляции, а не загружаться во время выполнения кода, поэтому условная загрузка не может быть достигнута. Именно благодаря этому возможен статический анализ.
5. Различия между модулями ES6 и модулями CommonJS
1. Модуль CommonJS выводит копию значения, а модуль ES6 выводит ссылку на значение.
- Модули CommonJS выводят копию значения, то есть после вывода значения изменения внутри модуля не повлияют на значение.
- Модули ES6 работают иначе, чем CommonJS. Когда движок JS статически анализирует скрипт, он встречает команду загрузки модуля
import
, создается ссылка только для чтения. Когда скрипт действительно выполняется, в соответствии с этой ссылкой только для чтения перейдите к загруженному модулю, чтобы получить значение. Другими словами, ES6import
Вроде как "символическая ссылка" Unix-систем, исходное значение изменилось,import
Загруженное значение также изменится соответствующим образом. Таким образом, на модули ES6 ссылаются динамически и они не кэшируют значения, а переменные в модулях привязаны к модулю, в котором они находятся.
2. Модуль CommonJS загружается во время выполнения, а модуль ES6 является выходным интерфейсом во время компиляции.
-
Загрузка во время выполнения: модули CommonJS являются объектами, то есть при вводе сначала загружается весь модуль, генерируется объект, а затем из этого объекта считываются методы, такая загрузка называется «загрузка во время выполнения».
-
Загрузка во время компиляции: модули ES6 не являются объектами, а передаются через
export
Команда явно указывает код для вывода,import
в виде статической команды. то естьimport
Вместо того, чтобы загружать весь модуль, вы можете указать загружать выходное значение, эта загрузка называется «загрузкой во время компиляции».
Загрузка CommonJS объекта (т.е.module.exports
свойство), объект не будет создан, пока скрипт не завершит работу. Модуль ES6 не является объектом, его внешний интерфейс — это просто статическое определение, которое будет сгенерировано на этапе статического анализа кода.
(Статья предназначена исключительно для личных целей записи заметок, и некоторые цитаты взяты из Интернета плюс личное понимание. Добро пожаловать в перепечатку, пожалуйста, укажите источник. Если это полезно для вас, пожалуйста, не стесняйтесь вознаграждать.)