Комплекс представляет собой модульное приложение, в соответствии со спецификацией на несколько отдельных файлов, те файлы или аналогичные, которые завершают общую логику, путем внешнего вызова метода экспозиции или части данных и внешней интеграции.
Основные функции модуля:可复用性
,可组合性
,独立性
,中心化
Так какие проблемы могут использовать модульность, помогите нам решить?
- Устранены конфликты имен: Поскольку каждый модуль независим, имя переменной или функции не будет конфликтовать с тем же именем.
- Улучшить ремонтопригодность: Поскольку у каждого файла есть одна функция, это способствует сопровождению кода.
- оптимизация производительности: асинхронная загрузка модулей может быть очень полезна для производительности страницы.
- Управление версиями модуля: Управление версией модуля может быть достигнуто благодаря конфигурации, такими как псевдонимы и с помощью инструментов сборки
- Совместное использование модулей в разных средах: Благодаря версии Sea.js для NodeJS модули могут совместно использоваться серверами и браузерами.
В настоящее время основными стандартами модульности интерфейса являются:
- CommonJS
- AMD
- CMD
- UMD
- ES6
Ниже приводится подробное резюме
CommonJS
Node использует модульную спецификацию CommonJS.
Спецификация такая, каждый файл представляет собой модуль с отдельными скоупами, переменными и методами и т.д., и невидим для других файлов, что также является проявлением независимости
Внутри каждого модуля есть объект модуля, представляющий текущий модуль, через который можно экспортировать текущий модуль в API, модуль имеет несколько атрибутов:
-
exports
: внешний интерфейс, загрузка модуля для загрузки модуляmodule.exportsАтрибуты loaded
-
parent
: Возвращает объект, представляющий модуль, вызывает модуль -
children
: возвращает массив, указывающий, что модуль используется в коллекции других модулей. -
filename
: имя файла модуля с абсолютным путем -
id
: идентификатор модуля, обычно имя файла модуля с абсолютным путем.
Особенности спецификации CommonJS:
- Каждый файлНезависимостьМодуль имеет независимую область видимости и не будет загрязнять глобальное пространство.
- На файлы можно ссылаться и загружать повторно.будет кэшироваться при первой загрузке, а затем обратитесь к нему и прочитайте кеш напрямую
- При загрузке модуляmodule.exports выводит копию значения, как только это значение будет выведено, изменения в модуле не повлияют на выведенное значение.
Использование такое:
экспорт
module.exports.foo = function(){ ... } // 只能输出一个
或 可以输出多个
exports.a = 1
exports.foo = function(){ ... }
Просто используйте module.exports.
импорт
const foo = require("./xxx") // 如果没有写文件名后缀,会自动按照 .js、.json、.node的顺序补齐查找
Процесс загрузки выглядит следующим образом:
- Если кеша нет, проверьте, является ли он глобальным модулем, или загрузите его напрямую
- Если нет, проверьте, есть ли файл в пути к модулю, проанализируйте путь и найдите файл, а затем выполните загрузку.
- Если ничего из перечисленного выше, рекурсивно ищите текущий путь до корневого каталога node_modules.
AMD
Он модульный, как CommonJS, за исключениемМодули канонической загрузки CommonJS являются синхронной загрузкой, следующие операции можно выполнять только после завершения загрузки, аAMD — модуль асинхронной загрузки, вы можете указать функцию обратного вызова
Поскольку Node.js работает на сервере, все файлы обычно хранятся на локальном жестком диске, и нет необходимости запрашивать асинхронную загрузку. Однако, если он размещен в среде браузера, необходимо запросить получение файла модуля с сервера, в настоящее время использовать синхронную загрузку явно нецелесообразно, поэтому существует спецификация ADM, которая полностью подходит для браузера.Реализация этой спецификации require.js
Его использование через глобальную функциюdefine
, определите код как модуль, а затем используйтеrequire
метод загрузки модуля
define
получить три параметра
- Первый — имя модуля, которое также можно оставить пустым, по умолчанию — имя файла.
- Второй параметр должен быть массивом, определяющим список модулей, от которых зависит этот модуль.
- Третий параметр — это функция или объектный модуль, который нужно инициализировать. Если функция выполняется только один раз, если объект является то, что объект должен использоваться в качестве выходного значения модуля
define("myModule", ["require", "exports", "beta"], function(require, exports, beta){
exports.foo = function(){
return beat.foo()
}
})
экспорт
module.exports = { ... }
импорт
const foo = require("./xxx")
CMD
Спецификация CMD объединяет функции спецификации CommonJS и упомянутой выше спецификации AMD.Реализация спецификации CMD sea.js
Самая большая особенность спецификации CMD заключается в том, что懒加载
, вам не нужно объявлять зависимости при определении модуля, вы можете динамически загружать зависимости при выполнении модуля,并且同时支持同步和异步
загрузочный модуль
Основное различие между CMD и AMD заключается в следующем.:
- AMD необходимо загружать модули асинхронно, в то время как CMD может загружать синхронно (
require
), также может быть загружен асинхронно (require.sync
) - CMD следует принципу близости к зависимостям, а AMD следует принципу предзависимости. То есть в AMD нам нужно заранее объявить все зависимости, требуемые модулем, в массиве зависимостей, тогда как в CMD нам нужно только потребовать, чтобы модули использовались в конкретной логике кода.
Использование похоже на require.js.Он реализуется путем определения глобальной функции, но может принимать только один параметр, который может быть функцией или объектом. Если это объект, модуль экспортирует объект, если это функция, то функции будут переданы три параметра.
define( function(require, exports, module){
...
})
Три параметра:
-
require
: вы можете ссылаться на другие модули или использовать require.async для асинхронного вызова других модулей. -
expxort
: это объект. При определении модуля вам необходимо добавить атрибуты через экспорт параметра для экспорта API -
module
: это объект, который имеет три верхних свойства- uri: полный путь URI модуля.
- dependencies: зависимости модуля
- exports: API, который модуль должен экспортировать.
посмотреть на каштаны
define( function(require, export, module){
const add = require("math").add
exports.increment = function(val){
return add(val, 1)
}
module.id = "increment"
})
Является ли определение модуля, называемого приращением, со ссылкой на математический модуль в методе добавления, после обработки функция реэкспорта приращения
UMD
UMD не имеет специальной спецификации, а объединяет три указанные выше спецификации в одну, что позволяет выбрать подходящую спецификацию модуля в соответствующей среде.
Например, в среде Node.js для управления используется спецификация модуля CommonJS.Если AMD поддерживается на стороне браузера, используется спецификация модуля AMD.Если не поддерживается, то экспортируется как глобальная функция.
см. код реализации
(function(root, factory){
if(typeof define === "function" && define.amd){
define(["xxx"], factory)
}else if(typeof exports === "object"){
module.exports = factory( require("xxx") )
}else{
root.returnExports = factory( root.xxx )
}
}(this, ($) => {
return { ... }
}))
Судебный процесс таков
- Сначала определите, поддерживает ли поддержка AMD (существует ли определение), и используйте метод AMD для загрузки модуля, если он существует.
- Затем определите, поддерживает ли служба поддержки формат модуля Node.js (существует ли экспорт) и используйте формат модуля Node.js, если он существует.
- Если ни один из первых двух не существует, выставьте модуль в глобальный, оконный или глобальный
Модульный ES6
И CommonJS, и AMD определяют зависимости во время выполнения, то есть загружают во время выполнения. CommonJS загружает копии, тогда как модули ES6 определяют зависимости во время компиляции. Все загрузки являются ссылками. Преимущество этого в том, что его можно выполнить. Статический анализ и проверка типов
Разница между модулем ES6 и CommonJS:
-
ES6 Module
импорт является статическим импортом, CommonJS требует динамического импорта -
Tree-Shaking
Это статический анализ посредством импорта модуля ES6, который поддерживает толькоES6 Module
использование модулей. Tree-Shaking предназначен для удаления кода, на который нет ссылок в контексте JS.Например, если модуль импорта импорта не имеет возвращаемого значения, Tree-Shaking будет игнорировать этот файл по умолчанию при упаковке и компиляции веб-пакета. -
ES6 Module
Это ссылка на модуль, вывод — это ссылка на значение, и значение ссылки на значение в исходном модуле также изменится;CommonJS
Является копией модуля, изменение значения исходного модуля не повлияет на значение ссылки -
ES6 Module
где this указывает на undefined;CommonJS
где это относится к самому модулю -
ES6 Module
Он определяет зависимости во время компиляции, генерирует интерфейсы и выводит их наружу; CommonJS загружает модули во время выполнения. -
ES6 Module
Метод можно загрузить отдельно;CommonJS
загрузить весь модуль -
ES6 Module
Невозможно переназначить, будет сообщено об ошибке;CommonJS
Что такое статический анализ? Что такое статический импорт? Что такое динамический импорт?
// CommonJS / AMD 中动态引入的写法
const foo = require( `all/${["f","o","o"].join("")}` )
const foo = require( "all/FOO".toLowerCase() )
const foo = require( (()=>"foo")() )
const foo = xx.get( require("foo") )
// ES6 Module 中静态引入的写法
import foo from "xxxx/xxx"
import { foo1, foo2 } from "xxxx/xxx"
Вывод: динамическое == можно сращивать, статическое == нельзя сплайсировать, хахаха ~~~ , не === Ха, просто поймите это, принцип не будет расширяться
Не может быть объединен, модуль ES6 может легко анализировать, какие модули используются Это статический анализ, который может сканировать и обнаруживать код без запуска кода.
Использование модуля ES6, посмотрите на код
экспорт
// 方式一 可以输出多个
export const a = 1
export function foo(){}
//方式二 只能输出一个
const a = 1
function foo(){}
export default {
a,
foo
}
// 注意
export { a as b } // as 的意思就是重命名
Существует также экспорт по умолчанию, который будет экспортировать вывод по умолчанию.Те, кто использует vue, должны быть хорошо знакомы с ним, но вам не нужно знать имя вывода в модуле.Вы можете настроить имя при импорте.
// 导出
export default function(){ ... }
// 引入
import "./xxx" 这样只是加载,没有输出,也就不能调用
// 下面这样就可以使用
import funName1 from "./xxx"
import { funName1 as foo } from "./xxx"
import { funName1, funName2 } from "./xxx"
// 加载整个模块 会忽略 default 输出
import * as myModule from "./xxx"
// 使用
myModule.a
myModule.foo()
// 模块的继承
import * from "./xxx" // 在当前模块里这样引入别的模块,就把 xxx 模块里导出的全部继承过来了
Использование модульности ES в браузере
Просто добавьте в тег scripttype="module"
С атрибутами все в порядке. В настоящее время поддерживаются более новые версии основных браузеров. Если это неподдерживаемый браузер, добавьтеnomodule
свойства для выполнения других сценариев
<script type="module">
import module1 from "./xxx"
</script>
<script nomodule>
alert("您的浏览器暂不支持 ES 模块,请先升级浏览器版本")
</script>
Использование модульности ES в Node.js
Node.js поддерживает модули ES, начиная с версии 9.0.
Его можно добавить, когда нужно запустить скрипт выполнения.--experimental-modules, расширение файла должно быть .mjs
node --experimental-modules module1.mjs
//使用
import module1 from "./xxx"
Или вы также можете установитьbabel-cliа такжеbabel-preset-env, после настройки файла .babelrc выполните
./node_modules/.bin/babel-node
или
npx babel-node
разное
Сам Webpack поддерживает модульную систему, которая совместима почти со всеми спецификациями модулей в истории интерфейса.Все модули, упомянутые выше, доступны.
Эпилог
Ставь лайк и поддержи, оставь аромат в руке и будь почетным
Спасибо за то, что вы здесь!