Introducing the new high-performance Javascript and Typescript compiler which is written in Rust and the demonstrations at Tiki Co., Ltd. (tiki.vn)
Internal sharing session at Tiki Co., Ltd. on September 8 2022 by Thien Ly
_________________
On September 8, I held a presentation about a Javascript and Typescript compiler for my team at TIKI. It is the SWC - the new high-performance compiler written in Rust with customizable plugin API. This could make some massive enhancements to the DX(development experience) for your team in Node and Browser Products.
Read more about the SWC document here: https://swc.rs
#javascript #share #development #dx #typescript #compiler #slide #rust
1. A glance at the SWC
Speedy web compiler - written in Rust
2. About
- An extensible Rust-based platform for the next generation of fast developer
tools
- Main features: transform (to ecma targets, add new syntaxes,... ),
bundling(swcpack - still in development), ast parser,
- Used by tools like Next.js, Parcel, and Deno, the list goes on
- Used by companies like Vercel, ByteDance, Tencent, Shopify, etc.
*** SWC is 20x faster than Babel on a single thread and 70x faster on four cores.
(according to swc.rc)
3. Why SWC (pros)
Extensibility: allow extend features with plugin, in js(have bottleneck issue) or in rust
Performance: see page 2. (picture below: benchmarks for transform to es5)
WebAssembly: support for WASM => super fast even in browser environment
Community: ecosystem are bing and still expanding.
4. Why not SWC (cons)
Rust is new to learn:
Challenging learning curve —>
Bottleneck with other tools:
It can make the build process faster, but it may
not, if we have still Webpack, legacy babel
loaders, or swc js plugin in the pipe, to do
some work.
Source: humb1t
5. Why not SWC (cons)
Rust is new to learn:
Challenging learning curve —>
Bottleneck with other tools:
It can make the build process faster, but it may
not, if we have still Webpack (or with some
legacy babel loaders) in the pipe, to do some
work.
Source: humb1t
6. How SWC runs in Node/ Browser
On Nodejs:
using Foreign Function Interface (via Node C++ AddOn, https://nodejs.org/api/addons.html)
On Browser:
Rust core => Wasm => run directly in browser(see @swc/wasm )
7. plugin: javascript plugin
- Like babel plugin, but interfaces are not
- Have bottleneck issue: because the core which is written in rust has a high
performance but js plugin, which traveling on AST, is not
- Showcase: @formatjs/swc-plugin
8. Native Rust plugins
Extend from babel: see https://swc.rs/docs/migrating-from-babel
Provide from swc_project: see github.com/swc-project/plugins
Custom plugins:
=> To have a glance: let’s make one simple plugin
9. Example and practice
Setup env:
# install rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# install rust cli
cargo install swc_cli
# VSCODE setup rust language server
code --install-extension rust-lang.rust-analyzer
10. Example and practice
clone source plugin source code
# for quicker setup, clone this repository:
github.com/cute-me-on-repos/test-ts-miniapp.git
git checkout -b main/<.>
11. Example and practice
Init source plugin source code (target wasm32-wasi):
# init plugin with the name “tini-swc-plugin”:
swc plugin new --target-type wasm32-wasi tini-swc-plugin;
rustup target add wasm32-wasi # add target
cd tini-swc-plugin
12. Example and practice
Explaining simple example from document:
https://swc.rs/docs/plugin/ecmascript/getting-started
Then write our own one —> next page
13. Example and practice
# Practice problem:
Problem:
We want to limit some of the web Apis that users want to access in tini app;
Write a swc rust plugin to travel the AST of 1 js file and replace all statements
(include [`this`, `self`, `global`]) that refer to the global scope, except `this`
of Component/Page/App, with `(void 0)`(undefined).
Requirement: quick docs researching skill =))
14. Example and practice
# input:
```js
this;global; // thoses should be remove
global.unAllowWebApiCall();
(function unknow(){
this.unAllowWebApiCall();
})();
Page({
onLoad(){this.setData({value:”hi”})}
})
```
15. Example and practice
# output:
```js
(void 0);(void 0);
(void 0).unAllowWebApiCall();
(function unknow(){
(void 0).unAllowWebApiCall();
})();
Page({
onLoad(){this.setData({value:”hi”})}
})
```