likes
comments
collection
share

体验了一把 swc 替代 babel 和 tsc

作者站长头像
站长
· 阅读数 10

背景

Next.js 11 已经使用了 swc 替换 babel 进行了 js 代码编译,构建速度提升了不少。于是针对自己的组件库进行了一波优化。

组件库使用了 React + TypeScript 编译用的 TypeScript 自带的 tsc 进行编译成 es5 代码

配置项文件 .swcrc

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "target": "es5",
    "keepClassNames": true,
    "loose": true
  },
  "module": {
    "type": "commonjs",
    "strict": false,
    "strictMode": true,
    "lazy": false,
    "noInterop": false
  },
  "sourceMaps": true
}

原来构建完成需要将近12s左右,现在仅需要不到1s完成构建编译,看来确实如官方所说的快很多

官方描述 swc 编译与其他工具 esbuild、tsc、babel 编译成不同目标代码的性能对比 性能对比

踩到的坑

对于这个编译工具,虽然相比其他工具有明显的性能提升,但是也有一定的局限性

优点

  • 编译速度快;
  • 配置简单,开箱即用;

缺点

  • 可使用的插件很少,官方文档上都没有;
  • 目前生产环境使用该工具构建的案例很少(仅有 Next.js 框架);
  • 针对使用 Typescript 的项目编译成后无法生成相应的 *.d.ts 声明文件;

由于项目中在引入一些通用文件模块时使用了相对路径别名,举个🌰子:

// 原本的写法
import { moduleA } from '../../../common/utils/tool'
// 这样的写法读起来不太优雅,于是换成了 =>
import { moduleA } from 'src/common/utils/tool'
// 这样就能更清楚地知道模块的位置

但是在实际构建编译后生成的路径文件映射实际上是错误的,尽管官方说已经修复了这个问题,但是感觉不是一个问题,

"jsc": {
     "paths": {
      "src/*":["./src/*"]
    },
}
// 使用该配置映射之后
// import { moduleA } from 'src/common/utils/tool' => 
// import { moduleA } from './src/common/utils/tool'
// 根本没有生效!!!

解决路径别名的问题

不适用 jsc.paths,使用 tsc-alias 完美解决这个问题

tsc-alias

解决生成 *d.ts 的问题

tsc --emitDeclarationOnly 直接单独生成 *d.ts 文件,编译由 swc 并行完成

tsc --emitDeclarationOnly & swc sourceDir -d oudir && tsc-alias