новое хранилище знанийПередняя часть от входа до входаПросите внимания, помечайте звездочками и предложениями и время от времени обновляйте~
Эпизоды, которые вы не видели:Большое путешествие по построению фундамента с нуля (подробное объяснение, постоянное обновление~)
Если вы считаете, что это хорошо, пожалуйста, поставьте палец вверх
До NodeJS, потому что не было слишком сложных сценариев разработки, не было модульности во фронтенде, а только в бэкенде. После того, как NodeJS родился, он использует модульную спецификацию CommonJS. С тех пор модульность js быстро развивалась.
Модульный метод разработки может обеспечить скорость повторного использования кода и упростить управление кодом. как правило,Файл — это модуль, который имеет свою собственную область видимости и предоставляет доступ только к определенным переменным и функциям..
CommonJS
NodeJS является основным практиком спецификации CommonJS и имеет четыре важные переменные среды для поддержки модульной реализации:module
,exports
,require
,global
.
Каждый файл является модулем и имеет свою собственную область видимости. Переменные, функции и классы, определенные в файле, являются частными и невидимыми для других файлов.
// example.js
var x = 5;
var addX = function (value) {
return value + x;
};
В приведенном выше коде переменнаяx
и функцияaddX
, это текущий файлexample.js
Частный, других файлов не видно.
Если вы хотите совместно использовать переменные в нескольких файлах, вы должны определить их какglobal
свойства объекта.
global.warning = true;
код вышеwarning
переменная, которую могут читать все файлы. Конечно, такой способ записи не рекомендуется.
В спецификации CommonJS указано, что внутри каждого модуляmodule
Переменная представляет текущий модуль. Эта переменная является объектом,exports
свойства (т.е.module.exports
) — внешний интерфейс. Загрузка модуля фактически загружает модульmodule.exports
Атрибуты.
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
Приведенный выше код проходитmodule.exports
выходная переменнаяx
и функцияaddX
.
require
Метод используется для загрузки модулей.
var example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
Особенности модулей CommonJS заключаются в следующем.
- Весь код выполняется в области модуля и не загрязняет глобальную область.
- Модуль можно загружать несколько раз, но он будет запущен только один раз при первой загрузке, а затем текущий результат будет кэширован, а при последующей загрузке кэшированный результат будет прочитан напрямую. Чтобы модуль снова заработал, необходимо очистить кеш.
- Порядок загрузки модулей, порядок их появления в коде.
Объект модуля
Node внутренне предоставляет конструктор модуля. Все модули являются экземплярами Module.
Внутри каждого модуля находитсяmodule
Объект, представляющий текущий модуль. Он имеет следующие свойства.
-
module.id
Идентификатор модуля, обычно имя файла модуля с абсолютным путем. -
module.filename
Имя файла модуля с абсолютным путем. -
module.loaded
Возвращает логическое значение, указывающее, завершилась ли загрузка модуля. -
module.parent
Возвращает объект, представляющий модуль, вызвавший этот модуль. -
module.children
Возвращает массив других модулей, используемых этим модулем. -
module.exports
Указывает значение, выводимое модулем наружу.
Если модуль вызывается из командной строки, например node something.js, то module.parent имеет значение null. Если он вызывается в скрипте, таком как require('./something.js'), тогда module.parent — это модуль, вызвавший его. Используя это, вы можете определить, является ли текущий модуль сценарием входа.
свойство module.exports
Атрибут module.exports представляет внешний интерфейс вывода текущего модуля.Когда другие файлы загружают модуль, они фактически считывают переменную module.exports.
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
var example = require('./example.js');
console.log(example.x); // 5
console.log(example.addX(1)); // 6
переменная экспорта
Для удобства Node предоставляет переменную экспорта для каждого модуля, указывающую на module.exports. Это эквивалентно наличию такой строки в заголовке каждого модуля.
var exports = module.exports;
Поэтому при внешнем экспорте интерфейса модуля вы можете добавлять методы в объект экспорта.
exports.area = function (r) {
return Math.PI * r * r;
};
Обратите внимание, потому чтоexports
держатьmodule.exports
Таким образом, вы не можете напрямую указать значение переменной exports, потому что это равносильно разрыву связи между exports и module.exports.
exports = function(x) {console.log(x)};
Приведенный выше способ написания недействителен, так как экспорт больше не указывает на module.exports.
Следующее написание также недопустимо. Потому что это тоже вырезаноexports
правильноmodule.exports
цитаты
exports.hello = function() {
return 'hello';
};
module.exports = 'Hello world';
В приведенном выше коде функция hello не может быть экспортирована, поскольку модуль module.exports был переназначен.
Если внешний интерфейс модуля представляет собой одно значение, его нельзя вывести с помощью экспорта, а можно вывести только с помощью module.exports.
module.exports = function (x){ console.log(x);};
Режим загрузки
Спецификация CommonJS загружает модуль синхронно.При вводе сначала загружается весь модуль, генерируется объект, а затем метод считывается из объекта.Эта загрузка называется «загрузкой во время выполнения». То есть следующие операции можно выполнять только после завершения загрузки. Поскольку Node.js в основном используется для серверного программирования, файлы модулей обычно уже существуют на локальном жестком диске и читаются очень быстро, так что это не будет проблемой.
загрузочный механизм
Механизм загрузки модулей CommonJS заключается в том, что ввод является копией значения, которое выводится. То есть после вывода значения изменения внутри модуля не могут повлиять на это значение.
Ниже файл модуляlib.js
.
// lib.js
var counter = 3;
function incCounter() {
counter++;
}
module.exports = {
counter: counter,
incCounter: incCounter,
};
Приведенный выше код выводит внутреннюю переменнуюcounter
и внутренний метод, который переопределяет эту переменнуюincCounter
.
Затем загрузите указанный выше модуль.
// main.js
var counter = require('./lib').counter;
var incCounter = require('./lib').incCounter;
console.log(counter); // 3
incCounter();
console.log(counter); // 3
Приведенный выше код показывает,counter
После выхода,lib.js
Изменения внутри модуля не повлияютcounter
.
Технические характеристики AMD
Спецификация AMD заключается в том, чтобы загружать модули асинхронно, позволяя указывать функции обратного вызова. В среде браузера для загрузки модулей со стороны сервера необходимо использовать асинхронный режим, поэтому сторона браузера обычно использует спецификацию AMD.
Спецификация AMD использует метод определения для определения модулей.Если модули, которые мы определяем, также зависят от других модулей, их необходимо поместить в [] в качестве первого параметра define(). Вот пример:
define(['package/lib'], function(lib){
function foo(){
lib.log('hello world!');
}
return {
foo: foo
};
});
При ссылке на модуль мы помещаем имя модуля в [] в качестве первого параметра require(); все операторы, которые зависят от этого модуля, определены в функции обратного вызова, которая не будет выполняться до завершения загрузки.
// 引用模块,将模块放在[]内
require(['jquery', 'math'],function($, math){
var sum = math.add(10,20);
$("#sum").html(sum);
});
require
правила загрузки
Команда require используется для загрузки файлов, а расширение по умолчанию — .js.
var foo = require('foo');
// 等同于
var foo = require('foo.js');
В соответствии с различными форматами параметров,require
команда для поиска файлов модулей по разным путям.
1. 如果参数字符串以“/”开头,则表示加载的是一个位于绝对路径的模块文件。比如,`require('/home/marco/foo.js')`将加载`/home/marco/foo.js`。
2. 如果参数字符串以“./”开头,则表示加载的是一个位于相对路径(跟当前执行脚本的位置相比)的模块文件。比如,`require('./circle')`将加载当前脚本同一目录的`circle.js`。
3. 如果参数字符串不以“./“或”/“开头,则表示加载的是一个默认提供的核心模块(位于Node的系统安装目录中),或者一个位于各级node_modules目录的已安装模块(全局安装或局部安装)。
举例来说,脚本`/home/user/projects/foo.js`执行了`require('bar.js')`命令,Node会依次搜索以下文件。
/usr/local/lib/node/bar.js
/home/user/projects/node_modules/bar.js
/home/user/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
4. 如果参数字符串不以“./“或”/“开头,而且是一个路径,比如require('example-module/path/to/file'),则将先找到example-module的位置,然后再以它为参数,找到后续路径。
5. 如果指定的模块文件没有发现,Node会尝试为文件名添加.js、.json、.node后,再去搜索。.js件会以文本格式的JavaScript脚本文件解析,.json文件会以JSON格式的文本文件解析,.node文件会以编译后的二进制文件解析。
6. 如果想得到require命令加载的确切文件名,使用require.resolve()方法。
Правила загрузки каталога
В файле package.json запишите файл ввода в основное поле. Пусть метод require пройдет через этот файл записи и загрузит весь каталог.Ниже приведен пример.
// package.json
{
"name" : "some-library",
"main" : "./lib/some-library.js"
}
После того как require обнаружит, что строка параметра указывает на каталог, он автоматически просмотрит файл package.json каталога, а затем загрузит файл записи, указанный в основном поле. Если в файле package.json нет основного поля или если файла package.json нет вообще, будет загружен файл index.js или файл index.node в этом каталоге.
кеш модуля
При первой загрузке модуля Node кэширует модуль. Когда модуль загружается позже, свойство module.exports модуля берется непосредственно из кеша.
require('./example.js');
require('./example.js').message = "hello";
require('./example.js').message
// "hello"
Используйте команду require три раза подряд, чтобы загрузить один и тот же модуль. При второй загрузке к выходному объекту добавляется свойство сообщения. Но когда он загружается в третий раз, атрибут сообщения все еще существует, что доказывает, что команда require не перезагружает файл модуля, а выводит кеш.
Если вы хотите выполнить модуль несколько раз, вы можете позволить модулю выводить функцию, а затем повторно выполнять функцию вывода каждый раз, когда вам требуется модуль.
Функция require и ее вспомогательные методы в основном таковы.
- require(): загрузить внешние модули
- require.resolve(): преобразовать имя модуля в абсолютный путь
- require.main: указывает на основной модуль
- require.cache: указывает на все кешированные модули
- require.extensions: вызывать различные функции выполнения в соответствии с суффиксом файла
CMD
Средство реализации AMD require.js загрузит и выполнит код в модуле в первый раз при объявлении зависимого модуля:
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
// 等于在最前面声明并初始化了要用到的所有模块
if (false) {
// 即便没用到某个模块 b,但 b 还是提前执行了。**这就CMD要优化的地方**
b.foo()
}
});
CMD — еще одно решение для модуляризации js, очень похожее на AMD, разница в том, что AMD уважает предварительное доверие и раннее выполнение, в то время как CMD уважает зависимость от близости и отложенного выполнения.
define(function (require, exports, module){
var someModule = require("someModule");
var anotherModule = require("anotherModule");
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
exports.asplode = function (){
someModule.doTehAwesome();
anotherModule.doMoarAwesome();
};
});
UMD
umd — это идея, которая представляет собой совместимый метод записи, совместимый с commonjs, AMD, CMD, define.amd/define.cmd/module и т. д., чтобы определить, какие методы поддерживаются в настоящее время,
Сначала UMD определяет, существует ли модуль (экспорт), поддерживающий Node.js, и, если он существует, используется режим модуля Node.js. Затем оцените, поддерживается ли AMD (определить, существует), и если он существует, используйте метод AMD для загрузки модуля. Если это не работает, смонтируйте его в глобальный объект окна.
(функция (корень, фабрика) { if (typeof define === 'функция' && (define.amd || define.cmd)) { //АМД,ЦМД определить (['b'], функция (b) { возврат (root.returnExportsGlobal = factory(b)) }); } else if (typeof module === 'object' && module.exports) { //Узел, CommonJS и т.д. module.exports = factory (требуется ('b')); } еще { // доступ к глобальному объекту root.returnExports = factory(root.b); } }(это, функция (б) { вернуть {}; }));
ES6 Module
На уровне языковых стандартов 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);
}
ES6 также предоставляет команду экспорта по умолчанию, которая указывает выходные данные модуля по умолчанию, а соответствующий оператор импорта не требует использования фигурных скобок. Это также ближе к стилю цитирования ADM.
Особенности модулей ES6:
- Строгий режим: модули ES6 автоматически используют строгий режим.
- Функция импорта только для чтения: свойство импорта доступно только для чтения и не может быть назначено, аналогично функции const.
- Продвижение экспорта/импорта: импорт/экспорт должен быть расположен на верхнем уровне модуля и не может быть расположен в области; во-вторых, импорт/экспорт в модуле будет продвигаться наверх модуля, что делается в этап компиляции
загрузочный механизм
Модули ES6 работают иначе, чем CommonJS. Модули ES6 не являются объектами, а явно указывают код вывода через команду экспорта, а импорт осуществляется в виде статической команды. Когда движок JS статически анализирует скрипт и встречает команду импорта загрузки модуля, он генерируетссылка только для чтения. Когда скрипт действительно выполняется, в соответствии с этой ссылкой только для чтения перейдите к загруженному модулю, чтобы получить значение. Изменения во внутренней ссылке модуля будут отражены внешне.
При импорте вы можете указать загружать определенное выходное значение вместо загрузки всего модуля.Эта загрузка называется «загрузкой во время компиляции». Код модуля импортируется во время компиляции, а не загружается во время выполнения, поэтому условная загрузка невозможна. Именно благодаря этому возможен статический анализ.
Эта статья расположена в:Большое путешествие по построению фундамента с нуля (подробное объяснение, постоянное обновление~)
Рекомендуемое чтение:
Давайте поговорим о характеристиках атрибута положения css и его значении атрибута sticky (эффект потолка)
Я не знал, что это значение свойства существовало раньше. . .Переплавка и перекраска, KFC и MC
Каждый раз, когда эти двое упоминаются одновременно, отношения настолько близки, что KFC должен иметь рядом с собой MC.окно просмотра и 1px | инструментщик: это 1px, дизайнер: нет, это не
Я не умею проектировать, но умею споритьСъедобный "сухой товар css layout", чистый пример HTML, отлаживаемый | горизонтальный, вертикальный, многоколоночный
Можно смотреть, можно отлаживать, можно забрать, это единственное, ветки нет«Каскадный контекст CSS», который интерфейс должен освоить
Девушка и кот, кого вы хотите?
Справочная документация: