Rust Is is at The Future of JavaScript Infrastructure This article describes the fact that Rust is popular JS infrastructure circle: Webpack , Babel , terser , prettier , ESLint these pop up only a few years ago The tools already have Rust alternatives, and the performance has been improved by 10 to 100 times.
The iterative wave of front-end infrastructure has never stopped. When these tools cover Gulp, js-beautify, tslint and other tools, the new generation of construction tools based on Rust has quietly suspended the coffin cover on webpack, babel, prettier, and terser. , Eslint on their heads, I don't know when they will be covered.
Original've got a good Chinese translation , it is worth mentioning that some of the original English nouns corresponding to specific Chinese interpretation, recorded as follows:
- Programming-Level Low:
lower programmerlevel programming. - ergonomics:
ergonomicsergonomics. - opinionated:
self-righteous, stubbornout of the box. - critical adoption:
critical adoptiontechnology selection critical point.
intensive reading
This article will not introduce how to use Rust, but will focus on some basic usages of the Rust toolchain mentioned in the original text. If you are interested, you can immediately replace the existing tool library!
swc
swc is a series of tools such as compilation, packaging, compression, etc. developed based on Rust, and it is widely used in more and higher-level JS infrastructure, which greatly promotes the influence of Rust in JS infrastructure, so it is the first introduction.
swc provides a series of atomic capabilities, covering build and runtime:
@swc/cli
@swc/cli
can build js and ts files at the same time:
const a = 1
npm i -D @swc/cli
npx swc ./main.ts
# output:
# Successfully compiled 1 file with swc.
# var a = 1;
The specific function is similar to that of babel, which allows the browser to support advanced syntax or ts, but @swc/cli
is at least 20 times faster than babel. You can do custom configuration .swcrc
file.
@swc/core
You can use @swc/core
make higher-level build tools, so it is the developer-call version @swc/cli
The basic API comes from the official website developer documentation:
const swc = require("@swc/core");
swc
.transform("source code", {
// Some options cannot be specified in .swcrc
filename: "input.js",
sourceMaps: true,
// Input files are treated as module by default.
isModule: false,
// All options below can be configured via .swcrc
jsc: {
parser: {
syntax: "ecmascript",
},
transform: {},
},
})
.then((output) => {
output.code; // transformed code
output.map; // source map (in string)
});
In fact, the cli call is changed to a node call.
@swc/wasm-web
@swc/wasm-web
can call the swc of the wsm version when the browser is running to get better performance. The following is an official example:
import { useEffect, useState } from "react";
import initSwc, { transformSync } from "@swc/wasm-web";
export default function App() {
const [initialized, setInitialized] = useState(false);
useEffect(() => {
async function importAndRunSwcOnMount() {
await initSwc();
setInitialized(true);
}
importAndRunSwcOnMount();
}, []);
function compile() {
if (!initialized) {
return;
}
const result = transformSync(`console.log('hello')`, {});
console.log(result);
}
return (
<div className="App">
<button onClick={compile}>Compile</button>
</div>
);
}
This example can do things similar to babel when the browser is running, and it can be used for runtime compilation whether it is a low-code platform or an online coding platform.
@swc/jest
@swc/jest
provides a Rust version of jest implementation to make jest run faster. The usage is also very simple, first install:
npm i @swc/jest
Then in the jest.config.js
configuration file, point the ts file compile to @swc/jest
:
module.exports = {
transform: {
"^.+\\.(t|j)sx?$": ["@swc/jest"],
},
};
swc-loader
swc-loader
is a loader plugin for webpack, instead of babel-loader
:
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
// `.swcrc` can be used to configure swc
loader: "swc-loader"
}
}
];
}
swcpack
Enhance the function of multi-file bundle into one file, basically it can be considered as a swc version of webpack, of course, the performance will be further improved swc-loader
Up to now, this feature is still in the testing stage, as long as @swc/cli
installed, it can be used. npx spack
spack.config.js
then executing 0619b34d1a8b86, which is the same as using webpack.
Deno
Deno 's linter, code formatter, and document generator are built with swc, so they also belong to the Rust camp.
Deno is a new js/ts runtime, so we always like to compare with node. quickjs is the same, these three are a kind of js language runner, as a developer, the demand is always better performance, compatibility and ecology, the three are almost indispensable, so although they cannot be completely replaced at the moment Nodejs, but it is very fragrant as a high-performance alternative. You can some cross-end and cross-platform parsers based on them. For example, 1619b34d1a8bd9 kraken is a high-performance web rendering engine based on quickjs + flutter, which is a web browser. Alternative, as a cross-terminal solution.
esbuild
esbuild is a new generation of JS infrastructure that has been widely used earlier and is a JS packaging and compression tool. Although it is written in Go, its performance is comparable to Rust, and it can be viewed together with the Rust trend.
esbuild currently has two functions: compilation and compression, which can theoretically replace babel and terser respectively.
Basic usage of the compilation function:
require('esbuild').transformSync('let x: number = 1', {
loader: 'ts',
})
// 'let x = 1;\n'
Basic usage of compression function:
require('esbuild').transformSync('fn = obj => { return obj.x }', {
minify: true,
})
// 'fn=n=>n.x;\n'
The compression function is relatively stable and suitable for use in the production environment, and the compilation function should consider too many places compatible with webpack. It can be used in the production environment after it is mature and stable. In fact, many new projects have already used esbuild in the production environment. Compile function now.
The compilation function is @swc
, but because Rust supports compiling to wsm, @swc
provides web runtime compilation capabilities, and esbuild has not yet seen this feature.
Rome
Rome is a Nodejs-based front-end infrastructure family bucket made by the Babel author, including but not limited to Babel, ESLint, webpack, Prettier, Jest. Currently plans to use Rust to refactor . Although it has not yet been implemented, we can consider Rome as a member of Rust.
rome
is a family bucket API, so you only need yarn add rome
to complete all environmental preparations.
rome bundle
packaged project.rome compile
compiles a single file.rome develop
debugging project.rome parse
parses the file abstract syntax tree.rome analyzeDependencies
analysis dependent.
Rome also merged file formatting and Lint into rome check
command, and provided friendly UI terminal prompt .
In fact, I am not very optimistic about Rome, because it is too burdensome. There are too many trivial things such as testing, compiling, Lint, formatting, compression, and packaging. It may be better to give each piece to the community. This is not even now. In the restructuring, the whole body is affected by one move.
NAPI-RS
NAPI-RS provides a high-performance connection layer from Rust to Node, which can compile Rust code into a Node callable file. The following is an example of the official website:
#[js_function(1)]
fn fibonacci(ctx: CallContext) -> Result<JsNumber> {
let n = ctx.get::<JsNumber>(0)?.try_into()?;
ctx.env.create_int64(fibonacci_native(n))
}
A Fibonacci sequence function is written above, which is implemented fibonacci_native
In order for this method to be called by Node, first install the CLI: npm i @napi-rs/cli
.
Due to the troublesome environment, we need to use this scaffolding to initialize a workbench, we write Rust in it, and then use a fixed script to publish the npm package. Executing napi new
create a project, we found that the entry file must be a js, after all, it has to be referenced by node, which myLib
like this (I created a 0619b34d1a8e10 package):
const { loadBinding } = require('@node-rs/helper')
/**
* __dirname means load native addon from current dir
* 'myLib' is the name of native addon
* the second arguments was decided by `napi.name` field in `package.json`
* the third arguments was decided by `name` field in `package.json`
* `loadBinding` helper will load `myLib.[PLATFORM].node` from `__dirname` first
* If failed to load addon, it will fallback to load from `myLib-[PLATFORM]`
*/
module.exports = loadBinding(__dirname, 'myLib', 'myLib')
So loadBinding is the entry point. At the same time, there are three system environment packages under the project folder, which can be called by different system environments:
@cool/core-darwin-x64
macOS x64 platform.@cool/core-win32-x64
Windows x64 platform.@cool/core-linux-arm64-gnu
Linux aarch64 platform.
@node-rs/helper
package is to guide node to execute the pre-compiled binary file. The loadBinding
function will try to load the binary package recognized by the current platform.
After src/lib.rs
the code of the above Fibonacci sequence, execute npm run build
compile. Note that you need to install the rust development environment before compiling. You rustup.rs Then release the current project as a node package as a whole.
After publishing, you can reference it in the node code:
import { fibonacci } from 'myLib'
function hello() {
let result = fibonacci(10000)
console.log(result)
return result
}
As a bridge between Rust and Node, NAPI-RS solves the problem of Rust gradually replacing the existing JS toolchain.
Rust + WebAssembly
Rust + WebAssembly shows that Rust has the ability to compile to wsm. Although the code performance after compilation will become slightly slower, it is still much faster than js. At the same time, due to the portability of wsm, Rust has also become portable.
In fact, it is not surprising that Rust supports compilation to WebAssembly, because one of the original positioning of WebAssembly is to be a target compilation product of other languages, and then it supports cross-platform, so it can well complete the mission of dissemination.
WebAssembly is a stack-based virtual machine ( stack machine ), so it has first-class cross-platform capabilities.
If you want to compile Rust to wsm, in addition to installing the Rust development environment, you must also install wasm-pack .
After installation, you only need to execute wasm-pack build
to compile. For more usage, please API document .
dprint
dprint, is prepared rust js / ts formatting tools, and provides dprint, node- version can be used as node packets by npm installation, from source can be seen, use NAPI the RS- accomplish.
dprint-node
can be used directly in Node:
const dprint = require('dprint-node');
dprint.format(filePath, code, options);
Parcel
Parcel strictly speaking the previous generation of JS infrastructure. It appeared after Webpack and before the Rust trend. However, since it has with SWC in , it can be regarded as keeping up with the fashion for the time being.
Summarize
The front-end family bucket already has a complete set of Rust implementations, but the compilation accuracy of stock projects needs a lot of verification, and we still need time to wait for the maturity of these libraries.
But there is no doubt that the Rust language has relatively complete support for JS infrastructure, and the rest is only the problem of the logic coverage of the tool layer, which can be solved over time. The huge performance improvement brought by the logic rewritten in the Rust language will inject great vitality into the community. As the original text said, the front-end community can introduce the Rust language for the huge performance improvement, even if this may lead to the threshold of contribution to the community improve.
The discussion address is: "Rust is the future of JS infrastructure" · Issue #371 · dt-fe/weekly
If you want to participate in the discussion, please click here , a new theme every week, weekend or Monday. Front-end intensive reading-to help you filter reliable content.
Follow front-end intensive reading WeChat public
Copyright notice: Freely reprinted-non-commercial-non-derivative-keep the signature ( Creative Commons 3.0 License )
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。