当前位置:网站首页>Esbuild & SWC: a new generation of construction tools
Esbuild & SWC: a new generation of construction tools
2022-07-06 03:19:00 【phial03】
First , ESBuild & swc What is it? ?
ESBuild Is based on Go Language development JavaScript Bundler, from Figma front CTO Evan Wallace Development , And was also Vite Used for dependency resolution and analysis of development environment Transform.
SWC Is based on Rust Of JavaScript Compiler( Its ecology also includes packaging tools spack), At present for Next.JS/Parcel/Deno And other well-known projects in the front-end circle .
Why focus on these two tools ?
You may have encountered in your daily work , The construction time of the project increases gradually with the volume and complexity of the project , Sometimes it takes a few minutes to edit a project locally ( here @Webpack)
This is ESBuild The official website packages it 10 Share three.js Velocity contrast
SWC It claims to be better than Babel fast 20 times ( In the case of quad core, it can be fast 70 times )
that ESBuild & SWC It's really so fast ? Or the developer's own words ? Let's test it by experiment , First look at ESBuild
Let's start with a very simple piece of code
import * as React from 'react' import * as ReactServer from 'react-dom/server' const Greet = () => <h1>Hello, world!</h1> console.log(ReactServer.renderToString(<Greet />))
Then let's go through Webpack & ESBuild Build it
use ESBuild Pack it up
# compile > build-esb > esbuild ./src/app.jsx --bundle --outfile=out_esb.js --minify # Build product size and build time out_esb.js 27.4kb Done in 13ms # Run the product node out_esb.js <h1 data-reactroot="">Hello, world!</h1>
use Webpack Pack it up
# compile > build-wp > webpack --mode=production # Build products asset out_webpack.js 25.9 KiB [compared for emit] [minimized] (name: main) 1 related asset modules by path ./node_modules/react/ 8.5 KiB ./node_modules/react/index.js 189 bytes [built] [code generated] ./node_modules/react/cjs/react.production.min.js 8.32 KiB [built] [code generated] modules by path ./node_modules/react-dom/ 28.2 KiB ./node_modules/react-dom/server.browser.js 227 bytes [built] [code generated] ./node_modules/react-dom/cjs/react-dom-server.browser.production.min.js 28 KiB [built] [code generated] ./src/app.jsx 254 bytes [built] [code generated] ./node_modules/object-assign/index.js 2.17 KiB [built] [code generated] # Build time webpack 5.72.0 compiled successfully in 1680 ms npm run build-wp 2.79s user 0.61s system 84% cpu 4.033 total # function node out_webpack.js <h1 data-reactroot="">Hello, world!</h1>
Look again. swc Compilation efficiency
It's another simple ES6 Code
// Some variables declare const PI = 3.1415; let x = 1; // spread let [foo, [[bar], baz]] = [1, [[2], 3]]; const node = { loc: { start: { line: 1, column: 5 } } }; let { loc, loc: { start }, loc: { start: { line }} } = node; // arrow function var sum = (num1, num2) => { return num1 + num2; } // set const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x)); // class class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
First use Babel Translate
yarn compile-babel yarn run v1.16.0 warning package.json: No license field $ babel src/es6.js -o es6_babel.js Done in 2.38s.
Reuse swc Translate
yarn compile-swc yarn run v1.16.0 warning package.json: No license field $ swc src/es6.js -o es6_swc.js Successfully compiled 1 file with swc. Done in 0.63s.
The product comparison of the two
// es6_babel "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } var PI = 3.1415; var x = 1; var foo = 1, bar = 2, baz = 3; var node = { loc: { start: { line: 1, column: 5 } } }; var loc = node.loc, start = node.loc.start, line = node.loc.start.line; var sum = function sum(num1, num2) { return num1 + num2; }; var s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(function (x) { return s.add(x); }); var Point = /*#__PURE__*/function () { function Point(x, y) { _classCallCheck(this, Point); this.x = x; this.y = y; } _createClass(Point, [{ key: "toString", value: function toString() { return '(' + this.x + ', ' + this.y + ')'; } }]); return Point; }();
// es6 swc
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var PI = 3.1415;
var x = 1;
var foo = 1, bar = 2, baz = 3;
var node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
var loc = node.loc, start = node.loc.start, _loc = node.loc, line = _loc.start.line;
var sum = function(num1, num2) {
return num1 + num2;
};
var s = new Set();
[2,3,5,4, 5,2, 2].forEach(function(x1) {
return s.add(x1);
});
var Point = /*#__PURE__*/ function() {
"use strict";
function Point(x2, y) {
_classCallCheck(this, Point);
this.x = x2;
this.y = y;
}
_createClass(Point, [
{
key: "toString",
value: function toString() {
return "(" + this.x + ", " + this.y + ")";
}
}
]);
return Point;
}();
//# sourceMappingURL=es6_swc.js.map
It can be seen from the above data that
- In the comparison of packaged code , ESBuild The speed of (20ms) Far faster than Webpack(1680ms)
- In the comparison of compiled code , swc Also on the babel It has obvious performance advantages (0.63s vs 2.38s).
- What needs to be added is , The code used as an example is very simple , And in the comparison, all construction optimization strategies of various construction tools are not fully used , Just compare the speed of several tools under the most basic configuration , This and the list of tools benchmark The data will be different , And the construction speed is also related to the hardware performance / Runtime state .
ESBuild/swc So fast ? That's OK Webpack/Babel Throw it away ? Don't worry , current ESBuild and Swc It may not completely replace Webpack. But through this sharing, we may have a more comprehensive understanding of them , You can also explore future opportunities to use these new generation front-end tools at work
ESBuild/swc Positioning in front-end Ecology
- In today's front-end world , New tools emerge in endlessly , Sometimes there are so many different tools that I can't tell what their functions are for a while , So let's study it first ESBuild/swc Role in today's front-end engineering system .
- From the screenshot above, select several front-end engineering tools that we contact most frequently in our daily life :
- Task Runner Task runner : Developers set up scripts for the build tool to complete the development 、 structure 、 A series of tasks in deployment , What we usually use is npm/yarn The script function of ; Earlier , More popular Gulp/Grunt Such a tool
- Package Manager Package manager : This is no stranger to everyone , npm/Yarn/pnmp Help developers download and manage dependencies , It is essential for current front-end development .
- Compiler/Transpiler compiler : In the market, many browsers only support ES5 In grammar , Babel In this way Comipler It is essential in front-end development ; If you use TypeScript Words , It also needs to pass tsc perhaps ts-loader Compile .
- Bundler Packaging tools : Starting from the entrance set by the developer , Analyze module dependencies , Load and package various resources into 1 Tools for one or more files .
- Loader: Because the front-end project contains various file types and data , It needs to be transformed into JS Modules can be used and built for packaging tools . JS Of Compiler And other types of files Loader May be collectively referred to as Transfomer.
- Plugin: You can further customize the construction process , Transform the module ( Like compression JS Of Terser)
- There are also some front-end building tools that are encapsulated or add additional functions based on general building tools , such as CRA/Jupiter/Vite/Umi
- ESBuild The location is Bundler, But it's also Compiler( Yes Transform The power of code )
- swc Call itself Compiler + Bundler, But at the moment spack It's not very easy to use
ESBuild/SWC Why so fast ?
- Think about it , Go & Rust These two languages and JavaScript What's the difference between ?
ESBuild The implementation of the ( Reference resources ESBuild FAQ)
from Go Implement and compile into local code : Most of the Bundler It's all by JavaScript Realized , however CLI Apply to JIT Compiling languages are the worst performing . Each run Bundler When , JS Virtual machines are parsed from the perspective of running code for the first time Bundler( such as Webpack) Code for , No optimization information . When ESBuild In parsing JavaScript When , Node Still parsing Bundler Of JS Code
Heavy use of parallel computing : Go The design of the language itself attaches great importance to parallel computing , therefore ESBuild This will be exploited . There are three main links in the construction : analysis (Parsing), link (Linking) And code generation (Code generation), In the process of parsing and code generation, multi-core parallel computing will be used as much as possible
ESBuild Everything in the code is implemented from zero : Avoid performance problems caused by third-party libraries by implementing all logic by yourself , Unified data structure can reduce the cost of data conversion , And you can change the architecture as needed , Of course, the biggest disadvantage is that the workload is doubled .
- It's amazing SpaceX This company , A large number of parts are produced in-house , Effectively reduce production costs
Efficient use of memory : ESBuild In the implementation, try to reduce the transmission and conversion of data , ESBuild Minimize the impact on the whole AST The transfer , And reuse as much as possible AST data , Other Bundler Data formats may be converted back and forth at different stages of compilation (string -> TS -> JS -> older JS -> string…). In terms of memory storage efficiency Go Is better than JavaScript More efficient .
swc The implementation of the
- swc Our official documents and websites are not correct swc A more specific explanation of the internal implementation , According to its Blog Some analysis in , babel The main reason for the slowness is its single threaded nature
A summary
- from ESBuild and swc In the official resources of , The common point is to make good use of Parallel computing .JS Because the goal at the beginning of the design is to serve the browser scene well , So single thread & Event driven is not suitable for CPU Intensive Computing , and ESBuild/Rust It is also on this point that we are based on Node Our build tools have a systematic speed advantage .
How to use ESBuild/swc Efficiency improvement ?
- Now we know that ESBuild/Rust What does it do , And what are the characteristics , How can we use... In our work ESBuild/swc To improve our development experience ?
Use ESBuild
ESBuild stay API Very concise on the level , The main API Only two. : Transform and Build, these two items. API Can pass CLI, JavaScript, Go Method call
Transform Mainly used for the conversion of source code , The input accepted is a string , The output is the converted code
# use CLI Way to call , take ts Code to js Code echo 'let x: number = 1' | esbuild --loader=ts => let x = 1;
Build Mainly for building , The input accepted is one or more files
// use JS Mode call build Method require('esbuild').buildSync({ entryPoints: ['in.js'], bundle: true, outfile: 'out.js', })
ESBuild The type of content (Content Type) It includes ES File types that can be resolved during packaging , This and Webpack Of loader Similar concepts , The following example is used when packaging JSX Loader analysis JS file .
require('esbuild').buildSync({
entryPoints: ['app.js'],
bundle: true,
loader: {
'.js': 'jsx' },
outfile: 'out.js',
})
- ESBuild It also includes plug-in system , During the construction process (Transform API The plug-in cannot be used ) Change your build process through plug-ins
// Plug in demonstration from the official website
let envPlugin = {
name: 'env',
setup(build) {
// Intercept import paths called "env" so esbuild doesn't attempt
// to map them to a file system location. Tag them with the "env-ns"
// namespace to reserve them for this plugin.
build.onResolve({
filter: /^env$/ }, args => ({
path: args.path,
namespace: 'env-ns',
}))
// Load paths tagged with the "env-ns" namespace and behave as if
// they point to a JSON file containing the environment variables.
build.onLoad({
filter: /.*/, namespace: 'env-ns' }, () => ({
contents: JSON.stringify(process.env),
loader: 'json',
}))
},
}
// The use of plug-in
require('esbuild').build({
entryPoints: ['app.js'],
bundle: true,
outfile: 'out.js',
plugins: [envPlugin],
}).catch(() => process.exit(1))
Use in other tools ESBuild
If you think it's completely used now ESBuild Not yet mature , It can also be in Webpack Used in the system ESBuild Of loader To replace babel For code conversion , besides ,
esbuild-loader
It can also be used for JS & CSS Minimize your code .
const { ESBuildMinifyPlugin } = require('esbuild-loader') module.exports = { rules: [ { test: /.js$/, // Use esbuild As js/ts/jsx/tsx loader loader: 'esbuild-loader', options: { loader: 'jsx', target: 'es2015' } }, ], // Or use esbuild-loader As JS Compression tool optimization: { minimizer: [ new ESBuildMinifyPlugin({ target: 'es2015' }) ] } }
Be careful
- ESBuild Can't turn ES5 Code and some other Syntax , Please refer to esbuild.github.io/content-typ…
Use Vite
- Want to say 2021 New tools with high attention in the front-end circle in , Vite It can be said to be among the best , that Vite and ESBuild/swc What does it matter ?
- Vite The core idea of is to use ESM+ Compile language tools (ESBuild) Speed up local operations
- Vite In the development environment ESBuild Pre build , In the production environment Rollup pack , It is also possible to use ESBuild Build the production environment .
- Support ES5 Need to introduce plug-ins github.com/vitejs/vite…
Use swc
Comilation
have access to swc Command line tools (swc/cli) coordination The configuration file Compiling Files
# Transpile one file and emit to stdout npx swc ./file.js # Transpile one file and emit to `output.js` npx swc ./file.js -o output.js # Transpile and write to /output dir npx swc ./my-dir -d output
swc The core of swc/core There are three main types API
- Transform: Code conversion API, Enter the source code => Output the converted code
- Parse: Analyze the source code , Output AST
- Minify: Minimize code
swc Also launched swc/wasm modular , Allows users to use... In a browser environment wasm Code conversion
If you want to Webpack Use under the system swc( replace babel), You can also use swc-loader
Bundle
- ️swc It also supports packaging , But at present, the function is not very complete , And there are many in use Bug. The author is currently trying to use spack Pack a simple React The application is not yet successful , You can't use it out of the box
- at present swc Of Bundle The tool is called spack, Later, it will be renamed swcpack.
- Packaging can be done through spack.config.js File
A little summary and thinking
Full text summary
ESBuild/swc It is a new generation of front-end tool written in compiled language , Yes JS The build tool written has a system level speed advantage
ESBuild Can be used to compile JS Code and module packaging , swc It is claimed that it can support both, but its packaging tool is still in the early stage of development
At present, these two tools cannot completely replace Webpack And other mainstream tools have developed a huge ecosystem in recent years
When the existing infrastructure is stable and the replacement cost is high , You can try to use new tools incrementally (loader) perhaps Vite This is based on ESBuild Construction tools for secondary packaging
Extended thinking
Continue to pay attention to the new development of front-end Ecology , Make good use of the open source community to improve R & D efficiency and experience .
While using new tools , Understand or participate in the technical principles behind it , Go It can be used as a server language , Rust It can be used as a system programming language , Learning a new language can open up a new Xintiandi , Beauty is not true ?
Reference material :
边栏推荐
- 建模规范:命名规范
- 真机无法访问虚拟机的靶场,真机无法ping通虚拟机
- svg拖动点裁剪图片js特效
- Shell 传递参数
- February 14, 2022 Daily: Google long article summarizes the experience of building four generations of TPU
- Audio-AudioRecord Binder通信机制
- SWC介绍
- JS音乐在线播放插件vsPlayAudio.js
- Quartz misfire missed and compensated execution
- SD card reports an error "error -110 whilst initializing SD card
猜你喜欢
随机推荐
Recommended foreign websites for programmers to learn
MADDPG的pythorch实现——(1)OpenAI MADDPG环境配置
jsscript
C # create self host webservice
SD卡报错“error -110 whilst initialising SD card
Add one to non negative integers in the array
IPv6 comprehensive experiment
Polymorphic day02
Some problem records of AGP gradle
Leetcode problem solving -- 173 Binary search tree iterator
Codeforces 5 questions par jour (1700 chacune) - jour 6
如何做好功能测试
建模规范:命名规范
[Li Kou] the second set of the 280 Li Kou weekly match
svg拖动点裁剪图片js特效
Audio-AudioRecord Binder通信机制
Résumé des méthodes de reconnaissance des caractères ocr
电机控制反Park变换和反Clarke变换公式推导
Mysql database operation
My C language learning record (blue bridge) -- on the pointer