浮之静

ViteConf 2023:Vite 即将 Rust 化

此文原本想对 ViteConf 2023[1] 做一个汇总,但因视频过于庞大(时长 12 个小时),故先将尤大分享的 Vite 部分整理出来。

ViteConf 干货满满,尤大的分享中最值得关注的就要数 Rolldown 了,它为 Vite 现有痛点提供了新的解决方案。

Image

Vite

Vite[2] 是支撑着全球增长最快的前端生态系统的下一代构建工具。

  • npm 每周下载量:7,200,000+

  • GitHub Stars:60,000+

Image

Image

Vite 生态

Vite 正在迅速崛起为一个共享的基础平台,吸引着越来越多的项目在其基础上构建和发展。令人兴奋的是,这些项目不仅仅满足于基础应用,而是在各自的领域中进行着前所未有的创新。

Vite 妥善平衡了低级别复杂性的抽象和高级用户及框架的灵活性。这不仅降低了入门门槛,提供了友好的开发体验,同时也确保了对于高级应用和多变需求的充分支持。

  • Storybook v7 提供一流的 Vite 支持:预先捆绑以提高速度、零配置设置、无需 Webpack 以及更小的安装大小(First-class Vite support in Storybook[3])

  • Angular v16 使用 Vite 作为开发服务器(Angular v16 is here![4])

  • Preact[5] 在 6 月份将默认工具切换为 Vite,推荐使用 create-vite 来快速开始一个项目

  • Redwood v6 完全构建在 Vite 之上(RedwoodJS Vite Configuration[6])

  • Bun v0.7 开始支持 Vite(bun vite support[7])

  • VitePress[8] 静态网站生成器

  • 与 Remix[9] 合作,探索向 Vite 迁移,已取得重大进展

  • ...

Vite 痛点 & 挑战

痛点

  • 相对缓慢的生产构建速度:目前仍使用 rollup 作为生产构建,本地开发使用 esbuild 或 Bun

  • 开发与生产环境之间的不一致:Vite 使用混合策略。开发使用 esbuild 预构建,使用 Native ES 模块提供源代码;生产使用 Rollup 来捆绑所有资产,CommonJS 在处理和转换时有时会出现轻微的不一致,最终导致难以调试。

  • 开发过程中存在未捆绑 ESM 的网络开销:如果开发者项目中包含大量未捆绑 ESM 时,网络开销会大幅影响初始页面加载速度。

  • 混乱的 SSR 外部问题

  • 对代码块分割的有限控制:与 ES 构建相比,虽然 Rollup 已经提供了很大灵活性,但与 Webpack 的完全支持自定义相比,还是有些差距

  • 缺乏首方模块联合(First-party Module Federation)支持:了解更多 Module Federation[10]

挑战

  • 大多数问题需要在打包工具(bundler)层面解决(Vite 内部有两个捆绑器:esbuild 和 Rollup)

  • esbuild(或 Bun)速度极快,但:

    • 对构建资源优化的控制非常有限:比如控制块的分割方式

    • 插件 API 不够灵活:比如当尝试将多个插件连接在一起以处理同一文件类型时

  • Rollup 成熟且灵活,但:

    • 与原生打包工具相比仍然较慢

    • ESM/CJS 交互操作的处理可以改进

  • 两个打包工具都无法完全替代对方,并且存在微妙的行为不一致性

Rolldown

尤大透露团队正在开发 Rolldown,它是 Rollup 的 Rust 移植版。目的并不是为了取代现有的工具 esbuild 或 Rollup,只是为了更好地满足一些特定需求,使 Vite 用户受益。

  • 专注点:在尽可能与 Rollup 兼容的前提下,重点关注性能

  • 目标:在对终端用户影响最小的前提下,在 Vite 中替换 esbuild 和 Rollup

它将为 Vite 提供:

  • 显著更快的生产构建速度

  • 更强的开发/生产一致性

  • 更稳健的 SSR 依赖处理

  • 更多关于代码块分割的控制

