Spec-Zone.ru › Node.js 18 LTS

Модули: CommonJS модули

Устойчивость: 2 - Стабильно

CommonJS модули — это оригинальный способ упаковки JavaScript кода для Node.js. Node.js также поддерживает стандарт ECMAScript модулей, используемый браузерами и другими JavaScript средами выполнения.

В Node.js каждый файл обрабатывается как отдельный модуль. Например, рассмотрим файл с именем foo.js:

const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`); copy

В первой строке foo.js загружает модуль circle.js , который находится в той же директории, что и foo.js.

Вот содержимое circle.js:

const { PI } = Math;

exports.area = (r) => PI * r ** 2;

exports.circumference = (r) => 2 * PI * r; copy

Модуль circle.js экспортировал функции area() и circumference(). Функции и объекты добавляются в корень модуля путём указания дополнительных свойств в специальном объекте exports.

Переменные, локальные для модуля, будут приватными, потому что модуль обернут функцией в Node.js (см. обёртку модуля). В этом примере переменная PI является приватной для circle.js.

Свойству module.exports можно присвоить новое значение (например, функцию или объект).

Ниже bar.js использует модуль square, который экспортирует класс Square:

const Square = require('./square.js');
const mySquare = new Square(2);
console.log(`The area of mySquare is ${mySquare.area()}`); copy

Модуль square определён в square.js:

// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
  constructor(width) {
    this.width = width;
  }

  area() {
    return this.width ** 2;
  }
}; copy

Система модулей CommonJS реализована в module ядревом модуле.

Включение

Node.js имеет две системы модулей: CommonJS модули и ECMAScript модули.

По умолчанию Node.js будет обрабатывать следующее как CommonJS модули:

  • Файлы с расширением .cjs;

  • Файлы с расширением .js , когда ближайший родительский package.json файл содержит поле верхнего уровня "type" со значением "commonjs".

  • Файлы с расширением .js , когда ближайший родительский package.json файл не содержит поле верхнего уровня "type". Авторы пакетов должны включать поле "type", даже в пакетах, где все источники являются CommonJS. Явное указание type пакета облегчит сборщикам и загрузчикам определение того, как файлы в пакете должны интерпретироваться.

  • Файлы с расширением, которое не является .mjs, .cjs, .json, .node, или .js (когда ближайший родительский package.json файл содержит поле верхнего уровня "type" со значением "module", эти файлы будут распознаны как CommonJS модули только если они включаются через require(), а не когда используются как точка входа в программу в командной строке).

См. Определение системы модулей для получения дополнительной информации.

Вызов require() всегда использует загрузчик CommonJS модулей. Вызов import() всегда использует загрузчик ECMAScript модулей.

Доступ к главному модулю

Когда файл запускается напрямую из Node.js, require.main устанавливается в его module. Это означает, что можно определить, был ли файл запущен напрямую, проверив require.main === module.

Для файла foo.js, это будет true при запуске через node foo.js, но false при запуске через require('./foo').

Когда точка входа не является CommonJS модулем, require.main имеет значение undefined, и главный модуль недоступен.

Советы по менеджерам пакетов

Семантика функции Node.js require() была спроектирована достаточно универсально, чтобы поддерживать разумные структуры директорий. Программы менеджеров пакетов, такие как dpkg, rpm, и npm , надеются, что смогут собирать нативные пакеты из Node.js модулей без модификаций.

Ниже приведена рекомендуемая структура директорий:

Предположим, что нам нужно поместить папку /usr/lib/node/<some-package>/<some-version> в содержимое определённой версии пакета.

Пакеты могут зависеть друг от друга. Для установки пакета foo, возможно, потребуется установка определённой версии пакета bar. Пакет bar сам может иметь зависимости, которые в некоторых случаях могут конфликтовать или образовывать циклические зависимости.

Поскольку Node.js ищет realpath любых загружаемых модулей (то есть, разрешает символические ссылки) и затем ищет их зависимости в node_modules папках, эту ситуацию можно решить с помощью следующей архитектуры:

  • /usr/lib/node/foo/1.2.3/: Содержимое пакета foo , версия 1.2.3.
  • /usr/lib/node/bar/4.3.2/: Содержимое пакета bar , от которого зависит foo.
  • /usr/lib/node/foo/1.2.3/node_modules/bar: Символическая ссылка на /usr/lib/node/bar/4.3.2/.
  • /usr/lib/node/bar/4.3.2/node_modules/*: Символические ссылки на пакеты, от которых зависит bar.

Таким образом, даже если встретится цикл или конфликты зависимостей, каждый модуль сможет получить версию своей зависимости, которую он может использовать.

Когда код в пакете foo выполняет require('bar'), он получит версию, которая находится в /usr/lib/node/foo/1.2.3/node_modules/bar. Затем, когда код в пакете bar выполняет require('quux'), он получит версию, которая находится в /usr/lib/node/bar/4.3.2/node_modules/quux.

Кроме того, для повышения эффективности процесса поиска модулей, вместо размещения пакетов непосредственно в /usr/lib/node, можно поместить их в /usr/lib/node_modules/<name>/<version>. Тогда Node.js не будет тратить время на поиск отсутствующих зависимостей в /usr/node_modules или /node_modules.

Для того чтобы модули были доступны в Node.js REPL, возможно, также потребуется добавить папку /usr/lib/node_modules в переменную среды $NODE_PATH. Поскольку поиск модулей с использованием папок node_modules является относительным и основан на фактическом пути к файлам, вызывающим require(), сами пакеты могут располагаться где угодно.

Расширение .mjs

Из-за синхронной природы require(), невозможно использовать его для загрузки файлов ECMAScript модулей. Попытка сделать это вызовет ошибку ERR_REQUIRE_ESM. Используйте import() вместо этого.

Расширение .mjs зарезервировано для ECMAScript модулей, которые не могут быть загружены через require(). См. раздел Определение системы модулей для получения дополнительной информации о том, какие файлы анализируются как ECMAScript модули.

Всё вместе

Чтобы получить точное имя файла, которое будет загружено при вызове require() , используйте функцию require.resolve().

Объединяя всё вышесказанное, вот алгоритм высокого уровня того, что делает require():

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with '/'
   a. set Y to be the file system root
3. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
   c. THROW "not found"
4. If X begins with '#'
   a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
5. LOAD_PACKAGE_SELF(X, dirname(Y))
6. LOAD_NODE_MODULES(X, dirname(Y))
7. THROW "not found"

LOAD_AS_FILE(X)
1. If X is a file, load X as its file extension format. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP

LOAD_INDEX(X)
1. If X/index.js is a file, load X/index.js as JavaScript text. STOP
2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
3. If X/index.node is a file, load X/index.node as binary addon. STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. If "main" is a falsy value, GOTO 2.
   c. let M = X + (json main field)
   d. LOAD_AS_FILE(M)
   e. LOAD_INDEX(M)
   f. LOAD_INDEX(X) DEPRECATED
   g. THROW "not found"
2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)
1. let DIRS = NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_PACKAGE_EXPORTS(X, DIR)
   b. LOAD_AS_FILE(DIR/X)
   c. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   b. DIR = path join(PARTS[0 .. I] + "node_modules")
   c. DIRS = DIR + DIRS
   d. let I = I - 1
5. return DIRS + GLOBAL_FOLDERS

LOAD_PACKAGE_IMPORTS(X, DIR)
1. Find the closest package scope SCOPE to DIR.
2. If no scope was found, return.
3. If the SCOPE/package.json "imports" is null or undefined, return.
4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
  ["node", "require"]) defined in the ESM resolver.
5. RESOLVE_ESM_MATCH(MATCH).

LOAD_PACKAGE_EXPORTS(X, DIR)
1. Try to interpret X as a combination of NAME and SUBPATH where the name
   may have a @scope/ prefix and the subpath begins with a slash (`/`).
2. If X does not match this pattern or DIR/NAME/package.json is not a file,
   return.
3. Parse DIR/NAME/package.json, and look for "exports" field.
4. If "exports" is null or undefined, return.
5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
   `package.json` "exports", ["node", "require"]) defined in the ESM resolver.
6. RESOLVE_ESM_MATCH(MATCH)

LOAD_PACKAGE_SELF(X, DIR)
1. Find the closest package scope SCOPE to DIR.
2. If no scope was found, return.
3. If the SCOPE/package.json "exports" is null or undefined, return.
4. If the SCOPE/package.json "name" is not the first segment of X, return.
5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
   "." + X.slice("name".length), `package.json` "exports", ["node", "require"])
   defined in the ESM resolver.
6. RESOLVE_ESM_MATCH(MATCH)

RESOLVE_ESM_MATCH(MATCH)
1. let RESOLVED_PATH = fileURLToPath(MATCH)
2. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension
   format. STOP
3. THROW "not found"

Кэширование

Модули кэшируются после первой загрузки. Это означает (среди прочего), что каждый вызов require('foo') получит ровно тот же объект, если он будет ссылаться на тот же файл.

При условии, что require.cache не изменяется, многократные вызовы require('foo') не приведут к многократному выполнению кода модуля. Это важная функция. С ней можно возвращать "частично готовые" объекты, что позволяет загружать транзитивные зависимости даже при наличии циклов.

Чтобы модуль выполнял код многократно, экспортируйте функцию и вызывайте её.

Ограничения кэширования модулей

Модули кэшируются на основе разрешённого имени файла. Поскольку модули могут разрешаться до разных имён файлов в зависимости от расположения вызывающего модуля (загрузка из папок node_modules), нет гарантии, что require('foo') всегда вернёт точно такой же объект, если он будет ссылаться на разные файлы.

Кроме того, в системах файлов или операционных системах, не учитывающих регистр, разные разрешённые имена файлов могут указывать на один и тот же файл, но кэш всё равно будет рассматривать их как разные модули и перезагружать файл несколько раз. Например, require('./foo') и require('./FOO') возвращают два разных объекта, независимо от того, являются ли ./foo и ./FOO одним и тем же файлом.

Ядерные модули

История
Версия Изменения
v16.0.0, v14.18.0

Добавлена поддержка импорта node: для require(...).

Node.js имеет несколько модулей, скомпилированных в двоичный файл. Эти модули описаны более подробно в других разделах этой документации.

Ядерные модули определены в исходном коде Node.js и расположены в папке lib/.

Ядерные модули можно идентифицировать по префиксу node:, в этом случае он обходит кэш require. Например, require('node:http') всегда вернёт встроенный модуль HTTP, даже если есть запись require.cache с таким же именем.

Некоторые ядерные модули всегда предпочтительно загружаются, если их идентификатор передаётся в require(). Например, require('http') всегда вернёт встроенный модуль HTTP, даже если существует файл с таким же именем. Список ядерных модулей, которые можно загрузить без использования префикса node: , представлен как module.builtinModules.

Циклы

При наличии циклических require() вызовов, модуль может не завершить выполнение к моменту возврата.

Рассмотрим такую ситуацию:

a.js:

console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done'); copy

b.js:

console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done'); copy

main.js:

console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done = %j, b.done = %j', a.done, b.done); copy

Когда main.js загружает a.js, а затем a.js в свою очередь загружает b.js. В этот момент b.js пытается загрузить a.js. Чтобы предотвратить бесконечный цикл, незавершенная копия объекта экспорта a.js возвращается модулю b.js . b.js затем завершает загрузку, и его объект exports предоставляется модулю a.js.

К тому времени, как main.js загрузил оба модуля, они оба завершены. Таким образом, выходные данные этой программы будут:

$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done = true, b.done = true copy

Требуется тщательное планирование, чтобы циклические зависимости модулей работали корректно в приложении.

Модули файлов

Если точное имя файла не найдено, Node.js попытается загрузить требуемый файл с добавленными расширениями: .js, .json, и, наконец, .node. При загрузке файла с другим расширением (например, .cjs) его полное имя должно быть передано require(), включая расширение файла (например, require('./file.cjs')).

Файлы .json парсятся как текстовые файлы JSON, файлы .node интерпретируются как скомпилированные модули плагинов, загруженные с помощью process.dlopen(). Файлы с любым другим расширением (или без расширения) парсятся как текстовые файлы JavaScript. Обратитесь к разделу Определение системы модулей, чтобы понять, какая цель анализа будет использована.

Модуль, требуемый и префиксрованный '/', представляет собой абсолютный путь к файлу. Например, require('/home/marco/foo.js') загрузит файл по адресу /home/marco/foo.js.

Требуемый модуль с префиксом './' является относительным по отношению к файлу, вызывающему require(). То есть, circle.js должен находиться в той же директории, что и foo.js, для того, чтобы require('./circle') смог его найти.

Без ведущего '/', './', или '../' для указания файла, модуль должен быть либо ядром модуля, либо загружаться из папки node_modules.

Если указанный путь не существует, require() вызовет ошибку MODULE_NOT_FOUND.

Папки как модули

Уровень стабильности: 3 - Legacy: Используйте экспорты подпутей или импорты подпутей вместо этого.

Существует три способа, которыми папка может быть передана require() в качестве аргумента.

Первый заключается в создании файла package.json в корне папки, который определяет модуль main. Пример файла package.json может выглядеть следующим образом:

{ "name" : "some-library",
  "main" : "./lib/some-library.js" } copy

Если он находился в папке по адресу ./some-library, то require('./some-library') попытается загрузить ./some-library/lib/some-library.js.

Если файл package.json отсутствует в каталоге или запись "main" отсутствует или не может быть разрешена, Node.js попытается загрузить файл index.js или index.node из этой директории. Например, если файла package.json не было в предыдущем примере, то require('./some-library') попытался бы загрузить:

  • ./some-library/index.js
  • ./some-library/index.node

Если эти попытки окажутся неудачными, Node.js сообщит об отсутствии всего модуля с помощью стандартной ошибки:

Error: Cannot find module 'some-library' copy

Во всех трёх вышеуказанных случаях вызов import('./some-library') приведёт к ошибке ERR_UNSUPPORTED_DIR_IMPORT. Использование пакета экспортов подпутей или импортов подпутей может обеспечить такие же преимущества организации контента, как папки-модули, и работать как с require, так и с import.

Загрузка из папок node_modules

Если идентификатор модуля, переданный в require(), не является модулем ядра core и не начинается с '/', '../', или './', Node.js начинает с каталога текущего модуля и добавляет /node_modules, пытаясь загрузить модуль из этого местоположения. Node.js не будет добавлять node_modules к пути, уже оканчивающемуся на node_modules.

Если он не будет найден там, то переходит к родительской директории и так далее, пока не достигнет корня файловой системы.

Например, если в файле по адресу '/home/ry/projects/foo.js' с именем require('bar.js'), Node.js будет искать в следующих местах, в таком порядке:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

Это позволяет программам локализовать свои зависимости, чтобы они не конфликтовали.

Возможно потребовать конкретные файлы или подмодули, распределенные с модулем, включив суффикс пути после имени модуля. Например, require('example-module/path/to/file') разрешит path/to/file относительно того, где расположен example-module . Суффиксный путь следует тем же семантикам разрешения модулей.

Загрузка из глобальных папок

Если переменная среды NODE_PATH установлена в список путей, разделённых двоеточиями, Node.js будет искать модули по этим путям, если они не найдены где-либо ещё.

В Windows, NODE_PATH разделяются точкой с запятой (;) вместо двоеточий.

NODE_PATH изначально был создан для поддержки загрузки модулей из различных путей до определения текущего алгоритма разрешения модулей .

NODE_PATH всё ещё поддерживается, но теперь он менее необходим, поскольку экосистема Node.js установила соглашение о поиске зависимых модулей. Иногда развертывания, которые полагаются на NODE_PATH, показывают неожиданное поведение, если люди не знают, что NODE_PATH должна быть установлена. Иногда зависимости модуля меняются, что приводит к загрузке другой версии (или даже другого модуля) при поиске NODE_PATH.

Кроме того, Node.js будет искать в следующем списке GLOBAL_FOLDERS:

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/lib/node

Где $HOME - домашняя директория пользователя, а $PREFIX - конфигурируемая Node.js node_prefix.

В основном это из исторических соображений.

Настоятельно рекомендуется размещать зависимости в локальной папке node_modules . Они будут загружаться быстрее и надёжнее.

Обёртка модуля

Перед выполнением кода модуля Node.js обернёт его функцией-обёрткой, похожей на следующую:

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
}); copy

Делая это, Node.js добивается нескольких целей:

  • Он сохраняет переменные верхнего уровня (определённые с помощью var, const, или let) в области видимости модуля, а не глобального объекта.
  • Это помогает предоставить некоторые глобальные переменные, которые на самом деле специфичны для модуля, такие как:
    • Объекты module и exports, которые реализатор может использовать для экспорта значений из модуля.
    • Удобные переменные __filename и __dirname, содержащие абсолютное имя файла и путь к каталогу модуля.

Область видимости модуля

__dirname

Добавлена в: v0.1.27
  • <строка>

Имя каталога текущего модуля. Оно совпадает с path.dirname() __filename.

Пример: запуск node example.js из /Users/mjr

console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr copy

__filename

Добавлена в: v0.0.1
  • <строка>

Имя файла текущего модуля. Это абсолютный путь к текущему файлу модуля с разрешенными символическими ссылками.

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

См. __dirname для имени каталога текущего модуля.

Примеры:

Запуск node example.js из /Users/mjr

console.log(__filename);
// Prints: /Users/mjr/example.js
console.log(__dirname);
// Prints: /Users/mjr copy

Рассмотрим два модуля: a и b, где b является зависимостью a, и структура каталогов:

  • /Users/mjr/app/a.js
  • /Users/mjr/app/node_modules/b/b.js

Ссылки на __filename внутри b.js вернут /Users/mjr/app/node_modules/b/b.js, а ссылки на __filename внутри a.js вернут /Users/mjr/app/a.js.

exports

Добавлена в: v0.1.12
  • <Объект>

Ссылка на module.exports, которая короче для ввода. Подробности о том, когда использовать exports и когда module.exports, см. в разделе об обходном пути экспорта.

module

Добавлена в: v0.1.16
  • <модуль>

Ссылка на текущий модуль, см. раздел об module объекте. В частности, module.exports используется для определения того, что экспортирует модуль, и что доступно через require().

require(id)

Добавлена в: v0.1.13
  • id <строка> имя или путь модуля
  • Возвращает: <любой> содержимое экспортированного модуля

Используется для импорта модулей, JSON, и локальных файлов. Модули можно импортировать из node_modules. Локальные модули и JSON-файлы можно импортировать с помощью относительного пути (например, ./, ./foo, ./bar/baz, ../foo), который будет разрешен относительно каталога, указанного в __dirname (если задан) или текущей рабочей директории. Относительные пути в стиле POSIX разрешаются независимо от ОС, то есть вышеприведенные примеры будут работать в Windows так же, как и в Unix.

// Importing a local module with a path relative to the `__dirname` or current
// working directory. (On Windows, this would resolve to .\path\myLocalModule.)
const myLocalModule = require('./path/myLocalModule');

// Importing a JSON file:
const jsonData = require('./path/filename.json');

// Importing a module from node_modules or Node.js built-in module:
const crypto = require('node:crypto'); copy
require.cache
Добавлена в: v0.3.0
  • <Объект>

Модули кэшируются в этом объекте при их использовании. Удаление пары ключ-значение из этого объекта приведет к перегрузке модуля при следующем вызове require. Это не относится к нативным плагинам, для которых перегрузка приведет к ошибке.

Также возможно добавление или замена записей. Этот кеш проверяется перед встроенными модулями, и если имя, совпадающее с именем встроенного модуля, добавлено в кеш, только вызовы require с префиксом node: получат встроенный модуль. Используйте с осторожностью!

const assert = require('node:assert');
const realFs = require('node:fs');

const fakeFs = {};
require.cache.fs = { exports: fakeFs };

assert.strictEqual(require('fs'), fakeFs);
assert.strictEqual(require('node:fs'), realFs); copy
require.extensions
Добавлена в: v0.3.0Устаревшая с версии: v0.10.6
Уровень стабильности: 0 - Устаревшее
  • <Объект>

Инструкции для require по обработке определенных расширений файлов.

Обработка файлов с расширением .sjs как .js:

require.extensions['.sjs'] = require.extensions['.js']; copy

Устарело. Раньше этот список использовался для загрузки модулей, не написанных на JavaScript, в Node.js, компилируя их по требованию. Однако на практике существуют лучшие способы, такие как загрузка модулей через другую программу Node.js или предварительная компиляция их в JavaScript.

Избегайте использования require.extensions. Это может привести к скрытым ошибкам, а разрешение расширений становится медленнее с каждым зарегистрированным расширением.

require.main
Добавлена в: v0.1.17
  • <модуль> | <неопределено>

Объект Module, представляющий загружаемый скрипт входа при запуске процесса Node.js, или undefined, если точка входа программы не является модулем CommonJS. См. "Доступ к основному модулю".

В скрипте entry.js:

console.log(require.main); copy
node entry.js copy
Module {
  id: '.',
  path: '/absolute/path/to',
  exports: {},
  filename: '/absolute/path/to/entry.js',
  loaded: false,
  children: [],
  paths:
   [ '/absolute/path/to/node_modules',
     '/absolute/path/node_modules',
     '/absolute/node_modules',
     '/node_modules' ] } copy
require.resolve(request[, options])
История
Версия Изменения
v8.9.0

Теперь поддерживается опция paths.

v0.3.0

Добавлена в: v0.3.0

  • request <строка> Путь к модулю для разрешения.
  • options <Объект>
    • paths <массив строк> Пути для разрешения расположения модуля. Если присутствуют, эти пути используются вместо стандартных путей разрешения, за исключением GLOBAL_FOLDERS, таких как $HOME/.node_modules, которые всегда включаются. Каждый из этих путей используется в качестве отправной точки для алгоритма разрешения модуля, то есть иерархия node_modules проверяется с этого местоположения.
  • Возвращает: <строка>

Использует внутренние механизмы require() для поиска расположения модуля, но вместо загрузки модуля просто возвращает разрешённое имя файла.

Если модуль не найден, выбрасывается ошибка MODULE_NOT_FOUND.

require.resolve.paths(request)
Добавлена в: v8.9.0
  • request <строка> Путь к модулю, пути поиска которого нужно получить.
  • Возвращает: <массив строк> | <null>

Возвращает массив, содержащий пути, просмотренные при разрешении request или null если строка request ссылается на ядро модуля, например, http или fs.

Объект module

Добавлен в: v0.1.16
  • <Объект>

В каждом модуле свободная переменная module ссылается на объект, представляющий текущий модуль. Для удобства module.exports также доступен через глобальную переменную модуля exports. module на самом деле не глобальная, а локальная для каждого модуля.

module.children

Добавлен в: v0.1.16
  • <модуль[]>

Объекты модулей, необходимых в первый раз этим модулем.

module.exports

Добавлен в: v0.1.16
  • <Объект>

Объект module.exports создается системой Module. Иногда это неприемлемо; многие хотят, чтобы их модуль был экземпляром какого-либо класса. Для этого присвойте желаемый объект экспорта переменной module.exports. Присвоение желаемого объекта exports просто перепривяжет локальную переменную exports, что, вероятно, нежелательно.

Например, предположим, что мы создаем модуль под названием a.js:

const EventEmitter = require('node:events');

module.exports = new EventEmitter();

// Do some work, and after some time emit
// the 'ready' event from the module itself.
setTimeout(() => {
  module.exports.emit('ready');
}, 1000); copy

Затем в другом файле мы можем сделать:

const a = require('./a');
a.on('ready', () => {
  console.log('module "a" is ready');
}); copy

Присвоение переменной module.exports должно быть выполнено немедленно. Это нельзя делать в каких-либо колбэках. Это не работает:

x.js:

setTimeout(() => {
  module.exports = { a: 'hello' };
}, 0); copy

y.js:

const x = require('./x');
console.log(x.a); copy
exports сокращение
Добавлен в: v0.1.16

Переменная exports доступна в файловом пространстве имен модуля и получает значение module.exports перед оценкой модуля.

Это позволяет использовать сокращение, так что module.exports.f = ... можно записать более лаконично как exports.f = .... Однако имейте в виду, что, как и любая переменная, если новое значение присваивается exports, оно больше не привязано к module.exports:

module.exports.hello = true; // Exported from require of module
exports = { hello: false };  // Not exported, only available in the module copy

Когда свойство module.exports полностью заменяется новым объектом, обычно также переприсваивается exports:

module.exports = exports = function Constructor() {
  // ... etc.
}; copy

Для иллюстрации поведения представьте эту гипотетическую реализацию require(), которая очень похожа на то, что фактически делает require():

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
    // Module code here. In this example, define a function.
    function someFunc() {}
    exports = someFunc;
    // At this point, exports is no longer a shortcut to module.exports, and
    // this module will still export an empty default object.
    module.exports = someFunc;
    // At this point, the module will now export someFunc, instead of the
    // default object.
  })(module, module.exports);
  return module.exports;
} copy

module.filename

Добавлен в: v0.1.16
  • <строка>

Полное разрешенное имя файла модуля.

module.id

Добавлен в: v0.1.16
  • <строка>

Идентификатор модуля. Обычно это полное разрешенное имя файла.

module.isPreloading

Добавлен в: v15.4.0, v14.17.0
  • Тип: <логическое> true если модуль выполняется во время фазы предварительной загрузки Node.js.

module.loaded

Добавлен в: v0.1.16
  • <логическое>

Загружен ли модуль или находится в процессе загрузки.

module.parent

Добавлен в: v0.1.16Устарело с: v14.6.0, v12.19.0
Стабильность: 0 - Устарело: Используйте require.main и module.children вместо этого.
  • <модуль> | <null> | <undefined>

Модуль, который в первый раз загрузил этот модуль, или null, если текущий модуль является точкой входа текущего процесса, или undefined, если модуль был загружен чем-то, что не является модулем CommonJS (например, REPL или import).

module.path

Добавлен в: v11.14.0
  • <строка>

Имя каталога модуля. Обычно оно совпадает с path.dirname() module.id.

module.paths

Добавлен в: v0.4.0
  • <массив строк>

Пути поиска модуля.

module.require(id)

Добавлен в: v0.5.1
  • id <строка>
  • Возвращает: <любой> экспортированное содержимое модуля

Метод module.require() предоставляет способ загрузки модуля так, как будто require() был вызван из исходного модуля.

Для этого необходимо получить ссылку на объект module. Так как require() возвращает module.exports, а module обычно только доступен внутри кода определенного модуля, его необходимо явно экспортировать, чтобы его можно было использовать.

Объект Module

Этот раздел был перемещен в Модули: module базовый модуль.

  • module.builtinModules
  • module.createRequire(filename)
  • module.syncBuiltinESMExports()

Поддержка Source Map v3

Этот раздел был перемещен в Модули: module базовый модуль.

  • module.findSourceMap(path)
  • Класс: module.SourceMap
    • new SourceMap(payload)
    • sourceMap.payload
    • sourceMap.findEntry(lineNumber, columnNumber)

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v18.x/docs/api/modules.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API