#构建
Review
- 2022/11/28
- 2023/02/05
- 2024-09-15
[!Summary] 构建工具实现的优化
- 体积:压缩、按需、分包、TreeShaking
- 异步
- 文件合并:减少HTTP资源请求数
一、简介 #
构建工具的价值 #
- 支持模块化:部分浏览器不支持ES Module的方式,需要将源代码转换成浏览器支持的格式
- 更好的兼容性:解决CSS、JS代码的浏览器兼容性问题
- 代码压缩:对HTML代码、CSS代码、JS代码、图片等资源进行压缩
- TreeShaking:对未使用的代码代码进行删除
- CodeSplit(代码分割):将较大的文件分离成多个较小的文件,与HTTP2使用极大提升加载速度
- 代码合并:将较小的文件进行合并,文件多又小,在HTTP1中效率较低,浏览器最大支持6个TCP连接
- 支持解析广泛的文件类型:对 .jsx、.tsx、.vue、.less、.sass等文件进行解析,转换成浏览器能识别的代码(loader解析)
- 进行代码校验以及类型校验
- 对第三方模块进行抽离
- 提前使用一些JS的新特性
- 延迟加载/异步加载
二、流行构建工具 #
构建工具细分为2种
- 转译器:将一门高级语言转译为另一个语言,如TS转译为JS、ES6转译为ES5;
- 打包器:将项目中的各种文件如png、SASS、JSON等打包成期望的形式;
2.1、转译器 #
- Babel(JS)
babel-loaderfor Webpack - ESBuild(Go)
esbuild-loaderfor Webpack - SWC(Rust)
swc-loaderfor Webpack - TSC(TS)
ts-loaderfor Webpack - Traceur
- Closure Compiler
2.2、打包器 #
- Browserify
- Grunt
- Gulp(JS)
- Rollup(JS) https://github.com/rollup/rollup
- Webpack https://webpack.js.org/
- Razzle
- ESBuild(Go)
- SWC(Rust) https://swc.rs/
- Bun(Zig)
- Parcel(JS/Rust hybrid)
- Vite(JS/Go hybrid via esbuild)
- napi-rs(Rust)
- Turbopack(Rust)
- Snowpack(JS)
- Rome(Rust)
- Nx(TS)
- WMR(JS)
- Rspack(Rust)
- Rolldown
- tsup https://github.com/egoist/tsup The simplest and fastest way to bundle your TypeScript libraries. powered by esbuild.
- tsdx https://github.com/jaredpalmer/tsdx Zero-config CLI for TypeScript package development.
- wp2vite: https://github.com/tnfe/wp2vite
- Farm(Rust) https://github.com/farm-fe/farm
打包器主要有2类
- 通过监听源代码变化然后重新构建项目将打包后的代码推送到浏览器的传统模式
- 通过浏览器原生module实现动态打包的Bundleless模式
痛点 随着前端的项目越来越大,无论是项目的启动时间,还是项目的打包时间,变得越来越长,短则四、五分钟,长则十几二十分钟。Webpack 打包速度成为了前端开发的最大痛点之一。
趋势 基于系统级原生语言实现更高构建效率的Bundleless工具
- ESBuild
- SWC
- Bun
- Turbopack
为什么开始尝试Bundleless
- 启动和热更新所等待的时间越来越长
- HTTP/2.0多路复用
- 浏览器基本都支持ESM
- 原生的解决了代码依赖和复用的问题
- 越来越多的NPM包拥抱ESM
三、详细调研 #
3.1、Turbopack #
Turbopack 是 Webpack 的作者 Tobias Koppers 使用 Rust 语言开发一个前端模块化的工具,按作者构想 Turbopack 的目标是取代 Webpack。官方宣称 TurboPack 的速度比 Vite 快 10 倍,比 Webpack 快 700 倍。
功能和特点
- 增量计算和函数级别的缓存
- 按需编译:在浏览器中访问项目的首页地址,该页面的以及所依赖的组件才会被编译,而这种按需编译的机制,减少程序的重复工作,提升开发人员的工作效率。
- SWC 编译器:大部分 Webpack 的项目编译都是使用 Babel 编译和转换,由于 Babel 本身也是使用 Javascript 编写,转换效率并不理想,而 Turbopack 原生使用 SWC( https://swc.rs/) 作为编译器。
- 本地持久化:未来编译结果不仅仅缓存在内存当中,还会本地持久化。只需重新打包新的被修改的页面。
- Imports:支持 CommonJS、ESM
- 框架支持:原生支持 JSX/TSX
Turbopack 想替代 Webpack 急需解决的一个是生态问题,以及提供尽可能低成本的迁移方案。当迁移后的收益远大于迁移成本,Turbopack 完全取代 Webpack 也不是没有可能。就目前而言,未来一段时间内 Webpack 依然是主流的前端的工具。
3.2、SWC #
https://github.com/swc-project/swc SWC is an extensible Rust-based platform for the next generation of fast developer tools. It’s used by tools like Next.js, Parcel, and Deno, as well as companies like Vercel, ByteDance, Tencent, Shopify, and more.
SWC can be used for both compilation and bundling. For compilation, it takes JavaScript / TypeScript files using modern JavaScript features and outputs valid code that is supported by all major browsers.
SWC is 20x faster than Babel on a single thread and 70x faster on four cores.
Features SWC is designed to be extensible. Currently, there is support for:
- Compilation
- Bundling (swcpack, under development)
- Minification
- Transforming with WebAssembly
- Usage inside webpack (swc-loader)
- Improving Jest performance (@swc/jest)
- Custom Plugins
3.3、Parcel #
https://github.com/parcel-bundler/parcel Parcel is a zero configuration build tool for the web. It combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production application.
Features #
- 😍 Zero config – Parcel supports many languages and file types out of the box, from web technologies like HTML, CSS, and JavaScript, to assets like images, fonts, videos, and more. It has a built-in dev server with hot reloading, beautiful error diagnostics, and much more. No configuration needed!
- ⚡️ Lighting fast – Parcel’s JavaScript compiler is written in Rust for native performance. Your code is built in parallel using worker threads, utilizing all of the cores on your machine. Everything is cached, so you never build the same code twice. It’s like using watch mode, but even when you restart Parcel!
- 🚀 Automatic production optimization – Parcel optimizes your whole app for production automatically. This includes tree-shaking and minifying your JavaScript, CSS, and HTML, resizing and optimizing images, content hashing, automatic code splitting, and much more.
- 🎯 Ship for any target – Parcel automatically transforms your code for your target environments. From modern and legacy browser support, to zero config JSX and TypeScript compilation, Parcel makes it easy to build for any target – or many!
- 🌍 Scalable – Parcel requires zero configuration to get started. But as your application grows and your build requirements become more complex, it’s possible to extend Parcel in just about every way. A simple configuration format and powerful plugin system that’s designed from the ground up for performance means Parcel can support projects of any size.
不足 #
- 生态不够完善
- 配置项较少
- 缺少高级功能:缺少code splitting, Tree shaking等
3.4、Webpack #
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.
Core Concepts #
特性 #
- 模块化支持:CommonJS、AMD、ES6
- 优秀的Loaders和Plugins设计:压缩、代码分离(code splitting)等
- 生态丰富
不足 #
- 构建速度较慢
- 体积较大:将所有代码转换为模块,并引入一些必要的运行时依赖
- 配置复杂:配置项较多
- 依赖项管理复杂:
3.5、Vite #
Vite (French word for “quick”, pronounced
/vit/, like “veet”) is a new breed of frontend build tooling that significantly improves the frontend development experience. It consists of two major parts:
- A dev server that serves your source files over native ES modules, with rich built-in features and astonishingly fast Hot Module Replacement (HMR).
- A build command that bundles your code with Rollup, pre-configured to output highly optimized static assets for production.
Features #
- 💡 Instant Server Start:Vite 使用了浏览器内置的 ES 模块化支持,从而可以实现“按需编译、按需加载”的特性,使得开发服务器可以快速响应页面请求,无需等待整个项目打包完成。
- ⚡️ Lightning Fast HMR:Vite 使用了浏览器原生的模块热更新技术,能够实现组件级别的热更新,减少了开发时的刷新时间和手动刷新的次数。
- 🛠️ Rich Features:Vite 不仅支持 Vue.js,还支持 React、Preact 等多种前端框架。
- 📦 Optimized Build
- 🔩 Universal Plugin Interface
- 🔑 Fully Typed APIs
不足 #
- 对于旧浏览器支持较差
- 社区较小、生态还不完善
- 不是原生支持CommonJS,可以通过rollup plugin支持
3.6、Nx #
Nx is a smart, fast and extensible build system with first class monorepo support and powerful integrations.
支持的Workspace包括
- Package-based monorepo
- Integrated monorepo
- Standalone React app
- Standalone Angular app
- Standalone Node server
npx create-nx-workspace@latest3.7、ESBuild #
The main goal of the esbuild bundler project is to bring about a new era of build tool performance, and create an easy-to-use modern bundler along the way.
Major features #
- Extreme speed without needing a cache:无需缓存的极速
- JavaScript, CSS, TypeScript, and JSX built-in:内置默认支持多种语言
- A straightforward API for CLI, JS, and Go:提供简单的API给CLI、JS、Go调用
- Bundles ESM and CommonJS modules:支持ESM、CommonJS模块
- Tree shaking, minification, and source maps
- Local server, watch mode, and plugins
3.8、Farm #
Farm is an extremely fast vite-compatible web-building tool written in Rust. Benchmark against other tools (using Turbopack’s benchmark, 1000 React components) as shown below: