介绍

SWC 全称为 Speedy Web Compiler,译为“快速网页编译器”。是一个基于 Rust 的可扩展平台,用于下一代高速开发工具。它既可以用于编译,也可以用于打包。在编译方面,接受使用现代 JavaScript 功能的 JavaScript / TypeScript 文件,并输出由所有主流浏览器支持的有效代码。

SWC 的特点就是:快!

看一看官方对于 SWC 速度的描述:

SWC is 20x faster than Babel on a single thread and 70x faster on four cores.

当只使用一个 CPU 核心(即单线程环境)时,SWC 比 Babel 快 20 倍。而当使用四个 CPU 核心(即四核环境,能够进行并行处理)时,SWC 比 Babel 快 70 倍。

SWC 对标的就是 [[001.Babel 介绍|Babel]],力图成为 Babel 的替代品。SWC 之所以可以那么快,主要是由于以下几个因素:

早期各种前端工具都是基于 Node.js 来写的,Node.js 是一个 JS 的运行时,JS 的运行速度一般比 Rust、Go 这些语言慢。

这几年开始有一种趋势,用其他的编程语言来编写前端工具,甚至还专门出现了一个词语 rustification(锈化),就是指使用 Rust 语言来翻新已有的前端工具,从而提升工具的性能。

如:

虽然编写这些工具的语言发生了变化,但是使用这些工具的方法是没变的。

API

新建一个项目 swc-demo,使用 pnpm init 初始化后安装依赖:

pnpm add @swc/core -D

接下来在 src/index.js 中书写测试代码:

const greet = (name) => `Hello, ${name}!`;
console.log(greet("World"));

之后在项目根目录下创建 compile.js,在该文件中利用 SWC 提供的 API 对文件进行编译:

const swc = require("@swc/core");
const fs = require("fs");
const path = require("path");

// 拼接路径
const codePath = path.resolve("src", "index.js");
const sourceCode = fs.readFileSync(codePath, "utf8");
const outDir = path.resolve(__dirname, "dist");

swc
  .transform(sourceCode, {
    jsc: {
      target: "es5", // 设置目标 JavaScript 版本
      parser: {
        syntax: "ecmascript", // 设置源代码的语法
      },
    },
  })
  .then((res) => {
    if (!fs.existsSync(outDir)) {
      fs.mkdirSync(outDir);
    }

    const outputFilePath = path.join(outDir, "index.js");
    fs.writeFileSync(outputFilePath, res.code);
  })
  .catch((err) => {
    console.error(err);
  });

CLI

首先需要安装相应的 CLI 包:

pnpm add @swc/cli -D

可以在 官网 看到 SWC 支持的所有 CLI 命令。

package.json 中进行 CLI 的配置即可,例如:

"scripts": {
    // ...
    "swc": "swc src -d lib"
 },

配置

在使用 transform 方法时,第二个参数就是一个配置对象。可以在 官网 看到所有支持的配置选项。

如果没有配置文件,会有一个默认的配置设置:

{
  // 用于设置 JavaScript 的编译选项
  "jsc": {
    // 用于设置解析器的选项
    "parser": {
      // 设置源代码的语法,可以是 ecmascript、jsx、typescript 或 tsx
      "syntax": "ecmascript",
      // 是否启用 JSX 语法
      "jsx": false,
      // 是否启用动态 import() 语句
      "dynamicImport": false,
      // 是否启用私有方法和访问器
      "privateMethod": false,
      // 是否启用函数绑定语法(:: 操作符)
      "functionBind": false,
      // 是否启用 export v from 'mod' 语法
      "exportDefaultFrom": false,
      // 是否启用 export * as ns from 'mod' 语法
      "exportNamespaceFrom": false,
      // 是否启用装饰器语法
      "decorators": false,
      // 是否在导出之前应用装饰器
      "decoratorsBeforeExport": false,
      // 是否启用顶级 await 语法
      "topLevelAwait": false,
      // 是否启用 import.meta 语法
      "importMeta": false,
      // 是否保留所有注释
      "preserveAllComments": false
    },
    // 设置转换插件,通常不需要手动设置
    "transform": null,
    // 设置目标 JavaScript 版本
    // 例如 es3、es5、es2015、es2016、es2017、es2018、es2019、es2020
    "target": "es5",
    // 是否启用宽松模式,这会使编译后的代码更简短,但可能不完全符合规范
    "loose": false,
    // 是否引用外部的 helper 函数,而不是内联它们
    "externalHelpers": false,
    // 是否保留类名,这需要版本 v1.2.50 或更高
    // 且 target 需要设置为 es2016 或更高
    "keepClassNames": false
  },
  // 用于指示输入的源代码是否是模块代码。
  // 如果是,那么 import 和 export 语句将被正常处理
  // 否则,它们将被视为语法错误
  "isModule": false
}