12

Recently, there has been a rust trend in the front-end circle. Any front-end tool that can be rewritten in rust is rewritten in rust. The tool introduced today is babel: swc implemented through rust, a tool for converting ES6 to ES5.

Moreover, on the official website of swc, it is very straightforward to say that the swc and babel commands can be replaced with each other, and most of the babel plugins have also been implemented.

One advantage of using rust is that it is fast. For example, in one of our previous projects, after replacing babel with swc, the compilation speed increased from the original 7 seconds to 1 second, and the efficiency exploded directly.

get started

Like babel, swc divides command-line tools and compiling core modules into two packages.

  • @swc/cli similar to @babel/cli ;
  • @swc/core similar to @babel/core ;
npm i -D @swc/cli @swc/core

With the following command, you can convert an ES6 JS file to ES5.

npx swc source.js -o dist.js

Here is the code source.js

const start = () => {
  console.log('app started')
}

The code includes two ES6 features, const declarations and arrow functions. After swc transformation, these two features are transformed into var declaration and function anonymous function respectively.

configuration file

Like babel, swc supports configuration files .babelrc .swcrc , and the configuration format is JSON.

{
  "jsc": { // 编译规则
    "target": "es5", // 输出js的规范
    "parser": {
      // 除了 ecmascript,还支持 typescript
      "syntax": "ecmascript",
      // 是否解析jsx,对应插件 @babel/plugin-transform-react-jsx
      "jsx": false,
      // 是否支持装饰器,对应插件 @babel/plugin-syntax-decorators
      "decorators": false,
      // 是否支持动态导入,对应插件 @babel/plugin-syntax-dynamic-import
      "dynamicImport": false,
      // ……
      // babel 的大部分插件都能在这里找到对应配置
    },
    "minify": {}, // 压缩相关配置,需要先开启压缩
  },
  "env": { // 编译结果相关配置
    "targets": { // 编译结果需要适配的浏览器
      "ie": "11" // 只兼容到 ie 11
    },
    "corejs": "3" // corejs 的版本
  },
  "minify": true // 是否开启压缩
}

Babel's plug-in system is integrated into jsc.parser by swc, basically most plug-ins can take care of it. Moreover, swc also inherits the ability of compression, which is enabled through the minify attribute, and jsc.minify used to configure compression-related rules. For more detailed configuration, see document .

Node APIs

@swc/core module in the node.js code, you can call the api in node.js to compile the code directly, which is a normal operation for the development of CLI tools.

// swc.mjs
import { readFileSync } from 'fs'
import { transform } from '@swc/core'

const run = async () => {
  const code = readFileSync('./source.js', 'utf-8')
    const result = await transform(code, {
    filename: "source.js",
  })
  // 输出编译后代码
  console.log(result.code)
}

run()

packaging code

In addition to escaping code, swc also provides an easy packaging capability. We create a new src folder, create two files in it: index.js , utils.js .

// src/index.js
import { log } from './utils.js'
const start = () => log('app started')
start()
// src/utils.js
export const log = function () {
  console.log(...arguments)
}
export const errorLog = function () {
  console.error(...arguments)
}

You can see that index.js imports utils.js , and then we create a new spack.config.js file, which is the configuration file packaged by swc.

// spack.config.js
module.exports = {
  entry: {
    // 打包的入口
    web: __dirname + "/src/index.js",
  },
  output: {
    // 打包后输出的文件夹
    path: __dirname + "/dist",
  },
};

Then run at the command line:

$ npx spack

After the package is successful, a web.js file dist

It can be seen not only index.js , utils.js packaged into one file, also conducted tree shaking , the utils.js not used errorLog method deleted.

Can it be used?

After all, after so many years of development, babel is far superior to swc whether it is a bug or a community activity. Therefore, if it is a small product to test the water, you can still try swc. If the old project has already used babel, it is not recommended to migrate.

In the process of using, still found some small problems. For example, if I use async function , swc will automatically import the regenerator-runtime module.

// 编译前,有个 async 方法
const start = async () => {
  console.log('app started')
}

After calling swc to compile, the code is as follows:

This result seems to be no problem, but swc is similar to babel, it also has helpers (@swc/helpers), and provides externalHelpers switch, if externalHelpers set to true , swc will import some tool classes in the form of modules.

// .swcrc
{
  "jsc": {
    "externalHelpers": true
  }
}

The externalHelpers default value is false , that this time, regenerator-runtime , in the end is in the form of import module, or the entire code is written to the file?

swc happens to have a [issue [ https://github.com/swc-project/swc/issues/1461 ]]( https://github.com/swc-project/swc/issues/1461) in discuss this issue.

In addition to the problem mentioned above, there is actually another point, that is, the author feels that there is a problem with the previous structure, and is stepping up the rewrite of version 2.0. I feel that I can look forward to it. In addition, the author of swc is a Korean brother in 1997. At present, I haven't graduated from university yet, and in the end I can only say one thing: awesome!


Shenfq
3.9k 声望6.8k 粉丝