Spec-Zone.ru › webpack 5

Методы модулей

Этот раздел описывает все методы, доступные в коде, скомпилированном с помощью webpack. При использовании webpack для сборки вашего приложения, вы можете выбрать различные стили синтаксиса модулей, включая ES6, CommonJS и AMD.

Хотя webpack поддерживает несколько синтаксисов модулей, мы рекомендуем использовать единый синтаксис для согласованности и избегания странного поведения/ошибок. Фактически, webpack будет применять это рекомендацию к .mjs файлам, .cjs файлам или .js файлам, когда ближайший родительский package.json файл содержит поле "type" со значением "module" или "commonjs". Обратите внимание на эти требования, прежде чем продолжать:

  • .mjs или .js с "type": "module" в package.json
    • Запрещено использование CommonJS, например, вы не можете использовать require, module.exports или exports.
    • Требуются расширения файлов при импорте, например, вы должны использовать import './src/App.mjs' вместо import './src/App' (вы можете отключить это требование с помощью Rule.resolve.fullySpecified)
  • .cjs или .js с "type": "commonjs" в package.json
    • Ни import, ни export недоступны
  • .wasm с "type": "module" в package.json
    • При импорте файлов wasm необходимы расширения файлов

ES6 (Рекомендуется)

Версия 2 webpack поддерживает синтаксис модулей ES6 по умолчанию, что означает, что вы можете использовать import и export без инструмента, такого как babel, для его обработки. Имейте в виду, что вам, вероятно, всё ещё понадобится babel для других функций ES6+. Следующие методы поддерживаются webpack:

import

Статически import export другого модуля.

import MyModule from './my-module.js';
import { NamedExport } from './other-module.js';
Предупреждение

Ключевое слово здесь — статически. Обычное import выражение не может использоваться динамически в других логических операциях или содержать переменные. Для получения дополнительной информации обратитесь к спецификации, а также к разделу import() для динамического использования.

Также вы можете import Data URI:

import 'data:text/javascript;charset=utf-8;base64,Y29uc29sZS5sb2coJ2lubGluZSAxJyk7';
import {
  number,
  fn,
} from 'data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgY29uc3QgZm4gPSAoKSA9PiAiSGVsbG8gd29ybGQiOw==';

export

Экспортируйте что угодно в виде default или именованного экспорта.

// Named exports
export var Count = 5;
export function Multiply(a, b) {
  return a * b;
}

// Default export
export default {
  // Some data...
};

import()

function(string path):Promise

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

Подсказка

Спецификация загрузчика ES2015 Loader определяет import() как метод динамической загрузки модулей ES2015 во время выполнения.

if (module.hot) {
  import('lodash').then((_) => {
    // Do something with lodash (a.k.a '_')...
  });
}
Предупреждение

Эта функция опирается на Promise внутри. Если вы используете import() с устаревшими браузерами, не забудьте имплементировать Promise с помощью полифилла, например, es6-promise или promise-polyfill.

Динамические выражения в import()

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

import() должен содержать хотя бы некоторую информацию о местоположении модуля. Сборка может быть ограничена определенным каталогом или набором файлов, чтобы когда вы используете динамическое выражение — каждый потенциально запрашиваемый модуль в вызове import() включался. Например, import(`./locale/${language}.json`) вызовет сборку каждого .json файла в каталоге ./locale в новый фрагмент. Во время выполнения, когда переменная language вычислена, любой файл, такой как english.json или german.json, будет доступен для использования.

// imagine we had a method to get language from cookies or other storage
const language = detectVisitorLanguage();
import(`./locale/${language}.json`).then((module) => {
  // do something with the translations
});
Подсказка

Использование опций webpackInclude и webpackExclude позволяет вам добавить шаблоны регулярных выражений, которые сократят количество файлов, которые webpack будет собирать для этого импорта.

Магические комментарии

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

// Single target
import(
  /* webpackChunkName: "my-chunk-name" */
  /* webpackMode: "lazy" */
  /* webpackExports: ["default", "named"] */
  /* webpackFetchPriority: "high" */
  'module'
);

// Multiple possible targets
import(
  /* webpackInclude: /\.json$/ */
  /* webpackExclude: /\.noimport\.json$/ */
  /* webpackChunkName: "my-chunk-name" */
  /* webpackMode: "lazy" */
  /* webpackPrefetch: true */
  /* webpackPreload: true */
  `./locale/${language}`
);

import(/* webpackIgnore: true */ 'ignored-module.js');
webpackIgnore