当然,这将是一项庞大的工作!

  • 目前状态:初步的工作进行中!(计划在年底前开源)

  • 核心贡献者是前 rspack[11] 团队成员(rspack 是字节开源的一个基于 rust 实现的前端打包工具,对标 Webpack)

  • 与 rspack 团队合作,在 OXC[12] 基础上进行建设(Oxc 是一套为 JavaScript 和 TypeScript 创建的高性能工具,基于 Rust 实现。它正在构建一个解析器、linter、格式化程序、转译器、压缩器、解析器……)

  • 与 @lukastaegert[13](rollup 核心维护者) 合作以确保与 Rollup 的一致性

如果 Vite 对你的使用场景来说过于庞大,Rolldown 当然也可以作为一个独立的依赖项使用。它还可以提高 Vitest[14] 和 Nitro[15] 的性能。

Vite Roadmap

计划将通过四个阶段逐步完善和升级打包和构建过程,最后将 Vite 的一部分功能通过 Rust 和 Rolldown 进行重写或优化,以提高整体性能和提供更多的构建模式。

  • 阶段 1:基础打包

    • 替换 esbuild 用于依赖预打包:CommonJS & 仿 ESM(faux-ESM)兼容性

  • 阶段 2:高级打包

    • 与 Rollup 功能对齐:插件兼容性、Tree-shaking、高级代码块分割控制等

  • 阶段 3:内置转换

    • TypeScript

    • JSX

    • 代码压缩(minification)

    • 语法降级(syntax lowering)

  • 阶段 4:使用 Rust 重构 Vite

    • Rolldown 暴露插件容器作为 API

    • Vite 引入一个以 Rolldown 为依赖的 Rust 核心

    • 使用 Rust 重构 Vite 内部关键插件和 ssrLoadModule 转换

    • 提供与未捆绑 ESM(unbundled ESM)相对的全包模式(full-bundle mode)

Vite 版本日志

