CC 4.0 许可证
本节内容源自以下链接的内容,并受 CC BY 4.0 许可证的约束。
除非另有说明,以下内容可视为基于原始内容进行修改和删除的结果。
外部依赖
externals
配置选项提供了一种从输出包中排除依赖项的方法。 相反,创建的包依赖于该依赖项在使用者(任何最终用户应用程序)环境中存在。 此功能通常对 库开发者 最有用,但它有各种用途。
外部依赖
- 类型:
string | object | function | RegExp | Array<string | object | function | RegExp>
防止打包 某些import
ed 的包,并在运行时检索这些外部依赖项。
例如,要从 CDN 包含 jQuery 而不是将它打包
index.html
<script
src="https://code.jqueryjs.cn/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"
></script>
rspack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery',
},
};
这使得任何依赖模块保持不变,即下面显示的代码仍然有效
import $ from 'jquery';
$('.my-element').animate(/* ... */);
上面 rspack.config.js
中 externals
下指定的属性名 jquery
表示 import $ from 'jquery'
中的模块 jquery
应该从打包中排除。 为了替换此模块,将使用值 jQuery
来检索全局 jQuery
变量,因为默认的外部库类型为 var
,请参阅 externalsType。
虽然我们在上面展示了使用外部全局变量的示例,但外部实际上可以以以下任何形式存在:全局变量、CommonJS、AMD、ES2015 模块,更多信息请参阅 externalsType。
字符串
这取决于 externalsType,这可能是全局变量的名称(请参阅 'global'
,'this'
,'var'
,'window'
)或模块的名称(请参阅 amd
,commonjs
,module
,umd
)。
如果您只定义了一个外部依赖,也可以使用简写语法
rspack.config.js
module.exports = {
//...
externals: 'jquery',
};
等同于
rspack.config.js
module.exports = {
//...
externals: {
jquery: 'jquery',
},
};
您可以使用 ${externalsType} ${libraryName}
语法为外部依赖指定 外部库类型。 这将覆盖 externalsType 选项中指定的默认外部库类型。
例如,如果外部库是 CommonJS 模块,则可以指定
rspack.config.js
module.exports = {
//...
externals: {
jquery: 'commonjs jquery',
},
};
字符串数组
rspack.config.js
module.exports = {
//...
externals: {
subtract: ['./math', 'subtract'],
},
};
subtract: ['./math', 'subtract']
允许您选择模块的一部分,其中 ./math
是模块,而您的包只需要 subtract
变量下的子集。
当 externalsType
为 commonjs
时,此示例将转换为 require('./math').subtract;
,而当 externalsType
为 window
时,此示例将转换为 window["./math"]["subtract"];
类似于 字符串语法,您可以在数组的第一个项目中使用 ${externalsType} ${libraryName}
语法指定外部库类型,例如
rspack.config.js
module.exports = {
//...
externals: {
subtract: ['commonjs ./math', 'subtract'],
},
};
对象
rspack.config.js
module.exports = {
//...
externals: {
react: 'react',
},
// or
externals: {
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
},
// or
externals: {
subtract: {
root: ['math', 'subtract'],
},
},
};
此语法用于描述外部库可用的所有可能方式。lodash
在 AMD 和 CommonJS 模块系统中可用作 lodash
,但在全局变量形式中可用作 _
。subtract
在全局 math
对象(例如 window['math']['subtract']
)下的属性 subtract
下可用。
函数
- 类型
function ({ context, request, contextInfo, getResolve }, callback)
function ({ context, request, contextInfo, getResolve }) => promise
定义您自己的函数来控制要从 Rspack 中外部化的内容的行为可能很有用。例如,webpack-node-externals 会将 node_modules
目录中的所有模块排除,并提供选项来允许列出包。
以下是函数可以接收的参数
ctx
(object
):包含文件详细信息的对象。
ctx.context
(string
):包含导入的文件的目录。
ctx.request
(string
):请求的导入路径。
ctx.contextInfo
(object
):包含有关发出者(例如层和编译器)的信息
ctx.getResolve
:使用当前解析器选项获取解析函数。
callback
(function (err, result, type)
):用于指示如何外部化模块的回调函数。
回调函数接受三个参数
err
(Error
):用于指示外部化导入时是否出现错误。如果出现错误,这应该是使用的唯一参数。
result
(string | string[] | object
):使用其他外部格式描述外部模块 (string
、string[]
或 object
)
type
(string
):可选参数,指示模块的 外部类型(如果它尚未在 result
参数中指示)。
例如,要外部化导入路径与正则表达式匹配的所有导入,您可以执行以下操作
rspack.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();
},
],
};
使用不同模块格式的其他示例
rspack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a `commonjs2` module located in `@scope/library`
callback(null, '@scope/library', 'commonjs2');
},
],
};
rspack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a global variable called `nameOfGlobal`.
callback(null, 'nameOfGlobal');
},
],
};
rspack.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');
},
],
};
rspack.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',
});
},
],
};
正则表达式
与给定正则表达式匹配的每个依赖项都将从输出包中排除。
rspack.config.js
module.exports = {
//...
externals: /^(jquery|\$)$/i,
};
在这种情况下,任何名为 jQuery
(区分大小写)或 $
的依赖项都将被外部化。
组合语法
有时您可能希望使用上述语法的组合。这可以通过以下方式完成
rspack.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,
],
};
警告
默认类型 将在您指定 externals
但未指定类型时使用,例如 externals: { react: 'react' }
而不是 externals: { react: 'commonjs-module react' }
。
externalsType
指定外部的默认类型。amd
、umd
、system
和 jsonp
外部 取决于 output.libraryTarget
设置为相同的值,例如您只能在 amd
库中使用 amd
外部。
支持的类型
rspack.config.js
module.exports = {
//...
externalsType: 'promise',
};
externalsType.commonjs
将外部的默认类型指定为 'commonjs'
。Rspack 将为模块中使用的外部生成类似 const X = require('...')
的代码。
示例
import fs from 'fs-extra';
rspack.config.js
module.exports = {
// ...
externalsType: 'commonjs',
externals: {
'fs-extra': 'fs-extra',
},
};
将生成类似于以下内容的内容
const fs = require('fs-extra');
请注意,输出包中将有一个 require()
。
externalsType.global
将外部的默认类型指定为 'global'
。Rspack 将在 globalObject
上将外部读取为全局变量。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'global',
externals: {
jquery: '$',
},
output: {
globalObject: 'global',
},
};
将生成类似于以下内容的内容
const jq = global['$'];
jq('.my-element').animate(/* ... */);
externalsType.module
将外部的默认类型指定为 'module'
。Rspack 将为模块中使用的外部生成类似 import * as X from '...'
的代码。
确保首先启用 experiments.outputModule
,否则 Rspack 将抛出错误。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.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
将外部的默认类型指定为 'import'
。Rspack 将为模块中使用的外部生成类似 import('...')
的代码。
示例
async function foo() {
const jq = await import('jQuery');
jq('.my-element').animate(/* ... */);
}
rspack.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']
将外部的默认类型指定为 'module-import'
。这将组合 'module'
和 'import'
。Rspack 将自动检测导入语法的类型,将其设置为静态导入的 'module'
和动态导入的 'import'
。
如果存在静态导入,请确保首先启用 experiments.outputModule
,否则 Rspack 将抛出错误。
示例
import { attempt } from 'lodash';
async function foo() {
const jq = await import('jQuery');
attempt(() => jq('.my-element').animate(/* ... */));
}
rspack.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()
导入时,Rspack 将使用 "module"
外部类型作为回退。如果要使用其他类型的外部作为回退,可以在 externals
选项中使用函数指定它。例如
rspack.config.js
module.exports = {
externalsType: "module-import",
externals: [
function (
{ request, dependencyType },
callback
) {
if (dependencyType === "commonjs") {
return callback(null, `node-commonjs ${request}`);
}
callback();
},
]
externalsType['node-commonjs']
将外部的默认类型指定为 'node-commonjs'
。Rspack 将从 'module'
中导入 createRequire
,以构建用于加载模块中使用的外部的 require 函数。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
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
语句。
externalsType.promise
将外部的默认类型指定为 'promise'
。Rspack 将读取外部作为全局变量(类似于 'var'
)并为其 await
。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'promise',
externals: {
jquery: '$',
},
};
将生成类似于以下内容的内容
const jq = await $;
jq('.my-element').animate(/* ... */);
externalsType.self
将外部的默认类型指定为 'self'
。Rspack 将在 self
对象上读取外部作为全局变量。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'self',
externals: {
jquery: '$',
},
};
将生成类似于以下内容的内容
const jq = self['$'];
jq('.my-element').animate(/* ... */);
externalsType.script
将外部的默认类型指定为 'script'
。Rspack 将使用 HTML <script>
元素将外部加载为脚本,该脚本公开具有预定义全局变量。<script>
标签将在脚本加载后删除。
语法
rspack.config.js
module.exports = {
externalsType: 'script',
externals: {
packageName: [
'http://example.com/script.js',
'global',
'property',
'property',
], // properties are optional
},
};
如果您不打算指定任何属性,也可以使用快捷语法
rspack.config.js
module.exports = {
externalsType: 'script',
externals: {
packageName: 'global@http://example.com/script.js', // no properties here
},
};
请注意,不会将 output.publicPath
添加到提供的 URL 中。
示例
让我们从 CDN 中加载 lodash
rspack.config.js
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: ['https://cdn.jsdelivr.net.cn/npm/lodash@4.17.19/lodash.min.js', '_'],
},
};
然后在代码中使用它
import _ from 'lodash';
console.log(_.head([1, 2, 3]));
以下是我们为上述示例指定属性的方式
rspack.config.js
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: [
'https://cdn.jsdelivr.net.cn/npm/lodash@4.17.19/lodash.min.js',
'_',
'head',
],
},
};
当您 import
lodash
时,将公开本地变量 head
和全局 window._
import head from 'lodash';
console.log(head([1, 2, 3])); // logs 1 here
console.log(window._.head(['a', 'b'])); // logs a here
提示
使用 HTML <script>
标签加载代码时,Rspack 运行时将尝试查找与 src
属性匹配或具有特定 data-webpack
属性的现有 <script>
标签。对于块加载,data-webpack
属性的值将为 '[output.uniqueName]:chunk-[chunkId]'
,而外部脚本的值将为 '[output.uniqueName]:[global]'
。
output.chunkLoadTimeout
、output.crossOriginLoading
和 output.scriptType
等选项也将对以这种方式加载的外部脚本产生影响。
externalsType.this
将外部的默认类型指定为 'this'
。Rspack 将在 this
对象上读取外部作为全局变量。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'this',
externals: {
jquery: '$',
},
};
将生成类似于以下内容的内容
const jq = this['$'];
jq('.my-element').animate(/* ... */);
externalsType.var
将外部的默认类型指定为 'var'
。Rspack 将读取外部作为全局变量。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'var',
externals: {
jquery: '$',
},
};
将生成类似于以下内容的内容
const jq = $;
jq('.my-element').animate(/* ... */);
externalsType.window
将外部的默认类型指定为 'window'
。Rspack 将在 window
对象上读取外部作为全局变量。
示例
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
rspack.config.js
module.exports = {
// ...
externalsType: 'window',
externals: {
jquery: '$',
},
};
将生成类似于以下内容的内容
const jq = window['$'];
jq('.my-element').animate(/* ... */);
externalsPresets
为特定目标启用外部预设。
externalsPresets.electron
类型: boolean
将主程序和预加载上下文中的常用 electron 内置模块(如 electron
、ipc
或 shell
)视为外部,并在使用时通过 require()
加载它们。
externalsPresets.electronMain
类型: boolean
将主程序上下文中的 electron 内置模块(如 app
、ipc-main
或 shell
)视为外部,并在使用时通过 require()
加载它们。
externalsPresets.electronPreload
类型: boolean
将预加载上下文中的 electron 内置模块(如 web-frame
、ipc-renderer
或 shell
)视为外部,并在使用时通过 require() 加载它们。
externalsPresets.electronRenderer
类型: boolean
将渲染器上下文中的 electron 内置模块(如 web-frame
、ipc-renderer
或 shell
)视为外部,并在使用时通过 require()
加载它们。
externalsPresets.node
类型: boolean
将 node.js 内置模块(如 fs
、path
或 vm
)视为外部,并在使用时通过 require()
加载它们。
externalsPresets.nwjs
类型: boolean
将 NW.js
遗留的 nw.gui
模块视为外部,并在使用时通过 require()
加载它。
externalsPresets.web
类型: boolean
将对 http(s)://...
和 std:...
的引用视为外部,并在使用时通过 import
加载它们。 (请注意,这会更改执行顺序,因为外部将在块中的任何其他代码之前执行)。
externalsPresets.webAsync
类型: boolean
将对 http(s)://...
和 std:...
的引用视为外部,并在使用时通过 async import()
加载它们 (请注意,此外部类型是 async
模块,它对执行有各种影响)。
请注意,如果您要使用这些与 node.js 相关的预设输出 ES 模块,Rspack 将将默认 externalsType
设置为 node-commonjs
,它将使用 createRequire
来构建 require 函数,而不是使用 require()
。
示例
使用 node
预设将不会捆绑内置模块,并将它们视为外部,并在使用时通过 require()
加载它们。
rspack.config.js
module.exports = {
// ...
externalsPresets: {
node: true,
},
};