Использование JavaScript

Отключает разбор динамического импорта, если установлено значение true.

При использовании import.meta.url, оно не остаётся неизменным; вместо этого оно заменяется в зависимости от baseURI. Для модулей оно заменяется на new URL("./", import.meta.url), а для других случаев по умолчанию document.baseURI. Это гарантирует, что относительные URL-адреса работают правильно, в соответствии с контекстом базового URL.

import(/* webpackIgnore: true */ 'ignored-module.js');

new URL(/* webpackIgnore: true */ 'file1.css', import.meta.url);
Предупреждение

Обратите внимание, что установка webpackIgnore в true отключает разделение кода.

Использование CSS

Комментарий webpackIgnore может управлять тем, обрабатывает ли webpack определённый импорт или ссылку на URL. Он работает в определённых случаях «из коробки», но не поддерживает все случаи по умолчанию из-за соображений производительности.

Мы поддерживаем webpackIgnore в следующих случаях:

@import /* webpackIgnore: false */ url(./basic.css);

.class {
  color: red;
  background: /* webpackIgnore: true */ url('./url/img.png');
}

.class {
  background-image: image-set(
    /*webpackIgnore:  true*/ url(./url/img1x.png) 1x,
    url(./url/img2x.png) 2x,
    url(./url/img3x.png) 3x
  );
}
Подсказка

Для других сценариев с CSS, css-loader полностью поддерживает webpackIgnore, что обеспечивает большую гибкость при необходимости.

webpackChunkName

Имя нового фрагмента. Начиная с webpack 2.6.0, в данной строке поддерживаются плейсхолдеры [index] и [request], соответственно, для увеличенного числа или фактического разрешенного имени файла. Добавление этого комментария приведет к тому, что наш отдельный фрагмент будет называться [my-chunk-name].js вместо [id].js.

webpackFetchPriority
5.87.0+

Установите fetchPriority для конкретных динамических импортов. Также возможно установить глобальное значение по умолчанию для всех динамических импортов с помощью опции module.parser.javascript.dynamicImportFetchPriority.

import(
  /* webpackFetchPriority: "high" */
  'path/to/module'
);
webpackMode

Начиная с webpack 2.6.0, можно указать различные режимы разрешения динамических импортов. Поддерживаются следующие варианты:

  • 'lazy' (по умолчанию): Создаёт фрагмент для ленивой загрузки для каждого import() модуля.
  • 'lazy-once': Создаёт один фрагмент для ленивой загрузки, который может удовлетворить все вызовы import(). Фрагмент будет загружен при первом вызове import(), а последующие вызовы import() будут использовать тот же ответ сети. Имейте в виду, что это имеет смысл только в случае частично динамического выражения, например, import(`./locales/${language}.json`), где могут быть запрошены несколько путей модулей.
  • 'eager': Не создаёт дополнительных фрагментов. Все модули включаются в текущий фрагмент, и дополнительные запросы к сети не выполняются. Promise всё ещё возвращается, но уже разрешён. В отличие от статического импорта, модуль не выполняется до вызова import().
  • 'weak': Попытается загрузить модуль, если функция модуля уже загружена каким-либо другим способом (например, другой фрагмент импортировал её или скрипт, содержащий модуль, был загружен). Promise всё ещё возвращается, но успешно разрешается только если фрагменты уже на клиенте. Если модуль недоступен, Promise отклоняется. Запрос к сети никогда не будет выполнен. Это полезно для универсального рендеринга, когда необходимые фрагменты всегда вручную предоставляются в начальных запросах (встроены в страницу), но не в случаях, когда навигация по приложению вызовет импорт, который изначально не был предоставлен.
webpackPrefetch

Сообщает браузеру, что ресурс, вероятно, потребуется для какой-то навигации в будущем. Более подробную информацию о том, как работает webpackPrefetch, можно найти в руководстве.

webpackPreload

Сообщает браузеру, что ресурс может потребоваться во время текущей навигации. Более подробную информацию о том, как работает webpackPreload, можно найти в руководстве.

Подсказка

Обратите внимание, что все опции могут быть объединены, как показано в /* webpackMode: "lazy-once", webpackChunkName: "all-i18n-data" */ . Это упаковано в JavaScript-объект и выполняется с помощью node VM. Вам не нужно добавлять фигурные скобки.

webpackInclude

Регулярное выражение, которое будет сопоставляться во время разрешения импорта. Только модули, которые соответствуют этому выражению, будут включены в сборку.

