Spec-Zone.ru › Node.js 20 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" или нет package.json в любой родительской папке; за исключением случаев, когда файл содержит синтаксис, приводящий к ошибке, если его оценивать как ES-модуль. Авторы пакетов должны включать поле "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 - Устаревший: Используйте экспорт подпутей или импорт подпутей вместо этого.

Существует три способа, которыми папка может быть передана 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(), не является модулем ядра и не начинается с '/', '../', или './', то 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.js ищет 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, содержащие абсолютный путь к файлу модуля и его директорию.
END_OF_DOCUMENT_MARKER

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

__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, см. в разделе о сокращении 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()

Поддержка карт исходного кода 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-v20.x/docs/api/modules.html

Spec-Zone.ru

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