内置功能:该选项用于设置 Rspack 提供的内置功能。
Record<string, any>
{}
Builtins 提供的内置功能在未来可能会发生变化,或被更好的方式取代,请在升级时注意 builtins 的变化,我们会在 Release Notes 中着重标注。
type BannerCondition = string | RegExp | Array<string | RegExp>;
type BannerConfig =
| string
| {
banner: string;
entryOnly?: boolean;
footer?: boolean;
raw?: boolean;
test?: BannerCondition;
include?: BannerCondition;
exclude?: BannerCondition;
};
export type BannerConfigs = BannerConfig | BannerConfig[];
undefined
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
banner | string | undefined | 指定 banner 内容(会被包裹成注释) |
entryOnly | boolean|undefined | undefined | 如果值为 true,将只在入口 chunks 文件中添加 |
footer | boolean|undefined | undefined | 如果值为 true,banner 将会位于编译结果的最下方 |
raw | boolean|undefined | undefined | 如果值为 true,将直接输出,不会被作为注释 |
test | BannerConditions|undefined | undefined | 包含所有匹配的模块 |
include | BannerConditions|undefined | undefined | 根据条件匹配指定的模块 |
exclude | BannerConditions|undefined | undefined | 根据条件排除指定的模块 |
为每个 chunk 文件头部或底部添加 banner。
module.exports = {
builtins: {
banner: [
{
banner: 'hello world',
footer: true,
},
],
},
};
用于设置对 emotion 的编译优化。
export type EmotionConfig =
| boolean
| {
sourceMap?: boolean;
autoLabel?: 'never' | 'dev-only' | 'always';
labelFormat?: string;
importMap?: {
[packageName: string]: {
[exportName: string]: {
canonicalImport?: [string, string];
};
};
};
};
false
若你在项目中使用了 emotion
,并且想要类似 @emotion/babel-plugin 的能力,你可以开启 builtins.emotion 配置,启用该配置后,Rspack 会使用 swc_emotion
插件对 emotion
代码进行转译。
你可以直接使用默认配置,直接将 builtins.emotion
设置为 true
即可。
module.exports = {
context: __dirname,
entry: {
main: './src/index.js',
},
builtins: {
emotion: true,
},
};
各字段与 @emotion/babel-plugin 保持一致,详细解释(下列内容部分取自 @emotion/babel-plugin 官方文档):
'never' | 'dev-only' | 'always'
'dev-only'
这个配置项用于:
css
或者 styled
生成的样式中会包含原来的名字,方便调试。iconStyles$1
会变成 iconStyles1
,因为 $
不是合法的 CSS 类名选择器。不同的配置项会产生不同的产物代码:
'dev-only'
:只在 Rspack 的 development 模式下开启,在 production 模式下关闭以减小存储占用。'always'
:无论什么模式下都开启该特效。'never'
:无论什么模式下都禁用该特性。string
'[local]'
此选项仅在 'autoLabel'
设置为 'dev-only'
或 'always'
时有效。允许你自定义添加的 label
的结构。通过字符串定义,其中可变部分用方括号 '[]'
括起来。例如对于标签:'my-classname——[local]'
,其中 '[local]'
将被替换为样式变量的名称。
允许的值:
'[local]'
——CSS 或样式表达式所在的文件名称'[filename]'
——CSS 或样式表达式所在的文件名称(不带扩展名)。'[dirname]'
——包含 CSS 或样式表达式所在文件的目录名。该配置只会影响表达式中的 label
,这意味着 CSS 前缀和 hash 会自动被添加。
boolean
该配置决定是否注入 source maps。production 模式下默认关闭,development 模式下默认开启。
export type ImportMap =
| undefined
| {
[packageName: string]: {
[exportName: string]: {
canonicalImport?: [string, string];
};
};
};
undefined
此选项允许你告诉 Rspack 它应该查看哪些 import 语句,确定应该转换什么,因此如果你重导出 emotion 的方法,仍然可以转换。
该配置可以让你的代码运行在更老版本的浏览器上,你可以通过 browserslist 来指定需要支持的所有浏览器。 当源代码中使用了这些浏览器中不支持的 API,则可以通过全局注入 core-js 来为这些浏览器提供同样的 API。 如果源代码中使用了这些浏览器中不支持的语法,也会将这些语法转换成浏览器支持的语法。
当该配置项中的 mode
不为 undefined 时,请确保项目中依赖了 core-js。
type PresetEnv =
| undefined
| {
mode?: 'entry'; // 在不久的将来会支持 `usage` 模式
targets?: string[];
coreJs?: string;
};
undefined
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
targets | string[]|undefined | undefined | 通过该配置可以使用 browserslist query 来控制用户代码中 js 和 css 语法的降级,当此值为 undefined 时,rspack 将尝试使用基础目录 下的 browserslist 配置来进行转换。 |
mode | 'entry'|undefined | undefined | 该配置决定怎样注入 polyfill,'entry' 表示根据 browserslist 查询的浏览器,注入所有这些浏览器中缺失的 polyfill,当此值为 undefined 时则不会注入 polyfill。 |
coreJs | string | undefined | 该配置指定注入的 core-js 的版本 |
当你使用 mode = entry
或者 mode = usage
来注入core-js
的时候, 你需要手动的安装 core-js
, 如果编译时还碰到了 failed to resolve core-js
的问题,
同时你还应该配置 resolve.alias 来将 core-js
路径指向本地的core-js
module.exports = {
resolve: {
alias: {
'core-js': require('path').dirname(require.resolve('core-js')),
},
},
};
该配置可以快速创建与 Rspack 产物关联的 html 文件。
type BuiltinsHtml = Array<{
title?: string;
filename?: string;
template?: string;
templateContent?: string;
templateParameters?: Record<string, string>;
inject?: 'head' | 'body';
publicPath?: string;
scriptLoading?: 'blocking' | 'defer' | 'module';
chunks?: string[];
excludedChunks?: string[];
sri?: 'sha256' | 'sha384' | 'sha512';
minify?: boolean;
favicon?: string;
meta?: Record<string, string | Record<string, string>>;
}>;
[]
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
title | string|undefined | undefined | 构建 html 的标题 |
filename | string | 'index.html' | 输出的文件名,可以指定子目录,例如 pages/index.html |
template | string|undefined | undefined | 模版文件路径,支持 ejs |
templateContent | string|undefined | undefined | 模版文件内容,优先级大于 template |
templateParameters | Record<string, string> | {} | 传递给模版的参数 |
inject | 'head'|'body'|undefined | undefined | 产物注入位置 |
publicPath | string | '' | script 和 link 标签的 publicPath |
scriptLoading | 'blocking'|'defer'|'module' | 'defer' | 现代浏览器支持使用 defer 来异步加载 js,设置为 module 则会添加 type="module" 同时使用 defer |
chunks | string[]|undefined | undefined | 配置需要注入的 chunk,默认注入所有 chunk |
excludedChunks | string[]|undefined | undefined | 配置需要跳过注入的 chunk |
sri | 'sha256'|'sha384'|'sha512'|undefined | undefined | sri hash 算法,默认不开启 sri |
minify | boolean | false | 是否启用压缩 |
favicon | string|undefined | undefined | 配置 html 图标 |
meta | Record<string, string|Record<string, string>> | {} | 配置需要注入 html 的 meta |
对于复杂的 HTML 配置需求,可使用 @rspack/plugin-html,兼容 html-webpack-plugin 中的 hooks 和大部分配置。
设置内置压缩器配置。
type BuiltinsMinifyOptions = {
passes?: number;
dropConsole?: boolean;
pureFuncs?: Array<string>;
extractComments: boolean | RegExp;
asciiOnly?: boolean;
comments?: false | 'all' | 'some';
};
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
passes | number | 1 | 运行压缩的最大次数 |
dropConsole | boolean | false | 是否移除对 console.* 函数的调用 |
pureFuncs | Array<string> | [] | 指定无副作用的函数名称,压缩时会丢弃相关语句 |
extractComments | boolean|RegExp | false | 提取符合配置注释到一个单独的文件 (fileName: {assetName}.LICENSE.txt ), 如果设置该选项为 true , 使用正则表达式/@preserve|@lic|@cc_on|^**!/ 。 |
asciiOnly | boolean | false | 转义字符串和正则表达式中的 Unicode 字符(会影响包含非ASCII字符的指令,使其无效)。 |
comments | false | "all" | "some" | false | 默认情况下将省略输出中的注释、正则表达式字符串(例如 /^!/)或函数,传递 "some" 以保留包含 "@license"、"@copyright"、"@preserve" 或以 ! 开头的注释,传递 "all" 以保留所有注释。 |
此选项将会在编译时将代码中的变量替换为其他值或表达式。
Record<string, string | boolean | undefined>
{}
当使用以下配置时
module.exports = {
builtins: {
define: {
'process.env.NODE_ENV': "'development'",
API_PREFIX: '/api',
TRUE: true,
TRUE_STRING: 'true',
UNDEFINED: undefined,
UNDEFINED_STRING: 'undefined',
},
},
};
输入代码:
if (process.env.NODE_ENV === 'development') {
console.log('run in development mode');
}
fetch('API_PREFIX/test');
console.log(TRUE === TRUE_STRING);
console.log(UNDEFINED === UNDEFINED_STRING);
输出代码:
if ('development' === 'development') {
console.log('run in development mode');
}
fetch('/api/test');
console.log(true === true);
console.log(undefined === undefined);
此选项可以用来配置 react 相关代码的转换。
type BuiltinsReact = {
runtime?: 'automatic' | 'classic';
importSource?: string;
pragma?: string;
pragmaFrag?: string;
throwIfNamespace?: boolean;
development?: boolean;
useBuiltins?: boolean;
useSpread?: boolean;
refresh?: boolean;
};
{}
Name | Type | Default | Description |
---|---|---|---|
runtime | 'automatic'|'classic' | 'automatic' | automatic 会自动导入 JSX 运行时模块,classic 会使用 React.createElement 来进行转换 |
importSource | string | 'react' | 当 runtime 为 automatic 时,自动导入的库名称 |
pragma | string | 'React.createElement' | 当 runtime 为 classic 时,编译 JSX 表达式时所替换的函数名 |
pragmaFrag | string | 'React.Fragment' | 编译 JSX fragments 时所使用的组件名 |
throwIfNamespace | boolean | true | 当使用 xml 命名空间(例如 |
development | boolean | false | 是否为开发者模式,开发者模式将会在 JSX 元素上导出 __self 和 __source 以供类似于 React Developer Tools 这类工具使用 |
useBuiltins | boolean | false | 是否使用 Object.assign() 代替 _extends |
useSpread | boolean | false | 是否使用 Object.assign() 代替扩展操作符 |
refresh | boolean | false | 是否启动 react-refresh 相关转换 |
此选项可以用来配置装饰器的转换行为,false 表示关闭装饰器转换。
type BuiltinsDecorator =
| boolean
| {
legacy?: boolean;
emitMetadata?: boolean;
};
true
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
legacy | boolean | true | 是否使用历史(第 1 阶段)类装饰器的语法和行为 |
emitMetadata | boolean | true | 是否保留 metadata 信息 |
此选项可以用来配置默认 css 打包策略。
type BuiltinsCss = {
modules?: BuiltinsCssModules;
};
css modules 配置
type BuiltinsCssModules = {
localsConvention?:
| 'asIs'
| 'camelCase'
| 'camelCaseOnly'
| 'dashes'
| 'dashesOnly';
localIdentName?: string;
exportsOnly?: boolean;
};
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
localsConvention | 'asIs' | 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly' | asIs | asIs 类名将按原样导出。camelCase 类名将被驼峰化,原始类名仍然可用。camelCaseOnly 类名将被驼峰化,原始类名不可用。dashes 只有类名中的破折号会被驼峰化,原始类名仍然可用。dashesOnly 只有类名中的破折号会被驼峰化,原始类名不可用。 |
localIdentName | string | 生产环境: '[hash]' 开发环境: '[path][name][ext][local]" | 最终产物里的类名生成规则,支持以下模版字符:hash 字符串 hashhash:<length> 截取一定长度的 hashpath 文件与基础目录的相对路径name 文件名称ext 文件后缀名local 原始类名 |
exportsOnly | boolean | false | 只输出 js 对象,不输出 css 文件。常在 SSR 场景下使用 |
此选项可以用来配置进度条,false 表示不显示进度条。
boolean | { prefix?: string }
false
, development 模式 为true
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
prefix | string | 'Rspack' | 进度条前显示文案 |
是否开启对开发友好的分包算法。
类型: boolean
默认值: false
本节内容派生于以下链接指向的内容 ,并遵守 CC BY 4.0 许可证的规定。
以下内容如果没有特殊声明,可以认为都是基于原内容的修改和删减后的结果。
将已存在的单个文件或整个目录复制到产物目录。
export type CopyConfig = {
patterns: (
| string // 如果传入字符串,会被视作 { from: `你传入的字符串` }
| {
from: string;
to?: string; // 默认根据 from 推断
context?: string; // 默认 Rspack 配置中的 context
toType?: 'dir' | 'file' | 'template'; // 默认根据 from 推断
noErrorOnMissing?: boolean; // 默认 false
force?: boolean; // 默认 false
priority?: number; // 默认 0
globOptions?: {
caseSensitiveMatch?: boolean; // 默认 true
dot?: boolean; // 默认 true
ignore?: string[]; // 忽略特定路径
};
}
)[];
};
undefined
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
from | string | undefined | 复制的源路径,可以是绝对路径、相对路径、glob 查询字符串,可以是文件或目录。若传入相对路径,则是相对于 context 配置。 |
to | string | undefined | 复制的目的地,可以是绝对路径、相对路径或者是 Rspack 的模版字符串,例如 '[name].[hash][ext]' 。当不指定 to 时,则相当于是产物目录。 |
context | string | undefined | 该配置决定怎样匹配 from 路径,以及复制后的结构。 |
toType | 'dir'|'file'|'template' | undefined | 指定 to 的类型,可以是目录,文件或 Rspack 的模版名,若不指定则会自动推断。 |
noErrorOnMissing | boolean | false | 当没有找到对应的文件或目录时,忽略错误。 |
force | boolean | false | 当产物中已经有相应的文件时,是否覆写。 |
priority | number | 0 | 当设置 force 为 true 时,如果匹配到同样的文件,优先级高的会覆写优先级的。 |
globOptions | object | undefined | glob 查询选项,caseSensitiveMatch 决定是否大小写敏感,dot 决定是否匹配以 . 开头的文件,ignore 是 glob 形式的字符串数组,可以使用该配置忽略部分特定路径。 |
示例:
module.exports = {
entry: './src/index.js',
builtins: {
copy: {
patterns: [
{
from: 'file.txt',
},
],
},
},
};
以上面的配置运行结果会是:"dist/file.txt"
。
module.exports = {
entry: './src/index.js',
builtins: {
copy: {
patterns: [
{
from: 'directory',
},
],
},
},
};
以上面的配置运行结果会是 directory
目录下的所有文件平铺在产物目录中。
module.exports = {
entry: './src/index.js',
builtins: {
copy: {
patterns: [
{
from: 'directory/**/*',
to: 'newdirectory',
},
],
},
},
};
以上面的配置运行结果会是 directory
目录被移动到产物目录中的 newdirectory
目录,例如 dist/newdirectory/directory/foo
。
将项目中的 graphql
调用转换成相对应的 require
。
export type RelayConfig =
| undefined
| boolean
| {
artifactDirectory?: string;
language: 'javascript' | 'typescript' | 'flow'; // 默认 'javascript'
};
undefined
当该配置为 true
时,Rspack 会从依次尝试寻找 context 目录下的 relay.config.json
,relay.config.js
以及 package.json
,详情可以参考 relay-compiler 文档,如果没找到则会使用默认配置。
如果传入具体的配置则不会尝试查找任何 relay
配置文件,而是直接使用传入的配置。
移植自 babel-plugin-import,配置基本保持一致。
但不能使用函数进行配置,例如 customName
,customStyleName
等,这是因为这些函数必须由 Rust 调用,这种调用会造成一些性能劣化,受到 modularize_imports 的启发,简单的函数逻辑其实可以通过模版来代替,因此 customName
,customStyleName
,这些配置可以传入字符串作为模版来代替函数,提高性能。
我们以下面代码为例说明:
import { MyButton as Btn } from 'foo';
添加以下配置:
module.exports = {
builtins: {
pluginImport: [
{
libraryName: 'foo',
customName: 'foo/es/{{ member }}',
},
],
},
};
其中的 {{ member }}
会被替换为相应的引入成员,转换后:
import Btn from 'foo/es/MyButton';
可以看出配置 customName: "foo/es/{{ member }}"
的效果等同于配置 customName: (member) => `foo/es/${member}`
,但是不会有 Node-API 的调用开销。
这里使用到的模版是 handlebars,模版配置中还内置了一些有用的辅助函数,还是以上面的导入语句为例:
配置如下:
module.exports = {
builtins: {
pluginImport: [
{
libraryName: 'foo',
customName: 'foo/es/{{ kebabCase member }}',
},
],
},
};
会转换成下面的结果:
import Btn from 'foo/es/my-button';
除了 kebabCase
以外还有 camelCase
、snakeCase
、upperCase
和 lowerCase
可以使用。
其他配置可以直接查看 babel-plugin-import。
再以经典的 4 版本的 ant-design 为例,我们只需要如下配置:
module.exports = {
builtins: {
pluginImport: [
{
libraryName: 'antd',
style: '{{member}}/style/index.css',
},
],
},
};
上面的配置会将 import { Button } from 'antd';
转换成
import Button from 'antd/es/button';
import 'antd/es/button/style/index.css';
然后就可以在页面中看到样式文件自动被引入并且生效了。
当然如果你已经配置了对 less
的支持,也可以直接使用如下配置:
module.exports = {
builtins: {
pluginImport: [
{
libraryName: 'antd',
style: true,
},
],
},
};
上面的配置会将 import { Button } from 'antd';
转换成:
import Button from 'antd/es/button';
import 'antd/es/button/style';
自动的将全局变量转换为模块导入,如下配置:
module.exports = {
builtins: {
provide: {
process: [require.resolve('process/browser')],
},
},
};
将如下代码:
console.log(process.version);
转换为:
import process from 'process/browser';
console.log(process.version);