webpackExclude

Регулярное выражение, которое будет сопоставляться во время разрешения импорта. Любой модуль, соответствующий этому выражению, не будет включён в сборку.

Подсказка

Обратите внимание, что опции webpackInclude и webpackExclude не влияют на префикс. Например: ./locale.

webpackExports

Сообщает webpack собирать только указанные экспорты динамически import() модуля. Это может уменьшить размер выходного фрагмента. Доступно начиная с webpack 5.0.0-beta.18.

Предупреждение

webpackExports нельзя использовать с операциями присваивания с деструктуризацией.

CommonJS

Цель CommonJS — определить экосистему для JavaScript вне браузера. Следующие методы CommonJS поддерживаются webpack:

require

require(dependency: String);

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

var $ = require('jquery');
var myModule = require('my-module');

Для require можно включить магические комментарии, см. module.parser.javascript.commonjsMagicComments для более подробной информации.

Предупреждение

Асинхронное использование может не иметь ожидаемого эффекта.

require.resolve

require.resolve(dependency: String);

Синхронно извлекает идентификатор модуля. Компилятор гарантирует, что зависимость доступна в выходной сборке. Рекомендуется рассматривать его как непрозрачное значение, которое можно использовать только с require.cache[id] или __webpack_require__(id) (лучше избегать такого использования).

предупреждение

Тип идентификатора модуля может быть number или string в зависимости от конфигурации optimization.moduleIds.

Для получения дополнительной информации см. module.id.

require.cache

Несколько require для одного и того же модуля приводят к выполнению модуля только один раз и к экспорту только одного результата. Поэтому в среде выполнения существует кэш. Удаление значений из этого кэша вызывает новое выполнение модуля и новый экспорт.

предупреждение

Это необходимо только в редких случаях для совместимости!

var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;
// in file.js
require.cache[module.id] === module;
require('./file.js') === module.exports;
delete require.cache[module.id];
require.cache[module.id] === undefined;
require('./file.js') !== module.exports; // in theory; in praxis this causes a stack overflow
require.cache[module.id] !== module;

require.ensure

предупреждение

require.ensure() специфично для webpack и устарело, заменено на import().

require.ensure(
  dependencies: String[],
  callback: function(require),
  errorCallback: function(error),
  chunkName: String
)

Выделение заданных dependencies в отдельный пакет, который будет загружен асинхронно. При использовании синтаксиса модулей CommonJS это единственный способ динамической загрузки зависимостей. Это означает, что этот код может быть запущен во время выполнения, загружая dependencies только при определённых условиях.

предупреждение

Эта функция использует Promise внутри. Если вы используете require.ensure с более старыми браузерами, помните о необходимости подмены Promise с помощью полифилла, такого как es6-promise или promise-polyfill.

var a = require('normal-dep');

if (module.hot) {
  require.ensure(['b'], function (require) {
    var c = require('c');

    // Do something special...
  });
}

Ниже перечислены поддерживаемые параметры в указанном порядке:

  • dependencies: Массив строк, объявляющих все модули, необходимые для выполнения кода в callback.
  • callback: Функция, которую webpack выполнит после загрузки зависимостей. Реализация функции require передаётся в качестве параметра в эту функцию. Функция может использовать это для дальнейшей require() необходимых модулей для выполнения.
  • errorCallback: Функция, которая выполняется, когда webpack не удаётся загрузить зависимости.
  • chunkName: Имя, заданное для пакета, созданного этим конкретным require.ensure(). Передавая то же chunkName различным вызовам require.ensure(), мы можем объединить их код в один пакет, что приведет к одному файлу, который должен загрузить браузер.
предупреждение

Несмотря на то, что реализация require передаётся как аргумент функции callback, использование произвольного имени, например, require.ensure([], function(request) { request('someModule'); }), не обрабатывается статическим анализатором webpack. Используйте require вместо этого, например, require.ensure([], function(require) { require('someModule'); }).

AMD

Asynchronous Module Definition (AMD) — это спецификация JavaScript, определяющая интерфейс для написания и загрузки модулей. Webpack поддерживает следующие методы AMD:

define (с фабрикой)

define([name: String], [dependencies: String[]], factoryMethod: function(...))

Если dependencies предоставлены, factoryMethod будет вызвана с экспортами каждой зависимости (в том же порядке). Если dependencies не предоставлены, factoryMethod вызывается с require, exports и module (для совместимости!). Если эта функция возвращает значение, это значение экспортируется модулем. Компилятор гарантирует, что каждая зависимость доступна.

