There is a lot of rust going on around the front end, and everything that can be written in Rust can be written in Rust. Today’s tool is Bable: SWC, a tool that converts ES6 to ES5.

And on the SWC website, it’s pretty straightforward to say that it’s aligned with Babel, SWC and Babel commands are interchangeable, and most Babel plug-ins are already implemented.

One of the advantages of using Rust is that it is fast. For example, on one of our previous projects, when we replaced Babel with SWC, the compilation speed went from 7 seconds to 1 second.

Get started

SWC, like Babel, splits command line tools and build core modules into two packages.

  • @swc/cliSimilar to the@babel/cli;
  • @swc/coreSimilar to the@babel/core;
npm i -D @swc/cli @swc/core
Copy the code

You can run the following command to convert an ES6 JS file to ES5.

npx swc source.js -o dist.js
Copy the code

Here is the code for source.js:

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

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

The configuration file

SWC, like Babel, supports configuration files similar to.babelrc:.swcrc in JSON format.

{
  "jsc": { // Compile rules
    "target": "es5".// Output the js specification
    "parser": {
      In addition to ecmascript, typescript is also supported
      "syntax": "ecmascript".@babel/plugin-transform-react-jsx
      "jsx": false.// Whether to support decorators, corresponding to the plugin @babel/plugin-syntax-decorators
      "decorators": false.// Whether dynamic import is supported, the corresponding plug-in @babel/plugin-syntax-dynamic-import
      "dynamicImport": false./ /...
      // Most of Babel's plug-ins can be found here
    },
    "minify": {}, // Enable compression for configurations related to compression
  },
  "env": { // Compile the configuration related to the result
    "targets": { // The result needs to be adapted to the browser
      "ie": "11" // Only compatible with IE 11
    },
    "corejs": "3" // Version of corejs
  },
  "minify": true // Whether to enable compression
}
Copy the code

The Babel plugin system is integrated by SWC into the jSC.Parser configuration, which is basically taken care of by most plug-ins. Furthermore, SWC also inherits compression capabilities, enabled through the Minify property, jSC.minify, which is used to configure the rules related to compression. For more details, see the documentation.

Node APIs

By importing the @SWc /core module into node.js code, you can directly compile the code by calling the API in Node.js, which is routine for CLI tool development.

// 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",})// Prints the compiled code
  console.log(result.code)
}

run()
Copy the code

Packaging code

In addition to escaping code, SWC provides a simple packaging capability. Let’s create a new SRC folder and create two new files: index.js and utils.js.

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

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

// spack.config.js
module.exports = {
  entry: {
    // Pack the entry
    web: __dirname + "/src/index.js",},output: {
    // Package the output folder
    path: __dirname + "/dist",}};Copy the code

Then run from the command line:

$ npx spack
Copy the code

Once packaged successfully, a web.js file is output in the dist directory.

As you can see, not only is index.js and utils.js packaged into a file, but also tree shaking, removing the errorLog method that is not used in utils.js.

Does it work?

After all, Babel has been around for so many years that both bug losses and community activity are far better than SWC’s. Therefore, if it is a small product to test the water, you can still try SWC, and old projects that already use Babel are not recommended to migrate.

In the use of the process, or found some small problems. For example, if I use async function, SWC will automatically import the Regenerator-Runtime module.

// Before compiling, there is an async method
const start = async() = > {console.log('app started')}Copy the code

After compiling by calling SWC, the code is as follows:

This seems to work, but SWC, like Babel, has helpers (@swc/helpers) and provides the externalHelpers switch. If externalHelpers is set to true, SWC will import some utility classes as modules.

// .swcrc
{
  "jsc": {
    "externalHelpers": true}}Copy the code

If the default value of externalHelpers is false, regenerator-Runtime should be imported as a module or written to a file.

SWC has an issue [https://github.com/swc-project/swc/issues/1461] on this issue.

In addition to the problem mentioned above, there is another point that the author thinks there is something wrong with the previous architecture and is working hard to rewrite version 2.0, which can be expected. By the way, the author of SWC is a Korean boy who was born in 1997 and has not graduated from university yet. Finally, I can only say: awesome!