// 具名导出
export var Count = 5;
export function Multiply(a, b) {
return a * b;
// 默认导出
export default {
// Some data...
Dynamic import()
function import(path: string): Promise;
动态加载模块,参考 Dynamic import 了解更多。
对 import() 的调用被视为分割点,这意味着请求的模块及其子模块被拆分成单独的 chunk。
if (module.hot) {
import('lodash').then(_ => {
// 使用 lodash 做些事情...
import() 中的动态表达式
import() 无法使用完全动态的导入语句,例如 import(foo)。因为 foo 可能是系统或项目中任何文件的任何路径。
import() 必须至少包含一些关于模块所在位置的信息。可以将打包限制在特定目录或一组文件中,这样当你使用动态表达式时,在 import() 调用中可能被请求的每个模块都会被包括进来。
例如,import(./locale/${language}.json) 会将 ./locale 目录中的每个 .json 文件都被打包进新的代码块。在运行时,一旦变量 language 被计算出来,任何像 english.json 或 german.json 这样的文件都将可供使用。
// 想象一下,如果我们有一种方法可以从 Cookie 或其他存储中获取语言
const language = detectVisitorLanguage();
import(`./locale/${language}.json`).then
(module => {
// 做一些翻译相关的事情
Rspack/Webpack specific
通过向 import 语句添加注释,我们可以实现「指定 chunk 名称」或「设置加载模式」等操作。有关这些魔法注释的完整列表,请参见下面的代码,以及对这些注释功能的解释。
// 单个模块
import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackFetchPriority: "high" */
'module'
// 多个可能模块
import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`./locale/${language}`
webpackIgnore
类型: boolean
设置为 true 时,Rspack 将跳过对该动态导入的静态分析和打包处理。具体表现为:
构建时不会分析该模块的依赖关系
该模块不会被打包为独立的 chunk 文件
导入操作将在运行时由浏览器原生 import() 执行
这在需要从外部 CDN 动态加载 ESM 格式的第三方库时特别有用,例如:
import('https://esm.sh/react' /* webpackIgnore: true */).then(React => {
console.log(React.version); // 19.0.0
webpackIgnore 同样适用于 new URL() 语法。默认情况下,Rspack 会解析 new URL() 中的模块标识符,并将其引用的模块打包到构建产物中。当你需要 Rspack 跳过某个 new URL() 的处理时,可以添加 webpackIgnore: true 注释:
// Rspack 会处理这个 URL,将 './index.css' 打包到构建产物中
const url1 = new URL('./index.css', import.meta.url);
// Rspack 会忽略这个 URL,保持原始的模块标识符
const url2 = new URL(/* webpackIgnore: true */ './index.css', import.meta.url);
webpackMode
类型: "eager" | "lazy" | "weak" | "lazy-once"
默认值: 'lazy'
可以指定以不同的模式解析动态导入。支持以下选项:
'lazy' (默认值):为每个 import() 导入的模块生成一个可延迟加载(lazy-loadable)的 chunk。
'lazy-once':生成一个可以满足所有 import() 调用的单个可延迟加载(lazy-loadable)的 chunk。此 chunk 将在第一次 import() 时调用时获取,随后的 import() 则使用相同的网络响应。注意,这种模式仅在部分动态语句中有意义,例如 import("./locales/${language}.json"),其中可能含有多个被请求的模块路径。
'eager':不会生成额外的 chunk。所有的模块都被当前的 chunk 引入,并且没有额外的网络请求。但是仍会返回一个 resolved 状态的 Promise。与静态导入相比,在调用 import() 完成之前,该模块不会被执行。
'weak':尝试加载模块,如果该模块函数已经以其他方式加载,(即另一个 chunk 导入过此模块,或包含模块的脚本被加载)。仍会返回 Promise, 但是只有在客户端上已经有该 chunk 时才会成功解析。如果该模块不可用,则返回 rejected 状态的 Promise,且网络请求永远都不会执行。当需要的 chunks 始终在(嵌入在页面中的)初始请求中手动提供,而不是在应用程序导航在最初没有提供的模块导入的情况下触发,这对于通用渲染(SSR)是非常有用的。
webpackPrefetch
number: 预取优先级
boolean: false 表示不预取, true 表示预取并且优先级是 0
告诉浏览器将来可能需要该资源来进行某些导航跳转,详情请查看预取/预载模块。
webpackPreload
number: 预载优先级
boolean: false 表示不预载, true 表示预载并且优先级是 0
告诉浏览器在当前导航期间可能需要该资源,详情请查看预取/预载模块。
webpackChunkName
类型:: string
指定新 chunk 的名称。
webpackFetchPriority
类型:: "low" | "high" | "auto"
为指定的动态导入设置 fetchPriority。也可以通过使用 module.parser.javascript.dynamicImportFetchPriority 选项为所有动态导入设置全局默认值。
webpackInclude
类型:: Regexp
在导入解析时匹配的正则表达式。只有匹配的模块才会被打包。
webpackExclude
类型:: Regexp
在导入解析时匹配的正则表达式。只有匹配的模块不会被打包。
请注意,webpackInclude 和 webpackExclude 选项不会影响前缀。例如:./locale。
webpackExports
Type:: string | string[]
使 Rspack 在处理该动态 import() 模块时仅打包指定的导出。这样可以降低 chunk 的产物体积。
CommonJS
Rspack 也支持 CommonJS 语法,可以使用 require 和 module.exports 语法。
require
以同步的方式引入其他模块。
require(dependency: string);
require.resolve
以同步的方式获取模块的 ID。此方法会将模块打包进最终的 bundle 中,但不会执行模块代码。返回的模块 ID 主要用于与 require.cache[id] 或 Rspack 内部的 __webpack_require__(id) 一起使用,在大多数应用场景中应避免直接使用此方法。
require.resolve(dependency: string);
WARNING
模块 ID 的类型可以是 number 或 string,具体取决于 optimization.moduleIds 配置。
require.cache
多处引用同一模块,最终只会产生一次模块执行和一次导出。所以,会在运行时(runtime)中会保存一份缓存。删除此缓存,则会产生新的模块执行和新的导出。
var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;
require.context
Rspack/Webpack specific
require.context 允许你动态地 require 一组模块。
你可以在代码中使用 require.context,Rspack 将在构建时进行解析并引用匹配的模块。
require.context 的返回值与 import.meta.webpackContext 相同,我们推荐使用 import.meta.webpackContext,它的功能更加强大。
function requireContext(
* 要搜索的目录
directory: string,
* 是否还搜索其子目录
* @default true
includeSubdirs?: boolean,
* 匹配文件的正则表达式
* @default /^\.\/.*$/(匹配任意文件)
filter?: RegExp,
* 模块加载模式
* @default 'sync'
mode?: 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once',
): Context;
// 创建一个上下文,
// 文件直接来自 test 目录,匹配的文件名以 `.test.js` 结尾。
const context = require.context('./test', false, /\.test\.js$/);
// 创建一个上下文,
// 文件来自父文件夹及其所有子级文件夹,匹配的文件名以 `.stories.js` 结尾。
const context = require.context('../', true, /\.stories\.js$/);
// 如果 `mode` 被设置为 `lazy`,模块将会被异步加载
const context = require.context('./locales', true, /\.json$/, 'lazy');
Rspack 在编译时,会通过静态分析来解析 require.context 的参数,因此参数必须是字面量。例如,filter 的值不允许传入一个变量,也不允许传入 new RegExp() 生成的值,只能是一个正则表达式字面量。
require.ensure
Rspack/Webpack specific
require.ensure() 基本已经被 import() 取代.
将给定 dependencies 单独打包,并异步加载。当使用 CommonJS 语法的时候,这是唯一动态加载依赖的方式。同时,这个 API 也可以用于运行时,只有在满足某些条件时才会加载依赖。
Type:
function requireEnsure(
* callback 执行需要的模块列表
dependencies: String[],
* 当 dependencies 中的模块都加载完毕时,这个函数就会被执行。
* require 函数将作为第一个参数传入该函数。
* 在这个函数中也可以进一步使用 require() 来加载模块。
callback: function(require),
* 当加载依赖失败的时候执行的函数
errorCallback?: function(error),
* 指定由 require.ensure() 生成的 chunk 名称。
* 通过指定相同的 chunkName 来合并多个 require.ensure() 调用的代码,从而只生成一个 bundle,
* 从而减少浏览器加载的次数。
chunkName?: string
): Context;
Example:
var a = require('normal-dep');
if (module.hot) {
require.ensure(['b'], function (require) {
var c = require('c');
// Do something special...
require.resolveWeak
Rspack/Webpack specific
与 require.resolve 类似,但是不会把 module 打包到最终的 bundle 中。是 "弱(weak)" 依赖。
require.resolveWeak(dependency: string);
if (__webpack_modules__[require.resolveWeak('module')]) {
// 当模块可用时,执行一些操作
if (require.cache[require.resolveWeak('module')]) {
// 在模块加载完成之前,执行一些操作
// 你可以像执行其他 require/import 方法一样,
// 执行动态解析上下文 resolves ("context")
const page = 'Foo';
__webpack_modules__[require.resolveWeak(`./page/${page}`)];
Data URI 模块
Rspack 支持使用 import 和 require 语法导入 Data URI 模块。
import
import DataURI from 'data:text/javascript,export default 42';
require
require('data:text/javascript,module.exports = 42');
除此之外,还支持了 Base64 编码:
const {
number,
} = require('data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgZnVuY3Rpb24gZm4oKSB7CiAgcmV0dXJuICJIZWxsbyB3b3JsZCI7Cn0=');
Data URI 模块可以被用作虚拟模块(Virtual Modules)的实现方式,如:配合 loader 完成运行时动态加载自定义模块。
自定义 Rules
Rspack 默认支持这些 MIME 类型 的 data URI 模块:application/json、text/javascript、application/javascript、application/node 和 application/wasm。这意味着当你使用这些 MIME 类型创建 data URI 模块时,Rspack 会自动识别他们。
Rspack 内置的 MIME rules 如下:
const defaultMimeRules = [
mimetype: 'application/node',
type: 'javascript/auto',
mimetype: 'application/json',
type: 'json',
mimetype: {
or: ['text/javascript', 'application/javascript'],
type: 'javascript/esm',
// ...
mimetype: 'application/wasm',
type: 'webassembly/async',
// ...
自定义 Rules
你可以也使用 Rule.mimetype 来扩展 Data URI 模块的匹配规则,例如为 text/javascript 添加自定义的 loaders:
rspack.config.mjs
export default {
module: {
rules: [
mimetype: 'text/javascript',
use: [
// ...