предупреждение

Обратите внимание, что webpack игнорирует аргумент name.

define(['jquery', 'my-module'], function ($, myModule) {
  // Do something with $ and myModule...

  // Export a function
  return function doSomething() {
    // ...
  };
});
предупреждение

Это НЕ может использоваться в асинхронной функции.

define (со значением)

define(value: !Function)

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

define({
  answer: 42,
});
предупреждение

Это НЕ может использоваться в асинхронной функции.

require (amd-версия)

require(dependencies: String[], [callback: function(...)])

Подобно require.ensure, это выделит заданные dependencies в отдельный пакет, который будет загружен асинхронно. callback будет вызвана с экспортами каждой зависимости в массиве dependencies.

предупреждение

Эта функция использует Promise внутри. Если вы используете AMD в старых браузерах (например, Internet Explorer 11), помните о необходимости подмены Promise с помощью полифилла, такого как es6-promise или promise-polyfill.

require(['b'], function (b) {
  var c = require('c');
});
предупреждение

Нет возможности указать имя пакета.

Меченные модули

Внутренний LabeledModulesPlugin позволяет использовать следующие методы для экспорта и импорта внутри ваших модулей:

экспорт метки

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

export: var answer = 42;
export: function method(value) {
  // Do something...
};
предупреждение

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

импорт метки

Сделать доступными все экспорты из зависимости в текущем объёме. Метка require может встречаться перед строкой. Зависимость должна экспортировать значения с меткой export. Модули CommonJS или AMD нельзя использовать.

some-dependency.js

export: var answer = 42;
export: function method(value) {
  // Do something...
};
require: 'some-dependency';
console.log(answer);
method(...);

Webpack

Помимо описанных выше синтаксисов модулей, webpack также позволяет использовать несколько пользовательских, специфичных для webpack методов:

require.context

require.context(
  (directory: String),
  (includeSubdirs: Boolean) /* optional, default true */,
  (filter: RegExp) /* optional, default /^\.\/.*$/, any file */,
  (mode: String) /* optional, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once', default 'sync' */
);

Укажите целую группу зависимостей, используя путь к directory, опцию для includeSubdirs, filter для более тонкого контроля включённых модулей и mode для определения того, как будет происходить загрузка. Подлежащие модули могут быть разрешены позже:

var context = require.context('components', true, /\.html$/);
var componentA = context.resolve('componentA');

Если mode установлено в 'lazy', подлежащие модули будут загружены асинхронно:

var context = require.context('locales', true, /\.json$/, 'lazy');
context('localeA').then((locale) => {
  // do something with locale
});

Полный список доступных режимов и их поведение описан в import() документации.

require.include

require.include((dependency: String));

Включить dependency без его выполнения. Это может использоваться для оптимизации положения модуля в выходных пакетах.

require.include('a');
require.ensure(['a', 'b'], function (require) {
  /* ... */
});
require.ensure(['a', 'c'], function (require) {
  /* ... */
});

Это приведёт к следующему выводу:

  • пакет-вход: file.js и a
  • анонимный пакет: b
  • анонимный пакет: c

Без require.include('a') он был бы дублирован в обоих анонимных пакетах.

require.resolveWeak

Аналогично require.resolve, но это не добавит module в пакет. Это то, что считается "слабой" зависимостью.

if (__webpack_modules__[require.resolveWeak('module')]) {
  // Do something when module is available...
}
if (require.cache[require.resolveWeak('module')]) {
  // Do something when module was loaded before...
}

// You can perform dynamic resolves ("context")
// similarly to other require/import methods.
const page = 'Foo';
__webpack_modules__[require.resolveWeak(`./page/${page}`)];
подсказка

require.resolveWeak является основой для универсального рендеринга (SSR + разделение кода), как используется в таких пакетах, как react-universal-component. Это позволяет коду отображаться синхронно как на сервере, так и при первоначальной загрузке на клиенте. Требуется, чтобы пакеты загружались вручную или были каким-то образом доступны. Он способен загружать модули без указания их включения в пакет. Используется в сочетании с import() , который берет на себя управление, когда навигация пользователя вызывает дополнительные импорты.

предупреждение

Если исходный код модуля содержит require, который нельзя статически проанализировать, выводится предупреждение о критически важных зависимостях.

Пример кода:

someFn(require);
require.bind(null);
require(variable);

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/api/module-methods

Spec-Zone.ru

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