Внешние зависимости
Параметр конфигурации externals предоставляет способ исключения зависимостей из выходных пакетов. Вместо этого создаваемый пакет полагается на то, что эта зависимость присутствует в среде потребителя (любого приложения-пользователя). Эта функция обычно наиболее полезна для разработчиков библиотек, однако у неё есть множество применений.
внешние зависимости
string object function RegExp [string, object, function, RegExp]
Предотвратить объединение определенных import пакетов и вместо этого извлечь эти внешние зависимости во время выполнения.
Например, чтобы включить jQuery с CDN вместо объединения:
index.html
<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous" ></script>
webpack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery',
},
}; Это оставляет любые зависимые модули неизменными, т.е. приведенный ниже код по-прежнему будет работать:
import $ from 'jquery';
$('.my-element').animate(/* ... */); Имя свойства jquery , указанное в externals в вышеупомянутом webpack.config.js, указывает, что модуль jquery в import $ from 'jquery' должен быть исключён из объединения. Для замены этого модуля будет использовано значение jQuery, для получения глобальной jQuery переменной, так как тип внешней библиотеки по умолчанию — var, см. externalsType.
Хотя мы показали пример использования внешней глобальной переменной выше, внешняя зависимость может быть доступна в любом из этих форматов: глобальная переменная, CommonJS, AMD, ES2015 Module, см. больше в externalsType.
строка
В зависимости от externalsType, это может быть имя глобальной переменной (см. 'global', 'this', 'var', 'window') или имя модуля (см. amd, commonjs, module, umd).
Также можно использовать сокращённый синтаксис, если определена только 1 внешняя зависимость:
module.exports = {
//...
externals: 'jquery',
}; равно
module.exports = {
//...
externals: {
jquery: 'jquery',
},
}; Вы можете указать тип внешней библиотеки внешней библиотеки для внешней зависимости с помощью синтаксиса ${externalsType} ${libraryName}. Он переопределит тип внешней библиотеки по умолчанию, указанный в параметре externalsType.
Например, если внешняя библиотека — модуль CommonJS, вы можете указать
module.exports = {
//...
externals: {
jquery: 'commonjs jquery',
},
}; [строка]
module.exports = {
//...
externals: {
subtract: ['./math', 'subtract'],
},
}; subtract: ['./math', 'subtract'] позволяет выбрать часть модуля, где ./math — это модуль, и ваш пакет требует только подмножества под переменной subtract.
Когда externalsType равно commonjs, этот пример переводится в require('./math').subtract;, а когда externalsType равно window, этот пример переводится в window["./math"]["subtract"];
Аналогично синтаксису строки, вы можете указать тип внешней библиотеки с помощью синтаксиса ${externalsType} ${libraryName}, в первом элементе массива, например:
module.exports = {
//...
externals: {
subtract: ['commonjs ./math', 'subtract'],
},
}; объект
module.exports = {
//...
externals: {
react: 'react',
},
// or
externals: {
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
},
// or
externals: {
subtract: {
root: ['math', 'subtract'],
},
},
}; Этот синтаксис используется для описания всех возможных способов доступности внешней библиотеки. lodash здесь доступен как lodash в системах модулей AMD и CommonJS, но доступен как _ в форме глобальной переменной. subtract здесь доступен через свойство subtract в глобальном объекте math (например, window['math']['subtract']).
функция
function ({ context, request, contextInfo, getResolve }, callback)-
function ({ context, request, contextInfo, getResolve }) => promise5.15.0+
Может быть полезно определить собственную функцию для управления поведением того, что вы хотите внешне экспортировать из webpack. webpack-node-externals, например, исключает все модули из каталога node_modules и предоставляет параметры для разрешения пакетов.
Вот аргументы, которые может получить функция:
-
ctx(object): Объект, содержащий детали файла.-
ctx.context(string): Каталог файла, содержащего импорт. -
ctx.request(string): Запрашиваемый путь импорта. -
ctx.contextInfo(object): Содержит информацию о передатчике (например, слое и компиляторе) -
ctx.getResolve5.15.0+: Получить функцию разрешения с текущими параметрами разрешения.
-
-
callback(function (err, result, type)): Функция обратного вызова, используемая для указания, как модуль должен быть экспортирован.
Функция обратного вызова принимает три аргумента:
-
err(Error): Используется для указания наличия ошибки при экспорте импорта. При возникновении ошибки этот параметр должен быть единственным используемым. -
result(string[string]object): Описывает внешний модуль с другими форматами внешних зависимостей (string,[string]илиobject) -
type(string): Необязательный параметр, указывающий тип внешней зависимости модуля external type (если он не был уже указан в параметреresult).
В качестве примера, чтобы экспортировать все импорты, где путь импорта соответствует регулярному выражению, можно сделать следующее:
webpack.config.js
module.exports = {
//...
externals: [
function ({ context, request }, callback) {
if (/^yourregex$/.test(request)) {
// Externalize to a commonjs module using the request path
return callback(null, 'commonjs ' + request);
}
// Continue without externalizing the import
callback();
},
],
}; Другие примеры с использованием различных форматов модулей:
webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a `commonjs2` module located in `@scope/library`
callback(null, '@scope/library', 'commonjs2');
},
],
}; webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a global variable called `nameOfGlobal`.
callback(null, 'nameOfGlobal');
},
],
}; webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a named export in the `@scope/library` module.
callback(null, ['@scope/library', 'namedexport'], 'commonjs');
},
],
}; webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a UMD module
callback(null, {
root: 'componentsGlobal',
commonjs: '@scope/components',
commonjs2: '@scope/components',
amd: 'components',
});
},
],
}; RegExp
Каждая зависимость, соответствующая заданному регулярному выражению, будет исключена из выходных пакетов.
webpack.config.js
module.exports = {
//...
externals: /^(jquery|\$)$/i,
}; В этом случае любая зависимость с именем jQuery, заглавными или строчными буквами, или $ будет экспортирована.
Комбинирование синтаксисов
Иногда вам может потребоваться использовать комбинацию вышеперечисленных синтаксисов. Это можно сделать следующим образом:
webpack.config.js
module.exports = {
//...
externals: [
{
// String
react: 'react',
// Object
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
// [string]
subtract: ['./math', 'subtract'],
},
// Function
function ({ context, request }, callback) {
if (/^yourregex$/.test(request)) {
return callback(null, 'commonjs ' + request);
}
callback();
},
// Regex
/^(jquery|\$)$/i,
],
}; Для получения дополнительной информации о том, как использовать эту конфигурацию, обратитесь к статье как создать библиотеку.
byLayer
function object
Укажите внешние зависимости по слоям.
webpack.config.js
module.exports = {
externals: {
byLayer: {
layer: {
external1: 'var 43',
},
},
},
}; externalsType
string = 'var'
Укажите тип внешних зависимостей по умолчанию. amd, umd, system и jsonp внешние зависимости зависит от output.libraryTarget, установленного в то же значение, т.е. вы можете использовать amd внешние зависимости только в библиотеке amd.
Поддерживаемые типы:
'amd''amd-require'-
'assign'- то же, что и'var' 'commonjs''commonjs-module''global'-
'import'- используетimport()для загрузки модуля EcmaScript (асинхронный модуль) 'jsonp''module''import''module-import''node-commonjs'-
'promise'- то же, что и'var', но ожидает результата (асинхронный модуль) 'self''system''script''this''umd''umd2''var''window'
webpack.config.js
module.exports = {
//...
externalsType: 'promise',
}; externalsType.commonjs
Укажите тип внешних зависимостей по умолчанию как 'commonjs'. Webpack сгенерирует код вроде const X = require('...') для внешних зависимостей, используемых в модуле.
Пример
import fs from 'fs-extra';
webpack.config.js
module.exports = {
// ...
externalsType: 'commonjs',
externals: {
'fs-extra': 'fs-extra',
},
}; Сгенерирует что-то вроде:
const fs = require('fs-extra'); Обратите внимание, что в выходном пакете будет require().
externalsType.global
Укажите тип внешних зависимостей по умолчанию как 'global'. Webpack будет читать внешнюю зависимость как глобальную переменную в globalObject.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'global',
externals: {
jquery: '$',
},
output: {
globalObject: 'global',
},
}; Сгенерирует что-то вроде
const jq = global['$'];
jq('.my-element').animate(/* ... */); externalsType.module
Укажите тип внешних зависимостей по умолчанию как 'module'. Webpack сгенерирует код вроде import * as X from '...' для внешних зависимостей, используемых в модуле.
Убедитесь, что вы сначала включили experiments.outputModule, иначе webpack выдаст ошибки.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
experiments: {
outputModule: true,
},
externalsType: 'module',
externals: {
jquery: 'jquery',
},
}; Сгенерирует что-то вроде
import * as __WEBPACK_EXTERNAL_MODULE_jquery__ from 'jquery';
const jq = __WEBPACK_EXTERNAL_MODULE_jquery__['default'];
jq('.my-element').animate(/* ... */); Обратите внимание, что в выходном пакете будет инструкция import.
externalsType.import
5.94.0+Укажите тип внешних зависимостей по умолчанию как 'import'. Webpack сгенерирует код вроде import('...') для внешних зависимостей, используемых в модуле.
Пример
async function foo() {
const jq = await import('jQuery');
jq('.my-element').animate(/* ... */);
} webpack.config.js
module.exports = {
externalsType: 'import',
externals: {
jquery: 'jquery',
},
}; Сгенерирует что-то вроде нижеследующего:
var __webpack_modules__ = {
jQuery: (module) => {
module.exports = import('jQuery');
},
};
// webpack runtime...
async function foo() {
const jq = await Promise.resolve(/* import() */).then(
__webpack_require__.bind(__webpack_require__, 'jQuery')
);
jq('.my-element').animate(/* ... */);
} Обратите внимание, что выходной пакет будет содержать инструкцию import().
externalsType.module-import
5.94.0+Укажите тип внешних зависимостей по умолчанию как 'module-import'. Это объединяет 'module' и 'import'. Webpack автоматически определит тип синтаксиса импорта, установив его в 'module' для статических импортов и 'import' для динамических импортов.
Убедитесь, что вы сначала включили experiments.outputModule, если существуют статические импорты, в противном случае webpack выдаст ошибки.
Пример
import { attempt } from 'lodash';
async function foo() {
const jq = await import('jQuery');
attempt(() => jq('.my-element').animate(/* ... */));
} webpack.config.js
module.exports = {
externalsType: 'import',
externals: {
jquery: 'jquery',
},
}; Сгенерирует что-то вроде следующего:
import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from 'lodash';
const lodash = __WEBPACK_EXTERNAL_MODULE_jquery__;
var __webpack_modules__ = {
jQuery: (module) => {
module.exports = import('jQuery');
},
};
// webpack runtime...
async function foo() {
const jq = await Promise.resolve(/* import() */).then(
__webpack_require__.bind(__webpack_require__, 'jQuery')
);
(0, lodash.attempt)(() => jq('.my-element').animate(/* ... */));
} Обратите внимание, что выходной пакет будет содержать оператор import или import().
Когда модуль не импортирован с помощью import или import(), webpack будет использовать тип "module" externals в качестве резервного варианта. Если вы хотите использовать другой тип externals в качестве резервного, вы можете указать его с помощью функции в опции externals. Например:
module.exports = {
externalsType: "module-import",
externals: [
function (
{ request, dependencyType },
callback
) {
if (dependencyType === "commonjs") {
return callback(null, `node-commonjs ${request}`);
}
callback();
},
] externalsType.node-commonjs
Укажите тип externals по умолчанию как 'node-commonjs'. Webpack импортирует createRequire из 'module', чтобы создать функцию require для загрузки внешних зависимостей, используемых в модуле.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.export = {
experiments: {
outputModule: true,
},
externalsType: 'node-commonjs',
externals: {
jquery: 'jquery',
},
}; Будет сгенерировано что-то вроде
import { createRequire } from 'module';
const jq = createRequire(import.meta.url)('jquery');
jq('.my-element').animate(/* ... */); Обратите внимание, что в выходном пакете будет оператор import.
Это полезно, когда зависимости полагаются на встроенные модули Node.js или требуют функцию require типа CommonJS для сохранения прототипов, что необходимо для функций, таких как util.inherits. Подробнее см. данный вопрос.
Для кода, который полагается на структуры прототипов, такие как:
function ChunkStream() {
Stream.call(this);
}
util.inherits(ChunkStream, Stream); Вы можете использовать node-commonjs для обеспечения сохранения цепочки прототипов:
const { builtinModules } = require('module');
module.exports = {
experiments: { outputModule: true },
externalsType: 'node-commonjs',
externals: ({ request }, callback) => {
if (/^node:/.test(request) || builtinModules.includes(request)) {
return callback(null, 'node-commonjs ' + request);
}
callback();
},
}; Это приводит к результату примерно такого вида:
import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "node:module";
// ...
/***/ 2613:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("stream");
/***/ }), Эта настройка сохраняет структуру прототипов, устраняя проблемы со встроенными модулями Node.js.
externalsType.promise
Укажите тип externals по умолчанию как 'promise'. Webpack прочитает внешнюю зависимость как глобальную переменную (аналогично 'var') и await её.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'promise',
externals: {
jquery: '$',
},
}; Будет сгенерировано что-то вроде
const jq = await $;
jq('.my-element').animate(/* ... */); externalsType.self
Укажите тип externals по умолчанию как 'self'. Webpack прочитает внешнюю зависимость как глобальную переменную объекта self.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'self',
externals: {
jquery: '$',
},
}; Будет сгенерировано что-то вроде
const jq = self['$'];
jq('.my-element').animate(/* ... */); externalsType.script
Укажите тип externals по умолчанию как 'script'. Webpack загрузит внешнюю зависимость как скрипт, экспонирующий предварительно определённые глобальные переменные с помощью HTML-элемента <script>. Тег <script> будет удалён после загрузки скрипта.
Синтаксис
module.exports = {
externalsType: 'script',
externals: {
packageName: [
'http://example.com/script.js',
'global',
'property',
'property',
], // properties are optional
},
}; Вы также можете использовать сокращённый синтаксис, если не собираетесь указывать какие-либо свойства:
module.exports = {
externalsType: 'script',
externals: {
packageName: 'global@http://example.com/script.js', // no properties here
},
}; Обратите внимание, что output.publicPath не будет добавлен к предоставленному URL.
Пример
Загрузим lodash с CDN:
webpack.config.js
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: ['https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js', '_'],
},
}; Затем используем его в коде:
import _ from 'lodash'; console.log(_.head([1, 2, 3]));
Вот как мы задаём свойства для вышеприведённого примера:
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: [
'https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js',
'_',
'head',
],
},
}; Обе локальные переменные head и глобальные window._ будут экспортированы, когда вы import lodash.
import head from 'lodash'; console.log(head([1, 2, 3])); // logs 1 here console.log(window._.head(['a', 'b'])); // logs a here
externalsType.this
Укажите тип externals по умолчанию как 'this'. Webpack прочитает внешнюю зависимость как глобальную переменную объекта this.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'this',
externals: {
jquery: '$',
},
}; Будет сгенерировано что-то вроде
const jq = this['$'];
jq('.my-element').animate(/* ... */); externalsType.var
Укажите тип externals по умолчанию как 'var'. Webpack прочитает внешнюю зависимость как глобальную переменную.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'var',
externals: {
jquery: '$',
},
}; Будет сгенерировано что-то вроде
const jq = $;
jq('.my-element').animate(/* ... */); externalsType.window
Укажите тип externals по умолчанию как 'window'. Webpack прочитает внешнюю зависимость как глобальную переменную объекта window.
Пример
import jq from 'jquery';
jq('.my-element').animate(/* ... */); webpack.config.js
module.exports = {
// ...
externalsType: 'window',
externals: {
jquery: '$',
},
}; Будет сгенерировано что-то вроде
const jq = window['$'];
jq('.my-element').animate(/* ... */); externalsPresets
object
Включить наборы предварительных настроек для внешних зависимостей для определённых целей.
| Опция | Описание | Тип ввода |
|---|---|---|
electron |
Обрабатывает распространённые встроенные модули электронных приложений в контекстах main и preload, такие как electron, ipc или shell, как внешние зависимости и загружает их с помощью require() при использовании. |
boolean |
electronMain |
Обрабатывает встроенные модули электронных приложений в контексте main, такие как app, ipc-main или shell, как внешние зависимости и загружает их с помощью require() при использовании. |
boolean |
electronPreload |
Обрабатывает встроенные модули электронных приложений в контексте preload, такие как web-frame, ipc-renderer или shell, как внешние зависимости и загружает их с помощью require() при использовании. |
boolean |
electronRenderer |
Обрабатывает встроенные модули электронных приложений в контексте renderer, такие как web-frame, ipc-renderer или shell, как внешние зависимости и загружает их с помощью require() при использовании. |
boolean |
node |
Обрабатывает встроенные модули node.js, такие как fs, path или vm, как внешние зависимости и загружает их с помощью require() при использовании. |
boolean |
nwjs |
Обрабатывает устаревший модуль NW.js nw.gui как внешнюю зависимость и загружает его с помощью require() при использовании. |
boolean |
web |
Обрабатывает ссылки на http(s)://... и std:... как внешние зависимости и загружает их с помощью import при использовании. (Обратите внимание, что это меняет порядок выполнения, так как внешние зависимости выполняются до любого другого кода в фрагменте). |
boolean |
webAsync |
Обрабатывает ссылки на http(s)://... и std:... как внешние зависимости и загружает их с помощью async import() при использовании. (Обратите внимание, что этот тип внешней зависимости — это модуль async, который оказывает различное влияние на выполнение). |
boolean |
Обратите внимание, что если вы собираетесь выводить ES Модули с этими наборами предварительных настроек, связанных с node.js, webpack установит тип externals по умолчанию в node-commonjs, который будет использовать createRequire для построения функции require вместо require().
Пример
Использование набора предварительных настроек node не будет включать встроенные модули, обрабатывает их как внешние зависимости и загружает их с помощью require() при использовании.
webpack.config.js
module.exports = {
// ...
externalsPresets: {
node: true,
},
};
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/configuration/externals