Vite 4.0 (2022.12)

  • 升级到 Rollup 3(3.0.0 changelog[16])

    • 最低 Node.js 要求:Rollup 现在至少需要 Node 14.18.0 来运行。

    • 插件和 API 更改:许多插件上下文函数和插件钩子已被移除或修改。

    • 新特性:包括按块调用 output.banner/footer/intro/outro 的函数,插件可以访问完整的块图表等。

    • 构建输出:增加了关于动态导入在 CommonJS 输出中的处理,允许控制动态导入在生成 CommonJS 输出时是以 import(...) 还是包装过的 require(...) 形式被输出。

    • 警告和弃用:一些之前被弃用的特性已被移除,而其他一些特性开始显示弃用警告。

    • 错误处理:改进了Rollup 抛出的错误信息的清晰度和一致性。

    • 性能优化:避免在发出数千个资产时的性能问题。

  • 就重大变更而言,这是一个小得多的主版本。目标是为了最大化利用生态,而推出的一个稳定版。CI 确保与下游项目的兼容性,以便更改对最终用户的影响尽可能小。

  • 使用 SWC 支持的 React 插件 @vitejs/plugin-react-swc[17]

    • 快速刷新(比 Babel 快约 20 倍)

    • 启用自动 JSX 运行时(Babel 在 v7.9.0 版本中引入此特性,相关阅读:Introducing the New JSX Transform[18] 和 A new JSX transform[19]

Vite 4.1 (2023.02)

  • 同步 Rollup 和 esbuild 版本

  • react 插件变化显著

    • plugin-react 修复了很多 HMR bug

    • 支持 SWC 的 Vite 版本,添加了对 SWC 插件的支持。

Vite 4.2 (2023.03)

  • 改进源代码调试体验

    • 修复 Chrome 开发工具在显示相对路径时的异常

    • 通过 x_google_ignoreList 从堆栈跟踪中排除某些文件的源映射,做到错误堆栈追踪仅关注你在意的部分(相关阅读:vite server.sourcemapIgnoreList[20] 和 The x_google_ignoreList source map extension[21])

Vite 4.3 (2023.04)

与 Vite 4.2 相比,4.3 带来了全面的速度提升(Vite 4.3 is out![22])。

Image

Vite 4.4 (2023.07)

  • 实验性支持 Lightning CSS[23](基于 Rust 实现的 CSS 编译工具链),注意:它目前与其他 CSS 处理器互斥。

  • create-vite[24] 添加 solid 和 qwik 模板。

Image

Vite 5.0 (当前处于 beta 版)

  • 最低 Node.js 版本要求 18+

  • CommonJS API 已弃用。注意:并未对其进行删除,如果你仍在使用 Vite 中的通用 API,也不会有任何问题。但会收到警告,督促你转向 ESM API。

Rust 在前端

继上一篇《下一代 Web 开发生态》没过多久,没想到 ViteConf 就带了 Rolldown 这样的重磅消息(Vite 逐渐 Rust 化)。

随着前端工具链的 Rust 程度加深,不难预测,Rust 在未来必将会是高级前端需要掌握的编程语言(即使不打算学习,也要尽可能多的了解一些基本概念,因为框架打包,配置,插件开发都将会遇到 Rust 的身影)。

前端入门

前端要学 Rust,我觉得有几个不错的方向:

  • 各种命令行小工具

  • Rust 通过 wasm-pack[25] 编译为 WebAssembly,运行在浏览器

  • 通过 NAP-RS[26] 扩展 Node.js 模块

  • 通过 Tauri[27] 开发跨平台应用

  • …

当然,也可以看看我写的《Rust 在前端》系列教程。

想要进技术交流群的,请在关注公众号后
发送 “rust fe”

References

[1]

ViteConf 2023: https://viteconf.org/23

[2]

Vite: https://vitejs.dev

[3]

First-class Vite support in Storybook: https://storybook.js.org/blog/first-class-vite-support-in-storybook

[4]

Angular v16 is here!: https://blog.angular.io/angular-v16-is-here-4d7a28ec680d

[5]

Preact: https://preactjs.com

[6]

RedwoodJS Vite Configuration: https://redwoodjs.com/docs/vite-configuration

[7]

bun vite support: https://bun.sh/blog/bun-v0.7.0#vite-support

[8]

VitePress: https://vitepress.dev

[9]

Remix: https://remix.run

[10]

Module Federation: https://webpack.js.org/concepts/module-federation

[11]

rspack: https://www.rspack.dev

[12]

OXC: https://github.com/web-infra-dev/oxc

[13]

@lukastaegert: https://twitter.com/lukastaegert

[14]

Vitest: https://github.com/vitest-dev/vitest

[15]

Nitro: https://github.com/unjs/nitro

[16]

3.0.0 changelog: https://github.com/rollup/rollup/blob/master/CHANGELOG.md#300

[17]

@vitejs/plugin-react-swc: https://github.com/vitejs/vite-plugin-react-swc

[18]

Introducing the New JSX Transform: https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

[19]

A new JSX transform: https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154

[20]

vite server.sourcemapIgnoreList: https://vitejs.dev/config/server-options.html#server-sourcemapignorelist

[21]

The x_google_ignoreList source map extension: https://developer.chrome.com/articles/x-google-ignore-list

[22]

Vite 4.3 is out!: https://vitejs.dev/blog/announcing-vite4-3.html

[23]

Lightning CSS: https://github.com/parcel-bundler/lightningcss

[24]

create-vite: https://github.com/vitejs/vite/tree/main/packages/create-vite

[25]

wasm-pack: https://github.com/rustwasm/wasm-pack

[26]

NAP-RS: https://github.com/napi-rs/napi-rs

[27]

Tauri: https://github.com/tauri-apps/tauri