跳到主要内容
版本:0.15

为什么需要 Farm?

随着 web 项目规模的扩大,构建性能已经成为主要瓶颈,对于一个庞大的项目,使用 webpack 编译可能需要 10min 甚至更多,一次 hmr 更新可能需要 10s 甚至更多,严重降低了研发效率。

因此我们急需极速的构建工具,解决项目编译性能问题。然后 vite/snowpack 这样的 unbundled 工具应运而生,此类工具主要有下面三个特性:

  1. 使用原生 ESM,在 dev server 启动时不对源文件进行编译和打包,源文件在入口模块执行时才会通过浏览器请求 dev server 编译,编译后的产物返回给浏览器
  2. HMR 时,只重新编译一个模块,这样 HMR 的时间约等于一个模块的编译时间
  3. 对外部依赖(如 node_modules 下的依赖)进行预打包

这使得 dev 服务器热启动和 HMR 非常快,但 vite 等工具使用的 Unbundled 模式并不完美,对于大型项目来说仍然存在很大的问题:

  • 大量的模块请求:对于一个大型项目,使用上述策略 1、2,首次启动可能需要加载数千个模块,使用原生模块系统加载数千个模块会导致浏览器卡住甚至崩溃。虽然 Dev Server 的启动快了,但是请求时的模块的首次编译依然会耗费大量时间,会有数十秒起步的白屏,编译时间只是转移了,并没有消失。
  • 开发和生产之间的不一致:出于兼容性和请求数量、请求层级的考虑,原生 ES 模块在大多数情况下无法在生产中使用。 因此 vite 选择在生产环境选择用 rollup 打包。 这就带来了不一致,当这种不一致导致生产错误时,调试起来非常困难且非常痛苦。 而 vite 在 dev 中使用 esbuild,在生产中使用 rollup,这更加就放大了不一致性。
  • 而 Vite 在 dev 上之所以这么快,esbuild 功不可没,它是用 go 编写的。 Go 利用了原生平台的优势,远快于 Js。

事实上,我们真正需要的是一个快速、强大、一致的 Web 构建工具,可以在解决上述问题的基础上,提供更加极致的编译效率。因此我们开发了 Farm。

备注

Farm 的设计主要都是针对 web 浏览器场景(包括 pc、移动、webview 等等),期望从构建速度到资源加载速度全方面提升 web 性能。因此 Farm 不会尝试成为一个传统意义上的通用打包器,Farm 的打包只是为了减少资源请求时的模块数量。

不过 Farm 不仅仅是一个用 Rust 重写的打包工具,它还有很多强大且先进的设计:

Farm 设计理念

  • 性能优先:一切都会用 Rust 编写,只有少数不是性能瓶颈的部分会用 JS 编写
  • 一致性:默认情况下确保开发和生产完全相同,您在开发中看到的将与您在生产中得到的相同。
  • 局部打包:Farm 的打包目标不是将所有东西打包在一起,而是限制资源的请求数量。 Farm 会根据依赖关系和资源大小将您的项目捆绑成 20-30 个小资源,在不损失缓存粒度的情况下获得最佳的资源加载性能。
  • 所有资源视为一等公民:Farm 不再需要将所有内容转换为 Javascript,它将任何内容视为一等公民,如 htmljs/jsx/ts/tsxcss/scsspng/svg/...都是 Farm 支持的基础模块,更多类型的模块可以通过插件支持。
  • 兼容性:Farm 将适用于旧版 (ES5) 和现代浏览器。
  • Rollup 风格的插件系统:轻松创建自己的插件,并轻松从 rollup/vite/webpack 迁移您的插件/项目。

Farm 的目标是成为真正的下一代构建工具,快速、强大、一致,并为 Web 开发人员提供最佳的开发体验。