CC 4.0 协议
本节内容派生于以下链接指向的内容 ,并遵守 CC BY 4.0 许可证的规定。
以下内容如果没有特殊声明,可以认为都是基于原内容的修改和删减后的结果。
Externals
外部依赖(externals)用于指定哪些模块不需要被 Rspack 打包,而是直接使用外部环境中提供的实现。
例如,当页面已经通过 CDN 引入了 React,或你开发的库希望由使用方自行安装 react 时,可以将其声明为 external。这可以减少打包产物的体积,同时避免重复引入相同依赖。
该能力常用于库开发场景,同时在应用侧接入 CDN、使用宿主环境注入依赖等场景中也同样适用。
- 类型:
基本用法
例如,当页面已通过 CDN 引入 Day.js 包时,可以将其声明为 external,避免被重复打包:
此时,dayjs 模块会从打包产物中剥离,转而在运行时从外部环境中获取,因此下面的代码仍然可以正常运行:
在上述配置中,externals 的键名 dayjs 对应 import dayjs from 'dayjs' 中的模块标识符,表示该模块不会被打包。
对应的值 dayjs 则用于在运行时访问全局变量。在这个基础配置中,externalsType 的默认值为 var,即从全局作用域中读取该变量。在浏览器环境下,这通常等价于访问 window.dayjs。
字符串
在前面的示例中,externals 的值使用了字符串形式,该字符串的具体含义取决于 externalsType 配置。
通常情况下,这个字符串可以表示:
简写语法
当只需要声明一个 external 时,也可以使用更简洁的写法:
匹配规则
需要注意的是,字符串形式是精确匹配。
例如,下面的配置只会匹配 react-dom,不会匹配 react-dom/client 这样的子路径导入:
如果你也希望这些子路径导入同样被 external,可以把它们一并列出来:
如果需要匹配一组相似的导入形式,也可以改用正则表达式。
指定外部模块类型
此外,还可以通过 ${externalsType} ${libraryName} 的语法显式指定外部模块类型,这会覆盖 externalsType 的默认值。
例如,当外部依赖以 ES module 形式提供时,可以这样配置:
字符串数组
subtract: ['./math', 'subtract'] 允许你选择一个模块的一部分,其中 ./math 是模块名,你的打包只需要包含 subtract 变量下的子集。
当 externalsType 为 commonjs 时,这个例子会编译为 require('./math').subtract;当 externalsType 为 window 时,这个例子会编译为 window["./math"]["subtract"]。
与字符串语法类似,你可以在数组的第一个元素中使用 ${externalsType} ${libraryName} 语法指定外部库类型,例如:
对象
带有 { root, commonjs, commonjs2, amd, ... } 的对象只允许用于 library.type: 'umd' 和 externalsType: 'umd'。其他库的 target 不允许这样做。
此语法用于描述外部 library 所有可用的访问方式。这里 lodash 这个外部库可以在 AMD 和 CommonJS 模块系统中通过 lodash 访问,但在全局变量形式下用 _ 访问。subtract 可以通过全局 math 对象下的属性 subtract 访问(例如 window['math']['subtract'])。
函数
- 类型:
function ({ context, request, contextInfo, getResolve }, callback)function ({ context, request, contextInfo, getResolve }) => promise
如果你想要自定义外部化的行为,可以使用函数。例如使用 webpack-node-externals 排除所有来自 node_modules 目录的模块,并提供了选项来允许列出白名单中的包。
函数接收两个入参:
ctx(object): 包含文件的详细信息的对象。ctx.context(string): 包含 import 的文件的目录。ctx.request(string): 被请求的 import 路径。ctx.contextInfo(object): 包含有关发起者的信息(例如 layer 和编译器)。ctx.getResolve: 获取一个带有当前解析器选项的解析函数。
callback(function (err, result, type)): 用来指示模块如何被外部化的回调函数。
回调函数接收三个参数:
err(Error): 用于标识外部化导入时是否出现错误。如果有错误,这应该是唯一使用的参数。result(string | string[] | object | boolean): 描述外部模块。type(string): 指示 externalsType 的可选参数(如果还没有在result参数中指出的话)。
例如,要外部化所有导入路径与正则表达式匹配的导入,可以这样做:
其他使用不同模块格式的例子:
正则表达式
你也可以使用正则表达式来匹配需要外部化的模块。所有符合该正则的模块标识符,都会从打包产物中排除。
在上述配置中,所有匹配 react-dom 的模块标识符都会被 external,例如 react-dom、react-dom/client 等。
复合语法
有时你可能希望使用上述语法的组合。这可以通过以下方式完成:
如果没有指定类型,将使用默认类型,例如 externals: { react: 'react' } 而不是 externals: { react: 'commonjs-module react' }。
externalsType
- 类型:
string - 默认值: 取决于
output.library.type和output.module
默认值的推导规则如下:
- 配置了
output.library时,与output.library.type保持一致。 - 否则,如果
output.module为true,则为'module-import'。 - 否则为
'var'。
指定 externals 的默认类型。当 external 被设置为 amd,umd,system 以及 jsonp 时,output.library.type 的值也应相同。例如,你只能在 amd 库中使用 amd 的 externals。
如果 external 依赖需要使用不同于推导结果的加载格式,请显式设置 externalsType。
支持的类型如下:
'amd''amd-require''assign'- 同'var''commonjs''commonjs-module''global''module''import'- 使用import()加载一个原生的 ECMAScript 模块(异步模块)'module-import''commonjs-import''jsonp''node-commonjs''promise''self''system''script''this''umd''umd2''var''window'
externalsType.commonjs
将 externals 的默认类型指定为 'commonjs'。Rspack 将为模块中使用的外部生成类似 const X = require('...') 的代码。
示例
将会转换为类似下面的代码:
请注意,输出产物中会有一个 require()。
externalsType.global
将 externals 的默认类型指定为 'global'。Rspack 会将 external 视为 globalObject 上的一个全局变量读取。
示例
将会转换为类似下面的代码:
externalsType.module
将 externals 的默认类型指定为 'module'。Rspack 将为模块中使用的 externals 生成类似 import * as X from '...' 的代码。
确保开启了 output.module。
示例
将会转换为类似下面的代码:
请注意,在输出产物中将有 import 语句。
externalsType.import
将 externals 的默认类型指定为 'import'。Rspack 将为模块中使用的 externals 生成类似 import('...') 的代码。
示例
将会转换为类似下面的代码:
请注意,在输出产物中将有 import() 语句。
externalsType['module-import']
将 externals 的默认类型指定为 'module-import'。这将结合 'module' 和 'import'。Rspack 将自动检测导入语法的类型,对于静态导入设置为 'module',对于动态导入设置为 'import'。
示例
将会转换为类似下面的代码:
请注意,在输出产物中将有 import 或 import() 语句。
当一个模块没有通过 import 或 import() 导入时,Rspack 将使用 "module" externals type 作为回退。如果你想使用不同类型的 externals 作为回退,你可以在 externals 选项中指定一个函数。例如:
externalsType['commonjs-import']
将 externals 的默认类型指定为 'commonjs-import'。这将结合 'commonjs' 和 'import'。Rspack 将自动检测导入语法的类型,对于动态导入设置为 'import',其他的导入设置为 'commonjs'。
这在构建一个 Node.js 应用程序时非常有用,当目标 Node.js 版本高于 13.2.0,同时支持 import() 表达式 和 require()。
commonjs-import 类型仅在 Rspack 中可用,webpack 并不支持此类型。
示例
将会转换为类似下面的代码:
请注意,在输出产物中将有 import() 语句。
externalsType['node-commonjs']
将 externals 类型设置为 'node-commonjs',Rspack 将从 module 中导入 createRequire 来构造一个 require 函数,用于加载模块中使用的外部对象。
示例
将会转换为类似下面的代码:
请注意,在输出产物中会有 import 语句。
externalsType.promise
将 externals 的默认类型指定为 'promise',Rspack 会将 external 视为全局变量(类似于 'var')并 await 它。
例子
将会转换为类似下面的代码:
externalsType.self
将外部的默认类型指定为 'self'。 Rspack 会将 external 作为 self 对象上的全局变量读取。
将会转换为类似下面的代码:
externalsType.script
将 external 的默认类型指定为 'script'。Rspack 会使用 HTML <script> 标签加载外部资源,暴露预定义的全局变量。脚本加载完成后,<script> 标签将被移除。
语法
如果不打算指定任何属性也可以使用快捷语法:
请注意,output.publicPath 不会被添加到提供的 URL 中。
示例
让我们从 CDN 加载一个 lodash:
然后在代码中使用:
下面是我们如何为上述示例指定属性的方法:
局部变量 head 和全局 window._ 在导入 lodash 时都将被暴露出来。
当使用 HTML <script> 标签加载代码时,Rspack 运行时会尝试查找与 src 属性匹配或具有特定 data-rspack 属性的现有 <script> 标签。对于 chunk 加载,data-rspack 属性的值将是 '[output.uniqueName]:chunk-[chunkId]',而外部脚本的值将是 '[output.uniqueName]:[global]'。
externalsType.this
将 external 的默认类型指定为 'this'。Rspack 会将 external 作为 this 对象上的全局变量读取。
示例
将会转换为类似下面的代码:
externalsType.var
将 external 的默认类型指定为 'var'。Rspack 会将 external 作为全局变量读取。
示例
将会转换为类似下面的代码:
externalsType.window
将 external 的默认类型指定为 'window'。Rspack 会将 external 作为 window 对象上的全局变量读取。
示例
将会转换为类似下面的代码:
externalsPresets
- 类型:
object
为特定的目标环境启用外部模块的预设值。
externalsPresets.electron
类型:boolean
将 Electron 主进程和预加载脚本中常见的 Electron 内置模块如 electron、ipc 或 shell 视为外部模块,并在使用时通过 require() 加载它们。
externalsPresets.electronMain
类型:boolean
将 Electron 主进程中常见的 Electron 内置模块如 app、ipc-main 或 shell 视为外部模块,并在使用时通过 require() 加载它们。
externalsPresets.electronPreload
类型:boolean
将 Electron 预加载脚本中常见的 Electron 内置模块如 web-frame、ipc-renderer 或 shell 视为外部模块,并在使用时通过 require() 加载它们。
externalsPresets.electronRenderer
类型:boolean
将 Electron 渲染进程中常见的 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 (externalType: "module") 来加载它们 (请注意,这会改变执行顺序,因为外部模块的代码会在 chunk 中的任何其他模块的代码之前执行)。
externalsPresets.webAsync
类型:boolean
将对 http(s)://... 和 std:... 引入的模块视为外部模块,并在使用时通过 async import() 来加载它们 (注意,外部模块的类型是 async 模块,对执行有各种影响)。
请注意,如果你打算输出 ES 模块并使用这些 node.js 相关的预设值,Rspack 将会将默认的 externalsType 设置为 node-commonjs,这将使用 createRequire 来构造一个 require 函数,而不是使用 require()。
示例
使用 node 预设将不会打包内置模块,并将它们视为外部模块,当使用时通过 require() 加载它们。

