前端工具链一览

这篇文章上次修改于 4 个月前,可能部分内容已经不适用,如有疑问可询问作者。

前端工具链一览

在翻看https://github.com/VueConf/2025里面的ppt的时候 发现里面聊到的很多东西都不是很清楚是啥 写篇文章记录一下这些轮子们

The first 5 years of Vite

https://vueconf-cn-25-patak.vercel.app/8?clicks=2 走马灯来了

snowpack

22.4停止维护的一个仓库,开发团队弃坑去搞astro了

它的核心理念是 “无打包构建”(Unbundled Development) 。

在 Webpack、Rollup 或 Parcel 这类传统的打包工具(Bundler)中,你的所有项目文件(JavaScript、CSS、图片等)在开发过程中都会被合并、转换并打包成一个或几个大的 JavaScript 文件。这个过程,尤其是在大型项目中,可能会非常缓慢。 Snowpack 彻底改变了这一点,它的工作方式是:

  1. 利用原生 ES 模块 (ESM) :现代浏览器本身就支持 import 和 export 语法。Snowpack 充分利用了这一原生功能。它不会将你的整个应用打包成一个大文件,而是将你的每个文件视为一个独立的模块。
  2. 一次性处理依赖 :当你第一次启动 Snowpack 时,它会扫描你的 node_modules 目录,将你的所有依赖项(如 React, Lodash)单独处理一次,并将它们转换成浏览器可以理解的 ES 模块格式,存放在一个 web_modules 目录中。这个过程非常快,并且 只需要做一次 。
  3. 即时、单个文件构建 :在你开发时,如果你修改了一个文件,Snowpack 只需要重新构建那一个文件 ,然后浏览器会通过原生 ESM 加载机制来获取更新。由于不需要重新打包整个应用,这个更新过程几乎是瞬时的(通常在 50 毫秒以内)。

是不是很眼熟?没错,这些想法都被vite偷了。所以看着是经典八股 webpack vs vite的答案

astro

Astro 是一个现代 web 框架,专注于构建以内容驱动的网站,如博客、作品集、文档和电子商务网站。可以理解为是一个支持vue + react的 next 框架。

它的核心理念是通过在服务器上完成尽可能多的工作来减少发送到浏览ers的 JavaScript 数量,从而实现更快的网站加载速度。

主要特点:

  • 组件岛 (Component Islands): Astro 在服务器上将 UI 渲染成 HTML,并剥离所有 JavaScript。然后,对于需要交互的组件(即“岛”),Astro 会在客户端按需加载并“激活”(hydrate) 它们。这大大减少了客户端的负担。
  • UI 框架无关: 你可以自由选择并混合使用 React, Vue, Svelte, SolidJS 等多种前端框架的组件。
  • 默认静态 (SSG), 支持动态 (SSR): Astro 既支持静态站点生成,也支持服务器端渲染,提供了灵活性。
  • 内容驱动: 对 Markdown 和各种 CMS 有良好支持。

nitro

nitro的话用nuxt的会比较熟,它是 Nuxt.js 3 的后端运行和部署引擎,为服务器端渲染 (SSR) 应用程序提供最快的冷启动速度,同时也可以部署在多种环境中,包括 Serverless 平台。

写nitro就很想写faas,一个接口长这样: ts // server/api/hello.get.ts export default defineEventHandler((event) => { return { message: 'Hello from Nitro!' } })

vite-node

vite-node 是一个基于 Vite 的工具,可以在 Node.js 环境中直接运行 TypeScript 或 ESM (ECMAScript Modules) 文件,并且享受 Vite 带来的极速热更新(HMR - Hot Module Replacement)体验。

说人话版本就是,它是vite版本的 ts-node,你用vite-node去启动一个ts文件,它会自动监听文件变化,并且重启服务。

最常用的是被vitest使用,它可以导出一个ViteNodeRunner和一个ViteNodeServer,前者是可以用来执行一些vitest的测试用例,后者是可以用来启动一个vite的服务。

TS
import { createServer, version as viteVersion } from 'vite'
import { ViteNodeRunner } from 'vite-node/client'
import { ViteNodeServer } from 'vite-node/server'
import { installSourcemapsSupport } from 'vite-node/source-map'

// create vite server
const server = await createServer({
  optimizeDeps: {
    // It's recommended to disable deps optimization
    noDiscovery: true,
    include: undefined,
  },
})

