На этот раз я хочу понять модульность javascript.

Node.js внешний интерфейс JavaScript jQuery

С увеличением сложности внешнего кода js модульность js является неизбежной тенденцией.Он не только прост в обслуживании, но также имеет четкие зависимости и не загрязнит весь мир.Давайте сегодня разберемся с некоторыми спецификациями модульности ~

Во-первых, давайте разберемся с развитием модуляризации~

Нет модульности --> Спецификации CommonJS --> Спецификации AMD --> Спецификации CMD --> Модульность ES6

1. Нет модульности

Тег script представляет файл js и перечисляет друг друга, но зависимые размещаются впереди, иначе будет сообщено об ошибке. следующим образом:

   <script src="jquery.js"></script>
  <script src="jquery_scroller.js"></script>
  <script src="main.js"></script>
  <script src="other1.js"></script>
  <script src="other2.js"></script>
  <script src="other3.js"></script>

То есть просто собрать все файлы js вместе. Однако порядок этих файлов не может быть неправильным, например, jquery необходимо импортировать до того, как можно будет ввести подключаемый модуль jquery, а затем jquery можно будет использовать в других файлах. Недостатки очевидны:

  • загрязнять глобальную область
  • Высокая стоимость обслуживания
  • Зависимости не очевидны

2. Спецификация CommonJS

Эта спецификация изначально использовалась для узла на стороне сервера и имеет четыре важные переменные среды для обеспечения поддержки модульной реализации:module,exports,require,global. В реальном использовании использоватьmodule.exportsОпределите внешний выходной интерфейс текущего модуля (не рекомендуется использовать его напрямуюexports),использоватьrequireЗагрузите модуль (синхронизация).

// a-commonJs.js (导出)
var a = 5;var add = function(param){//在这里写上需要向外暴露的函数、变量    return a + param}module.exports.a = a;module.exports.add = add===========================
// b-commonJs.js引用自定义模块,参数包含路径,可省略.js(导入)
var addFn = require('./a-commonJs')console.log(addFn.add(3)) //8console.log(addFn.a) //5

 Небольшое объяснение: :

exports 是对 module.exports 的引用。比如我们可以认为在一个模块的顶部有这句代码:   exports = module.exports所以,我们不能直接给exports赋值,比如number、function等。 

Уведомление:потому чтоmodule.exports сам по себе является объектом, поэтому мы можем использовать при экспорте

module.exports = {foo: 'bar'}  //true

module.exports.foo = 'bar'  //true.

Однако exports — это ссылка на module.exports, или подразумевается, что exports — это указатель, exports указывает на module.exports, поэтому мы можем использовать толькоexports.foo = 'bar' образом, вместо использования

exports = {foo: 'bar'} //error 这种方式是错误的,相当于重新定义了exports

Небольшое преимущество:Устранение зависимостей, глобальных переменных проблем загрязнения

небольшой недостаток: CommonJS загружает модули синхронно. На стороне сервера файлы модулей хранятся на локальном диске и читаются очень быстро, так что проблем с этим не будет. Но со стороны браузера, ограниченного сетевыми причинами,CommonJS не подходит для загрузки модуля на стороне браузера, более разумное решение — использовать асинхронную загрузку, как в спецификации AMD ниже.

3. Спецификации AMD

Продолжая сказанное выше, спецификация AMD заключается в асинхронной загрузке модулей.,позволяет указать функцию обратного вызова,AMD — это канонический результат продвижения определений модулей RequireJS..

В стандарте AMD определены следующие три API:

  1. require([module], callback)
  2. define(id, [depends], callback)
  3. require.config()

То есть по определениюопределениеМодуль, и требовать использованиянагрузкаМодуль, использующий require.config() для указания пути ссылки.

первый пришелофициальный сайт require.jsЗагрузите последнюю версию, а затем разместите ее на странице следующим образом:

<script data-main="./alert" src="./require.js"></script>

Атрибут data-main нельзя опускать.



Вышеуказанные являются модуль определения, эталонный модуль и появившееся сообщение Prompt, при запуске в браузере.

При ссылке на модуль мы помещаем имя модуля в[]в качествеreqiure()Первый параметр ; если модуль, который мы сами определяем, также зависит от других модулей, то нам нужно поместить их в[]в качествеdefine()первый параметр .

При использовании require.js мы должны загружать все зависимости заранее, прежде чем сможем их использовать, вместо того, чтобы загружать их, когда нам нужно их использовать.

Небольшое преимущество:Подходит для асинхронной загрузки модулей в среде браузера, параллельной загрузки нескольких модулей.

Небольшой недостаток:Не может быть загружен по запросу, высокая стоимость разработки

4. CMD

      AMD выступает за то, чтобы полагаться на предварительное доверие и раннее исполнение,Сторонники CMD полагаются на близость и отложенное выполнение. CMD — это стандартизированный результат определения модуля в процессе продвижения SeaJS.


Очевидно, что CMD загружается по требованию, принципе близости.

5. Модульность ES6

В ES6 мы можем использовать ключевое слово import для импорта модулей и использовать ключевое слово exprot для экспорта модулей, что является более мощным, чем предыдущие решения, и это то, что мы рекомендуем.Но поскольку ES6 в настоящее время не может быть выполнен в браузере, мы можем только скомпилировать неподдерживаемый импорт в широко поддерживаемый в настоящее время запрос через babel.


es6 имеет экспорт по умолчанию при экспорте,export default, После его использования для экспорта не нужно добавлять {} при импорте, а имя модуля можно запускать произвольно. Имя на самом деле является объектом, содержащим функции или переменные в экспортируемом модуле.


Но модуль может иметь только одинexport default.

6. Разница между CommonJs и ES6

Следующие цитаты учителя Жуань Ифэн:

(1) Модуль CommonJS выводит копию значения, а модуль ES6 выводит ссылку на значение.

  • Модули CommonJS выводят копию значения, то есть после вывода значения изменения внутри модуля не повлияют на значение.
  • Модули ES6 работают иначе, чем CommonJS. Когда движок JS статически анализирует скрипт, он встречает команду загрузки модуляimport, создается ссылка только для чтения. Когда скрипт действительно выполняется, в соответствии с этой ссылкой только для чтения перейдите к загруженному модулю, чтобы получить значение. Другими словами, ES6importВроде как "символическая ссылка" Unix-систем, исходное значение изменилось,importЗагруженное значение также изменится соответствующим образом. Таким образом, на модули ES6 ссылаются динамически и они не кэшируют значения, а переменные в модулях привязаны к модулю, в котором они находятся.

(2) Модуль CommonJS загружается во время выполнения, а модуль ES6 является выходным интерфейсом во время компиляции.

  • Загрузка во время выполнения: модули CommonJS являются объектами, то есть при вводе сначала загружается весь модуль, генерируется объект, а затем из этого объекта считываются методы, такая загрузка называется «загрузка во время выполнения».

  • Загрузка во время компиляции: модули ES6 не являются объектами, а передаются черезexportКоманда явно указывает код для вывода,importв виде статической команды. то естьimportВместо того, чтобы загружать весь модуль, вы можете указать загружать выходное значение, эта загрузка называется «загрузкой во время компиляции».

CommonJS загружает объект (т.е.module.exportsсвойство), объект не будет создан, пока скрипт не завершит работу. Модуль ES6 не является объектом, его внешний интерфейс — это просто статическое определение, которое будет сгенерировано на этапе статического анализа кода.



Небольшое пояснение: Эта статья — всего лишь моя собственная небольшая заметка, которую мне удобно запомнить и понять. \(^о^)/~