Experiments
该选项赋予用户激活和尝试实验功能的能力。
experiments.asyncWebAssembly
支持基于新规范的 WebAssembly,这使 WebAssembly 模块成为异步模块
当设置 experiments.futureDefaults
为 true
时,默认启用此功能。
experiments.incrementalRebuild
启用增量重新编译。当启用此选项,Rspack 在重新编译时会尝试复用上次构建的结果来提升构建速度,支持对不同阶段进行配置,默认为开启状态。
0.5 版本移除该配置并内置开启该功能。
- 类型:
boolean | { make?: boolean, emitAsset?: boolean }
- 默认值:
true
experiments.outputModule
开启之后,将尽可能输出符合 ECMAScript 语法的代码。例如,使用 import()
加载 chunk,使用 ESM exports 等等。
module.exports = {
experiments: {
outputModule: true,
},
};
experiments.css
启用原生 CSS 支持和 CSS 相关的 parser 和 generator options:
WARNING
如果你在使用 style-loader
和 css-loader
请关闭该配置,因为 style-loader
和 css-loader
和原生 CSS 功能冲突。
experiments.futureDefaults
使用下一个主版本 Rspack 的默认值,并在任何有问题的地方显示警告。
rspack.config.js
module.exports = {
experiments: {
futureDefaults: true,
},
};
experiments.topLevelAwait
开启打包 top level await 的支持,top level await
仅能在 ModuleType 为 javascript/esm
的模块中使用。
默认开启,可通过该配置关闭。
experiments.lazyCompilation
type LazyCompilationOptions =
| boolean
| {
/**
* 为 entries 启用 lazy compilation
*/
entries?: boolean;
/**
* 为 dynamic imports 启用 lazy compilation
*/
imports?: boolean;
/**
* 指定哪些导入的模块应该被延迟编译
*/
test?: RegExp | ((m: Module) => boolean);
};
开启懒编译,这对提高多入口应用(MPA)或大型单页面应用(SPA)的 dev 启动性能会非常有帮助。例如你有二十个入口,只有访问到的入口才会进行构建,或者如果项目中存在非常多的 import()
,每一个 import()
所指向的模块都只有在被真正访问到时,才进行构建。
如果设置为 true,则默认会对入口模块以及 import()
指向的模块进行懒编译。你可以通过配置对象形式,来决定是否只对入口或只对 import()
生效。entries
决定是否对入口生效,import()
决定是否对 import()
生效。
rspack.config.js
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
experiments: {
// 仅在 dev 模式下开启
lazyCompilation: isDev,
},
};
除此以外你还可以配置 test
来更细粒度控制对哪些模块进行懒编译。test
可以是一个正则表达式,只对该正则匹配到的模块进行懒编译,test
也可以是一个函数,函数的输入是 Module
类型,返回 boolean
类型,表示是否命中懒编译逻辑。
NOTE
当前 lazy compilation 是对齐 webpack 实现的,并且仍处于实验性阶段。在部分场景下,lazy compilation 可能无法按照预期工作,或是性能提升不明显。
排除 HMR client
如果你未使用 Rspack 的 dev server,而是使用自己的 server 作为开发服务器,一般会在 entry 配置中加入另外的 client 代码来开启 HMR 等能力,那么最好通过配置 test 来将该 client 模块从懒编译模块中排除出去。
如果不排除掉,并且开启 entry 的懒编译,该 client 在第一次访问页面时不会被编译,因此需要一次额外的刷新才能让其真正生效。
const rspack = require('@rspack/core');
const options = {
experiments: {
lazyCompilation: {
test(module) {
const isMyClient = module.nameForCondition().endsWith('dev-client.js');
// 让 dev-client.js 不被懒编译
return !isMyClient;
},
},
},
};
const compiler = rspack(options);
new compiler.webpack.EntryPlugin(compiler.context, 'dev-client.js', {
// name: undefined 代表这是全局 entry,会插入到每一个 entry 前
name: undefined,
}).apply(compiler);
experiments.rspackFuture
用于控制是否开启 Rspack 未来的默认行为,详情请参考这里。
experiments.rspackFuture.disableTransformByDefault
-
类型: boolean
-
引入版本: v0.3.5
-
默认开启版本: v0.4.0
-
移除版本: v0.5.0
-
说明:
该功能主要对于三类问题进行处理:builtins 代码转换功能,target,自定义 Rule.type
- 移除对部分 builtins 功能的支持:
这部分配置项应当作用于被选中的相应模块,而使用 builtins.(relay|react|emotion|pluginImport|decorator)
则等于是全局开启,这种方案不被推崇,因此将被废弃。
在开启 disableTransformByDefault
后,上述配置项将失效,迁移指南可以参考 builtin:swc-loader/options.rspackExperiments。
例如我们希望 emotion
的转换被应用于所有 jsx
文件:
rspack.config.js
module.exports = {
module: {
rules: [
{
test: /\.jsx$/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: "ecmascript",
jsx: true
}
},
rspackExperiments: {
emotion: true // 配置项和原 builtins 保持一致
}
}
type: 'javascript/auto',
},
],
},
experiments: {
rspackFuture: {
disableTransformByDefault: true
}
}
};
对于 decorator 的配置项可以在,swc 代码中找到并替换,如 legacyDecorator,decoratorMetadata。
- target 将不会对用户侧代码做降级
在以往的版本中,我们通常会配置 target: ["web", "es5"]
来生成适用于 web 和降级后的代码。
现在,当用户开启了 disableTransformByDefault
配置项后,target
仅会被用于控制 runtime 代码(除了用户编写、node_modules 内的 Rspack 生成的代码,例如 chunk 加载等等)
这和 webpack 的插件化设计思维完成了对齐,你可以使用 builtin:swc-loader
的 env
或 target
进行迁移,
并精确控制需要转译的模块:
rspack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: "ecmascript"
},
target: "es5" // 注意,env 和 jsc.target 不能同时设置
},
env: { // 注意,env 和 jsc.target 不能同时设置
targets: "chrome >= 48"
}
}
type: 'javascript/auto',
},
],
},
experiments: {
rspackFuture: {
disableTransformByDefault: true
}
}
};
注意:在未开启 disableTransformByDefault
时,rspack 内置的转译器会对 node_modules
下的所有内容进行转译。
因此在开启了 disableTransformByDefault
后,builtin:swc-loader
配合 exclude: /node_modules/
需要确保 node_modules
下代码已经完成了降级,否则可能会存在兼容性问题。
- 移除了非 webpack 兼容的 Rule.type
这些类型被移除:
对于 JS 相关的类型仅会保留:
"javascript/auto"
"javascript/esm"
"javascript/dynamic"
在开启 disableTransformByDefault
后,Rspack 仅支持符合 web 标准的输入,对齐 webpack 的设计理念。
在我们完成和 webpack 的讨论后,webpack 和 Rspack 将会提供更加开箱即用的配置,以支持非标准的输入,如 TypeScript 等。
由于目前对于 jsx
, tsx
, ts
后缀名的文件会隐式地开启转译,因此在开启 disableTransformByDefault
后会提示编译报错,你可以这样完成迁移:
rspack.config.js
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: "typescript"
}
}
}
type: 'javascript/auto',
},
],
{
test: /\.tsx$/,
exclude: /node_modules/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: "typescript",
tsx: true
}
}
}
type: 'javascript/auto',
},
{
test: /\.jsx$/,
exclude: /node_modules/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: "ecmascript",
jsx: true
}
}
}
}
},
experiments: {
rspackFuture: {
disableTransformByDefault: true
}
}
};
experiments.rspackFuture.newResolver
-
类型: boolean
-
引入版本: v0.3.5
-
默认开启版本: v0.4.0
-
移除版本: v0.5.0
该功能将会开启新版 resolver,新的实现比旧版的 resolver 快了 5 倍。
rspack.config.js
module.exports = {
experiments: {
rspackFuture: {
newResolver: true,
},
},
};
新的 resolver 同时提供了在 tsconfig-paths-webpack-plugin 中定义的tsconfig project references 功能。
具体请参考 resolve API.
rspack.config.js
module.exports = {
resolve: {
tsconfig: {
configFile: path.resolve(__dirname, './tsconfig.json'),
references: 'auto'
},
}
experiments: {
rspackFuture: {
newResolver: true
}
}
}
experiments.rspackFuture.newTreeshaking
- 类型:
boolean
- 引入版本: v0.4.2
- 默认开启版本: v0.6.0
- 移除版本: v0.7.0
WARNING
从 0.7.0 版本开始,newTreeshaking 默认开启并且不能切换回已废弃的老 tree shaking 算法。
该功能启用了与 webpack 相同的新摇树优化实现,可以生成更高效和更小的代码。
rspack.config.js
module.exports = {
experiments: {
rspackFuture: {
newTreeshaking: true,
},
},
};
experiments.rspackFuture.disableApplyEntryLazily
- 类型:
boolean
- 引入版本: v0.4.5
- 默认开启版本: v0.5.0
- 移除版本: v0.6.0
在未开启该功能时,在 compiler.hooks.afterEnvironment
调用之后仍然可以对 options.entry
进行有效的修改。
而在开启该功能后,在 compiler.hooks.afterEnvironment
调用之后不会再进行 options.entry
的有效修改。该行为与 Webpack 一致,所以该配置对于使用 Rspack 开发应用的用户来说基本没有影响,而对于 Rspack 的插件或上层框架开发者需要注意。
一个常见的场景就是在创建 Compiler 之后增加一些入口:
const rspack = require('@rspack/core');
const compiler = rspack(options);
function prependEntry(compiler, additionalEntry) {
for (const key in compiler.options.entry) {
compiler.options.entry[key].import = [
additionalEntry,
...(compiler.options.entry[key].import || []),
];
}
}
prependEntry(compiler, 'dev-client.js');
在开启该功能后修改将不生效,需要进行如下修改:
const rspack = require('@rspack/core');
const compiler = rspack(options);
function prependEntry(compiler, additionalEntry) {
new compiler.webpack.EntryPlugin(compiler.context, additionalEntry, {
name: undefined,
}).apply(compiler);
}
prependEntry(compiler, 'dev-client.js');