Rspack 实战:用 SWC Loader 搞定 JS 兼容(支持 IE 11 + 现代浏览器,兼顾构建速度)

在前端项目中,「兼容性」和「构建速度」往往是一对需要平衡的需求 ------ 比如要支持 IE 11 这类旧浏览器,就得做 JS 语法转译和 polyfill 补充,但传统工具(如 Babel)会明显拖慢构建效率。

而 Rspack 给出的解决方案是「内置 SWC Loader 」:SWC 基于 Rust 编写,转译速度是 Babel 的 10-20 倍,同时能完美承接兼容需求。本文就带你实战:如何通过 SWC Loader 实现「开发环境快构建、生产环境全兼容」,再结合 .browserslistrc 统一管理目标浏览器。

一、先理清核心逻辑:为什么这么配?

在看具体代码前,先明确 3 个关键前提,避免后续配置时「知其然不知其所以然」:

  1. SWC Loader 是 Rspack 内置的 :不用额外安装 swc-loader,直接用 builtin:swc-loader 即可,减少依赖成本;
  2. 环境差异化处理 :开发环境(development)不需要兼容旧浏览器 ------ 优先保证构建速度,没必要做冗余的转译 /polyfill;生产环境(production)才需要补全兼容逻辑,满足线上所有目标浏览器;
  3. .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转义

    ini 复制代码
    const 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 步:

  1. isDev 区分环境,开发环境空配置提速,生产环境配 core-jstargets

  2. 配置 JS Loader 规则,精确控制 include/exclude,避免无用处理;

  3. .browserslistrc 统一目标浏览器,实现多工具复用。

相比传统 Webpack + Babel 的方案,这套配置既能满足 IE 11 等旧浏览器的兼容需求,又能借助 SWC 的 Rust 性能优势,把生产环境的构建速度提升数倍 ------ 这也是 Rspack 作为下一代打包工具的核心价值之一。

最后,你在 Rspack 兼容配置中还遇到过哪些问题?比如支持更低版本浏览器、处理特殊 JS 语法转译等,欢迎在评论区分享你的解决方案~

相关推荐
恋猫de小郭7 小时前
Flutter 官方 LLM 动态 UI 库 flutter_genui 发布,让 App UI 自己生成 UI
android·前端·flutter
薄雾晚晴7 小时前
Rspack 实战:用 image-minimizer-webpack-plugin 做图片压缩,优化打包体积
javascript·vue.js
niuhuahua7 小时前
大模型流式聊天,实时对话,快捷问题选项
vue.js
JIngJaneIL7 小时前
汽车租赁|基于Java+vue的汽车租赁系统(源码+数据库+文档)
java·vue.js·spring boot·汽车·论文·毕设·汽车租赁系统
kymjs张涛7 小时前
零一开源|前沿技术周刊 #15
前端·javascript·面试
Artea7 小时前
聊聊 Vue3 的泛型
vue.js
BYSJMG7 小时前
计算机毕业设计选题:基于Spark+Hadoop的健康饮食营养数据分析系统【源码+文档+调试】
大数据·vue.js·hadoop·分布式·spark·django·课程设计
reacx7 小时前
# 第三章:状态管理架构设计 - 从 Zustand 到 React Query 的完整实践
前端
古夕7 小时前
Vue3 + vue-query 的重复请求问题解决记录
前端·javascript·vue.js