在前端项目中,「兼容性」和「构建速度」往往是一对需要平衡的需求 ------ 比如要支持 IE 11 这类旧浏览器,就得做 JS 语法转译和 polyfill 补充,但传统工具(如 Babel)会明显拖慢构建效率。
而 Rspack 给出的解决方案是「内置 SWC Loader 」:SWC 基于 Rust 编写,转译速度是 Babel 的 10-20 倍,同时能完美承接兼容需求。本文就带你实战:如何通过 SWC Loader 实现「开发环境快构建、生产环境全兼容」,再结合 .browserslistrc
统一管理目标浏览器。
一、先理清核心逻辑:为什么这么配?
在看具体代码前,先明确 3 个关键前提,避免后续配置时「知其然不知其所以然」:
- SWC Loader 是 Rspack 内置的 :不用额外安装
swc-loader
,直接用builtin:swc-loader
即可,减少依赖成本; - 环境差异化处理 :开发环境(
development
)不需要兼容旧浏览器 ------ 优先保证构建速度,没必要做冗余的转译 /polyfill;生产环境(production
)才需要补全兼容逻辑,满足线上所有目标浏览器; - .browserslistrc 统一目标 :单独用文件定义「需要支持的浏览器」,不仅 SWC 会参考,后续 CSS 兼容(如 Autoprefixer)也能复用,避免多处写重复的
targets
配置。
二、核心配置:分三步实现 JS 兼容
第一步:定义环境判断变量
先通过 process.env.NODE_ENV
区分开发 / 生产环境,后续用这个变量控制 SWC 的配置差异:
javascript
// rspack.config.js
const path = require('path');
const popperPath = path.dirname(require.resolve('@popperjs/core/package.json'));
// 1. 环境判断:开发环境为 true,生产环境为 false
const isDev = process.env.NODE_ENV === 'development';
// 工具函数:统一路径解析(项目根目录下的 src/test 等)
const resolve = (dir) => path.join(__dirname, dir);
// 2. 定义 SWC Loader 配置(根据环境差异化)
const swcLoaderOptions = isDev
? {} // 开发环境:空配置(不做兼容处理,提速)
: { // 生产环境:配置兼容逻辑
env: {
// polyfill 引入策略:usage(按需引入,避免全量引入 core-js 导致体积过大)
mode: 'usage',
// 指定 core-js 版本(需确保项目依赖的 core-js 版本与此一致)
coreJs: '3.45.0',
// 生产环境需要支持的浏览器(与 .browserslistrc 呼应,双重保障)
targets: [
"ie >= 11", // 支持 IE 11
'chrome >= 60', // 支持 Chrome 60+
'edge >= 88', // 支持 Edge 88+
'firefox >= 78',// 支持 Firefox 78+
'safari >= 14', // 支持 Safari 14+
],
},
// 模块类型:unknown(让 SWC 自动判断模块类型,避免 CommonJS/ESModule 冲突)
isModule: 'unknown',
};
⚠️ 注意:生产环境配置 coreJs: '3.45.0'
前,需确保项目已安装对应版本的 core-js
,执行命令安装:
perl
# pnpm 安装(推荐)
pnpm add core-js@3.45.0 -S
# 或 npm 安装
npm i core-js@3.45.0 --save
第二步:配置 JS 文件的 Loader 规则
在 module.rules
中针对 .js
文件配置 builtin:swc-loader
,同时通过 include/exclude
控制处理范围(避免无用文件拖慢速度):
javascript
// rspack.config.js 继续补充
module.exports = {
// 其他基础配置(入口、出口等)...
module: {
rules: [
// 3. JS 文件处理:用 SWC Loader 转译和做兼容
{
test: /\.js$/, // 匹配所有 .js 文件
// 排除 node_modules 中的 core-js(core-js 本身是 polyfill 库,无需再转译)
exclude: /node_modules[\\/]core-js/,
// 只处理项目核心目录(避免处理无关文件,提升构建速度)
include: [
resolve('src'), // 项目业务代码目录
resolve('test'), // 测试代码目录
popperPath // 第三方库路径(如 Popper.js,按需添加)
],
use: {
loader: 'builtin:swc-loader', // Rspack 内置 SWC Loader,无需额外安装
options: swcLoaderOptions, // 传入上面定义的差异化配置
},
},
],
},
};
关键配置解读(避坑重点):
-
exclude: /node_modules[\\/]core-js/
:必须排除
core-js
目录!如果不排除,SWC 会重复转译core-js
源码,可能导致 polyfill 失效或报错(比如core-js
里的_export
方法被误转译)。 -
include
精确指定目录 :只处理
src
/test
等核心目录,不处理整个node_modules
------ 一方面减少 SWC 的处理文件数量,提升构建速度;另一方面避免第三方库被误转译(很多库本身已做过兼容处理)。 -
由于vant2 中引入的 popperjs,影响IE浏览器兼容,可以转成cdn vant方式引入,并且在 include中 加入 popperjs转义
iniconst popperPath = path.dirname(require.resolve('@popperjs/core/package.json'));
第三步:配置 .browserslistrc(统一目标浏览器)
在项目根目录创建 .browserslistrc
文件,定义「需要支持的浏览器范围」------ 这个文件会被 SWC、Autoprefixer(CSS 前缀)等工具共同复用,避免多处写重复配置:
arduino
//.browserslistrc(项目根目录下)
//1. 支持 IE 11(旧浏览器核心需求)
ie >= 11
//2. 支持市场份额大于 1% 的浏览器(覆盖主流现代浏览器)
> 1%
// 3. 支持每个浏览器的最后 2 个版本(避免过于老旧的现代浏览器)
last 2 versions
//4. 排除已停止更新的浏览器(如 IE 10 及以下、旧版 Opera 等)
not dead
配置生效逻辑:
SWC 会优先读取自身 env.targets
配置(即我们在 swcLoaderOptions
里写的),如果 targets
未定义,则会自动读取 .browserslistrc
------ 我们这里两者都配置,是为了「双重保障」:既明确生产环境的核心兼容目标(如 IE 11),又通过 .browserslistrc
覆盖更广泛的场景。
三、验证配置:确保兼容生效
配置完成后,需要验证生产环境的兼容逻辑是否正常工作,避免线上踩坑:
1. 检查 polyfill 是否按需引入
执行生产构建命令(如 pnpm run build
),打开构建后的 JS 文件(通常在 dist/js
目录下),搜索 core-js
相关代码 ------ 如果能看到类似 require("core-js/modules/es.promise.js")
的语句,说明「按需引入 polyfill」生效了(不是全量引入 core-js
)。
2. 在 IE 11 中测试页面
将构建后的 dist
目录部署到本地服务(如用 serve
工具),用 IE 11 浏览器打开页面:
- 若页面能正常渲染,无控制台报错(如
Promise is undefined
、箭头函数不支持
等),说明兼容生效; - 若报错,优先检查两点:①
core-js
版本是否与swcLoaderOptions
中的coreJs
一致;② 是否排除了node_modules[\\/]core-js
。
3. 用工具检测目标浏览器覆盖范围
可以用 browserslist
命令行工具查看当前配置覆盖的浏览器:
csharp
# 先全局安装 browserslist
pnpm add browserslist -g
# 在项目根目录执行,查看覆盖的浏览器列表
browserslist
执行后会输出类似以下结果,确认包含 IE 11 和主流现代浏览器即可:
ie 11
chrome 120
chrome 119
edge 120
edge 119
firefox 121
firefox 120
safari 17
safari 16.5
四、优化建议 & 常见问题
1. 开发环境进一步提速:关闭 sourceMap
如果开发环境构建速度仍不理想,可以在 SWC 配置中关闭 sourceMap(生产环境建议保留,方便调试):
arduino
const swcLoaderOptions = isDev
? {
sourceMap: false, // 开发环境关闭 sourceMap,进一步提速
}
: { /* 生产环境配置不变 */ };
2. 常见报错:core-js 版本不匹配
如果控制台报 Cannot find module 'core-js@3.45.0'
,说明项目安装的 core-js
版本与 swcLoaderOptions.coreJs
不一致 ------ 执行 pnpm list core-js
查看当前版本,再调整 coreJs
参数或重新安装对应版本。
3. 排除不需要兼容的文件
如果项目中有部分 .js
文件(如第三方 SDK)本身已做过兼容处理,可以在 exclude
中追加路径,避免重复转译:
javascript
exclude: [
/node_modules[\\/]core-js/,
/node_modules[\\/]some-sdk/ // 追加不需要处理的第三方 SDK 目录
]
总结
用 Rspack + SWC Loader 做 JS 兼容,核心是「环境差异化配置 」和「统一目标浏览器」,整个流程可总结为 3 步:
-
用
isDev
区分环境,开发环境空配置提速,生产环境配core-js
和targets
; -
配置 JS Loader 规则,精确控制
include/exclude
,避免无用处理; -
用
.browserslistrc
统一目标浏览器,实现多工具复用。
相比传统 Webpack + Babel 的方案,这套配置既能满足 IE 11 等旧浏览器的兼容需求,又能借助 SWC 的 Rust 性能优势,把生产环境的构建速度提升数倍 ------ 这也是 Rspack 作为下一代打包工具的核心价值之一。
最后,你在 Rspack 兼容配置中还遇到过哪些问题?比如支持更低版本浏览器、处理特殊 JS 语法转译等,欢迎在评论区分享你的解决方案~