用SWC提升前端构建速度的实战经验分享

Zz乐佳 前端 阅读 2,847
赞 12 收藏
二维码
手机扫码查看
反馈

先来一发最爽的用法:把 Babel 换成 SWC,直接起飞

上周我接手了个老项目,Webpack + Babel 配置一套下来,本地启动要 40 秒,热更新等得我都快睡着了。我实在忍不了,直接上 SWC —— 改完之后,冷启动 8 秒,热更新基本无感。真不是吹,这速度提升是肉眼可见的。

用SWC提升前端构建速度的实战经验分享

核心改动就两步:一是换掉 babel-loader,二是加个 @swc/loader。代码贴出来,你照着改就行:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: '@swc/loader',
          options: {
            jsc: {
              parser: {
                syntax: 'ecmascript',
                jsx: true,
              },
              transform: {
                react: {
                  runtime: 'automatic', // 自动引入 React(17+)
                },
              },
            },
          },
        },
      },
    ],
  },
};

注意,如果你用的是 React,一定要开 runtime: 'automatic',不然会报 React is not defined。这个我踩过坑,折腾了半天才发现是 JSX 转译没配对。

另外,@swc/loader 要装,别只装 @swc/core。我一开始漏装了 loader,结果 Webpack 报错说找不到模块,其实是包名搞混了。

现在跑不起来?看看你的 .swcrc 配置对不对

SWC 的配置文件叫 .swcrc,长这样:

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true
    },
    "target": "es2016",
    "loose": false,
    "externalHelpers": false
  },
  "module": {
    "type": "commonjs"
  }
}

这里有几个关键点:

  • 如果你用 TypeScript,syntax 必须设为 typescript,不然解析会出错
  • target 我一般设成 es2016,兼容性够用,又不至于输出太多 polyfill
  • module.type 要和你的打包工具匹配。Webpack 默认支持 commonjs,所以没问题。但如果你用 Vite 或 esbuild,建议改成 es6es2020

还有一点,decorators 如果你用了装饰器语法(比如 MobX),必须显式开启,否则直接报错。这个在 Babel 里可能是默认开的,但 SWC 不认,默认是 false。

和 TypeScript 怎么配合?tsconfig.json 别瞎删

很多人以为上了 SWC 就可以删掉 tsconfig.json,大错特错。SWC 只负责转译,不负责类型检查。你要是把 tsconfig 删了,TS 类型报错都没了,等于裸奔。

正确做法是:保留 tsconfig.json 做类型校验,用 SWC 做编译。两者分工明确,一个查错,一个提速。

如果你用 VS Code,它还是会基于 tsconfig 提示错误,完全不受 SWC 影响,这点放心。

Vite 用户注意:vite-plugin-swc 是救星

最近我帮同事搞 Vite 项目,发现原生 Vite 不走 .swcrc,它自己用 esbuild 预构建,开发模式下根本没机会让 SWC 插手。

解决办法:装 vite-plugin-swc,强制让 SWC 在开发时也生效。

// vite.config.js
import { defineConfig } from 'vite';
import swc from 'vite-plugin-swc';

export default defineConfig({
  plugins: [
    swc({
      module: { type: 'es6' },
      jsc: {
        parser: { syntax: 'typescript', tsx: true },
        target: 'es2021',
      },
    }),
  ],
});

这个插件亲测有效,开发服务器启动速度几乎没影响,但生产构建能快不少。注意 module.type 设成 es6,不然 import/export 会被转成 commonjs,ESM 环境下可能出问题。

遇到奇怪的语法报错?很可能是 SWC 不支持

SWC 虽然快,但毕竟不是 Babel,生态没那么全。有些实验性语法它不支持,比如:

  • top-level await(部分版本支持,但有坑)
  • decorator metadata(TypeScript 特有,SWC 不处理)
  • 某些 babel-plugin-xxx 的功能(比如自动按需引入 lodash 函数)

举个例子,我们项目里用了 babel-plugin-import 来按需加载 Ant Design 组件,换成 SWC 后发现样式全没了——因为 SWC 不认识这个插件。

解决办法有两个:

  1. 换用组件库自带的 ES 导出方式,手动按需引入
  2. swc-plugin-auto-import 这类社区插件(不稳定,慎用)

我的建议是:别太依赖 Babel 插件,尽量用标准语法。如果非要用,提前测试,别等到上线才发现。

Node.js 后端也能用?当然,启动快到飞起

我们有个 Node 服务是用 TS 写的,每次改完要重新编译再重启,tsc + nodemon 组合慢得离谱。后来我上了 @swc-node/register,直接运行时编译,快太多了。

// server.ts
import express from 'express';

const app = express();
app.get('/', (req, res) => {
  res.send('Hello from SWC!');
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});
# 安装
npm install @swc/core @swc-node/register --save-dev

# 启动
node -r @swc-node/register server.ts

实测比 ts-node 快 3 倍以上。而且内存占用低,适合部署环境。不过注意,生成环境不要用这种方式,还是应该先构建再运行,避免运行时编译风险。

API 调用示例:fetch 数据也更快?

这个其实和 SWC 没直接关系,但既然提到性能,顺带提一嘴。我们在前端请求中用了 SWC 编译后的代码,bundle 更小,首屏加载更快,自然 fetch 也“显得”更快了。

async function fetchData() {
  try {
    const res = await fetch('https://jztheme.com/api/data');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Fetch failed:', err);
  }
}

虽然这只是个普通请求,但因为整体 JS 包体积小了 30%,页面更早执行到这段代码,用户感知就是“接口变快了”。

踩坑提醒:这三点一定注意

最后总结三个我亲自踩过的坑,你避开就能省半天时间:

  1. 别忘了装 @swc/loader:只装 @swc/core 没用,Webpack 找不到 loader
  2. .swcrc 的 module.type 要和打包器匹配:Webpack 用 commonjs,Vite 用 es6,错了会报 __esModule is not a function 之类的错
  3. TSX 文件要显式开启 tsx: true:不然会当普通 TS 解析,JSX 标签直接报错

还有一个小细节:SWC 对 process.env.NODE_ENV 不做注入,如果你代码里依赖这个变量,记得用 DefinePlugin 或其他方式手动注入,不然生产环境可能出问题。

写在最后:SWC 不是万能,但值得尝试

SWC 确实快,但它不是 Babel 的完全替代品。如果你项目重度依赖 Babel 插件,迁移成本会高。但如果是新项目,或者想优化构建速度,我强烈建议直接上 SWC。

我自己现在的项目基本都换掉了 Babel,除了个别老系统还在过渡。速度快了,心情都好了,每天少等几十秒,一年下来也是几个小时。

这个技巧的拓展用法还有很多,比如结合 Turbopack、Rspack 等新构建工具,后续会继续分享这类博客。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论