Spec-Zone.ru › Node.js 8 LTS

Модули ECMAScript

Устойчивость: 1 - Экспериментальная

Node.js содержит поддержку модулей ES на основе Node.js EP для модулей ES.

Не все функции EP завершены и будут реализованы по мере готовности поддержки VM и реализации. Сообщения об ошибках всё ещё дорабатываются.

Включение

Флаг --experimental-modules может быть использован для включения функций загрузки модулей ESM.

После его установки файлы с расширением .mjs смогут загружаться как модули ES.

node --experimental-modules my-app.mjs

Функциональные возможности

Поддерживаемые

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

Неподдерживаемые

Функция Причина
require('./foo.mjs') Модули ES имеют разные правила разрешения и синхронизации, используйте стандарт языка import()
import() ожидается выпуск новой версии V8, используемой в Node.js
import.meta ожидается реализация в V8

Существенные различия между import и require

Отсутствует NODE_PATH

NODE_PATH не входит в процесс разрешения import спецификаторов. Пожалуйста, используйте символические ссылки, если такое поведение необходимо.

Отсутствует require.extensions

require.extensions не используется import. Ожидается, что в будущем для этого потока работы будут доступны хуки загрузчика.

Отсутствует require.cache

require.cache не используется import. Он имеет отдельный кэш.

Пути, основанные на URL

Модули ESM разрешаются и кэшируются на основе семантики URL. Это означает, что файлы, содержащие специальные символы, такие как # и ? должны быть экранированы.

Модули будут загружаться несколько раз, если спецификатор import , используемый для их разрешения, имеет разные параметры запроса или фрагмента.

import './foo?query=1'; // loads ./foo with query of "?query=1"
import './foo?query=2'; // loads ./foo with query of "?query=2"

Пока загружаться могут только модули, использующие протокол file:.

Взаимодействие с существующими модулями

Все модули CommonJS, JSON и C++ могут использоваться с import.

Загруженные таким образом модули будут загружены только один раз, даже если их строка запроса или фрагмента отличается между import операторами.

При загрузке через import эти модули предоставят единственный экспорт default , представляющий значение module.exports на момент завершения их вычисления.

import fs from 'fs';
fs.readFile('./foo.txt', (err, body) => {
  if (err) {
    console.error(err);
  } else {
    console.log(body);
  }
});

Хуки загрузчика

Для настройки стандартного разрешения модулей можно предоставить хуки загрузчика через аргумент --loader ./loader-name.mjs для Node.

При использовании хуков они применяются только к загрузке модулей ES, а не к модулям CommonJS.

Хук разрешения

Хук разрешения возвращает разрешенный URL файла и формат модуля для заданного спецификатора модуля и родительского URL файла:

import url from 'url';

export async function resolve(specifier, parentModuleURL, defaultResolver) {
  return {
    url: new URL(specifier, parentModuleURL).href,
    format: 'esm'
  };
}

Функция стандартного разрешения модулей NodeJS предоставляется в качестве третьего аргумента для разрешителя, для обеспечения простоты взаимодействия совместимости.

Помимо возвращаемого разрешенного URL файла, хук разрешения также возвращает свойство format , указывающее формат модуля разрешенного модуля. Это может быть одно из следующих:

format Описание
'esm' Загрузить стандартный JavaScript модуль
'commonjs' Загрузить модуль CommonJS в стиле Node
'builtin' Загрузить встроенный модуль CommonJS Node
'json' Загрузить файл JSON
'addon' Загрузить C++ плагин
'dynamic' Использовать динамический хук инициализации

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

import url from 'url';
import path from 'path';
import process from 'process';
import Module from 'module';

const builtins = Module.builtinModules;
const JS_EXTENSIONS = new Set(['.js', '.mjs']);

export function resolve(specifier, parentModuleURL/*, defaultResolve */) {
  if (builtins.includes(specifier)) {
    return {
      url: specifier,
      format: 'builtin'
    };
  }
  if (/^\.{0,2}[/]/.test(specifier) !== true && !specifier.startsWith('file:')) {
    // For node_modules support:
    // return defaultResolve(specifier, parentModuleURL);
    throw new Error(
      `imports must begin with '/', './', or '../'; '${specifier}' does not`);
  }
  const resolved = new url.URL(specifier, parentModuleURL);
  const ext = path.extname(resolved.pathname);
  if (!JS_EXTENSIONS.has(ext)) {
    throw new Error(
      `Cannot load file with non-JavaScript file extension ${ext}.`);
  }
  return {
    url: resolved.href,
    format: 'esm'
  };
}

С этим загрузчиком выполнение:

NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.js

загрузит модуль x.js как модуль ES с поддержкой относительного разрешения (с пропуском загрузки node_modules в данном примере).

Динамический хук инициализации

Для создания пользовательского динамического модуля, который не соответствует одному из существующих format интерпретаций, можно использовать хук dynamicInstantiate. Этот хук вызывается только для модулей, возвращающих format: 'dynamic' из хука resolve.

export async function dynamicInstantiate(url) {
  return {
    exports: ['customExportName'],
    execute: (exports) => {
      // get and set functions provided for pre-allocated export names
      exports.customExportName.set('value');
    }
  };
}

С предопределённым списком экспортов модуля, функция execute затем будет вызвана в точности в момент вычисления модуля в порядке импорта для этого модуля в дереве импорта.

© 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-v8.x/docs/api/esm.html

Spec-Zone.ru

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