// For old Vite, this is needed to initialize the plugins.
if (Number(viteVersion.split('.')[0]) < 6) {
  await server.pluginContainer.buildStart({})
}

// create vite-node server
const node = new ViteNodeServer(server)

// fixes stacktraces in Errors
installSourcemapsSupport({
  getSourceMap: source => node.getSourceMap(source),
})

// create vite-node runner
const runner = new ViteNodeRunner({
  root: server.config.root,
  base: server.config.base,
  // when having the server and runner in a different context,
  // you will need to handle the communication between them
  // and pass to this function
  fetchModule(id) {
    return node.fetchModule(id)
  },
  resolveId(id, importer) {
    return node.resolveId(id, importer)
  },
})

// execute the file
await runner.executeFile('./example.ts')

// close the vite server
await server.close()
Copy

unplugin

这个最好理解,一句话描述:Unified plugin system for build tools.

举个例子就是 ```ts import type { UnpluginFactory } from 'unplugin' import { createUnplugin } from 'unplugin'

export interface Options { // define your plugin options here }

export const unpluginFactory: UnpluginFactory = options => ({ name: 'unplugin-starter', transform: { // an additional hook is needed for better perf on webpack and rolldown filter: { id: /main.ts$/ }, handler(code) { return code.replace(//, '

Injected
') }, }, // more hooks coming })

export const unplugin = / #PURE / createUnplugin(unpluginFactory) ```

然后我们就可以进行一个导出

TS
export const vitePlugin = unplugin.vite
export const rollupPlugin = unplugin.rollup
export const rolldownPlugin = unplugin.rolldown
export const webpackPlugin = unplugin.webpack
export const rspackPlugin = unplugin.rspack
export const esbuildPlugin = unplugin.esbuild
export const farmPlugin = unplugin.farm
Copy

turbopack rspack

这俩都是用rust写的优化webpack执行效率的轮子 turbopack主要再next.js里面使用,是next.js的打包工具,还没有泛用化。 rspack则是我司研发的高性能javascript打包工具,特点是对webpack生态兼容性很好。

parcel

也是个打包工具,特色是 Zero Configuration,也就是零配置 只是个老古董了,v2.0开始于21年,核心也是用rust写的,不过它的star数比上面俩个加起来还多。 零配置听起来事不事挺牛逼的? 但是实际上它的官网例子还停留于 html + css + js ,也就是说它主要是处理这个用的 针对vue的支持也相当有限,停留于 vue 2和3的早起写法

lightning CSS

是由 Parcel 团队开发的一个用 Rust 编写的、性能极高的 CSS 工具链。 可以简单理解为rust版本的postcss,压缩速度比起postcss用的cssnano要快15倍,但是生态要差一点。 vite默认的css打包还是postcss,不过tailwind什么的有用它

rolldown

rollup的rust版本 目前vite在开发时使用 esbuild 进行预构建,在生产构建时使用 Rollup,而rolldown 的目标就是统一这两个环节,用一个 Rust 引擎同时提供开发时的高速转换和生产时的优化打包。

暂时还是个饼,现在处于公开开发中 (In Public Alpha)的状态。

oxc

oxc是一个用 Rust 编写的、高性能的 JavaScript/TypeScript 工具集合 (Toolkit) 它把打包工具的功能再拆分,拆成了独立的、可复用的“零件”,比如: - 解析器 (Parser) :将代码字符串转换为 AST(抽象语法树)。 - Linter :基于 AST 进行代码质量检查,是 ESLint 的一个极速替代方案。 - 解析器 (Resolver) :实现 Node.js 的模块解析算法。 - 转换器 (Transformer) :对 AST 进行操作,实现代码转换。 - 代码生成器 (Codegen) :将 AST 转换回代码字符串。

现在rolldown就在使用oxc的解析器,rspack也在使用Oxc 的部分组件。 其中oxlint 1.0 在今年6.10发布了

tsdown

用来优化 tsc --noEmit 这个指令

  • 定位 :一个用 Rust 编写的、与 tsc 兼容的、极速的 TypeScript 类型检查器。
  • 核心目标 :在保持与 tsc 行为一致的前提下,提供数量级的性能提升。它通过 Rust 的性能优势和大量的并行处理来实现这一点。
  • 如何工作 :它会读取你的 tsconfig.json 文件,像 tsc 一样分析你的整个项目,然后报告类型错误。它的设计目标是,对于同一个项目, tsdown 报告的错误应该和 tsc --noEmit 报告的错误完全一样。