Farm火了!比RspackVite更快的打包方案!
大家好,很高兴又见面了,我是高级前端进阶,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
高级前端进阶
今天给大家带来的主题是Farm,即一个快速、强大、本地与生产环境保持一致的Web打包器,目标是解决Vite面临的主要问题。话不多说,直接开始!1。Vite的不足
随着web项目规模的扩大,构建性能成为了开发者面临的主要问题。对于一个巨大的前端项目而言,使用webpack编译可能需要10分钟甚至更长时间,而热更新可能需要超过10s,从而大大降低了前端开发的效率。
随着vite的出现,它在开发模式下使用原生的ESM(即非打包模式),同时使用esbuild预打包依赖项,极大提升了应用开发服务器启动和热更新效率。但是非打包模式(Unbundled)并不完美,对于大型项目来说还是有很大的问题:海量模块请求:对于一个大型项目,可能需要加载的模块有上千个,使用原生模块系统加载上千个模块会导致浏览器卡死甚至崩溃。Dev和Production不一致:在大多数情况下,本地模块不能直接用于生产环境。因此,非打包工具在生产环境中依然需要打包流程,从而导致Dev、Production不一致。当这种不一致导致生产错误时,调试起来非常麻烦、痛苦。而vite选择在dev环境使用esbuild,在production中使用rollup,这进一步扩大了不一致性。Vite在dev环境之所以这么快,是因为esbuild,esbuild是用go编写的。Go利用了原生平台的优势,比Js快得多。2。Farm的出现
鉴于Vite的现状和面临的问题,Farm认为,前端开发者需要一个快速、强大、本地生产环境一致的Web打包器,从而解决Vite面临的问题。
其实,Farm不仅仅是一个用Rust重写的普通打包器,它还包括很多强大和进步的设计。在性能方面,Vite与其他工具的基准测试(使用Turbopack的基准测试,1000个React组件)数据如下:
不论是在冷启动,热更新等方面,Farm比Webpack(纯JS打包)、Vite(本质也算Rust方案)、Turbopack(Rust方案)、Rspack(Rust方案,字节开源)等都有显著的优势。
值得一提的是,Farm的作者是brightwu(吴明亮),曾就职于字节跳动和腾讯。Farm开源时间不到一年,在Github上已有500的star,是一个值得持续关注的项目。3。Farm的设计理念性能至上:能用Rust编写的模块都用Rust,只有少数不是性能瓶颈的部分沿用JSdevproduction一致性:确保开发和生产完全一致,即在开发中看到的与在生产中得到的一样。部分打包:Farm的打包目标不是把所有东西都打包在一起,而是限制资源的请求数量。Farm会根据依赖关系和资源大小,将项目打包成2030个小资源,在不损失缓存粒度的情况下获得最佳的资源加载性能。Web资产的一等公民支持:Farm不需要将所有内容转换为Javascript,它将任何资源都视为一等公民,如html、jsjsxtstsx、cssscss、pngsvg等等都是Farm支持的基础模块,更多资源可以通过插件支持。兼容性:Farm适用于旧版(ES5)和现代浏览器。Rollup风格的插件系统:易于创建自己的插件,并且易于从rollupvitewebpack迁移插件项目。
Farm的目标是成为真正的下一代构建工具,快速、强大、多环境一致,并为Web开发人员提供最佳的开发体验。4。使用Farm
Farm需要Node16及以上版本,如果开发者使用的是Linux,请确保操作系统版本为ubuntu22及以上(GLIBC2。32)。4。1创建Farm项目
farmfecli包提供创建、启动和构建Farm项目或Farm插件的能力。使用如下创建命令来初始化一个新的Farm项目。npxfarmfeclilatestcreate
需要注意的是:create命令目前只支持初始化一个简单的React项目,但是已经在逐步增强功能阶段。4。2开始项目
首先执行install命令,可以选择喜欢的包管理器,npm或yarn或pnpm:cdfarmreactnpminstallnpmcdfarmreactyarnyarncdfarmreactpnpminstallpnpmnpmstart开始项目
直接通过浏览器访问地址http:localhost:9000即可开始。4。3配置项目
该项目由项目根目录下的farm。config。ts文件配置,比如下面是farm。config。ts的内容:import{defineConfig}fromfarmfecoredistconfig;exportdefaultdefineConfig({与编译相关的选项compilation:{input:{可以是相对路径或绝对路径index:。index。html,},output:{path:。build,publicPath:,},。。。},与开发服务器相关的选项server:{port:9000,。。。},附加插件配置plugins:〔〕,});4。4FarmRoadMap
目前,Farm已经实现了Web构建工具的基本功能,但是要用于生产环境部署还有很多事情要做。Web资产(html、css、jsjsxtstsx、静态资产等)的解析、加载、转换和资源生成。懒编译DevServer和HMR(支持快速响应)部分打包Rust和Js插件系统SourceMap支持ResourcesMinimize(暂未支持)TreeShake(暂未支持)Cssmodules(暂未支持)类Sass的官方插件(暂未支持)持久缓存(暂未支持)
如上列表所示,目前Farm很多生产部署功能还依然在开发中,值得期待!5。Farm高级特性5。1懒编译
当涉及到一个大项目时,开发者可以拆分成小块并按需加载,这可以通过动态导入来实现。constpageReact。lazy(()import(。page));懒加载
默认情况下,Farm会延迟编译这些动态导入,只有在真正需要模块时才编译它们。5。2部分打包(PartialBundling)
回到webpack,开发者经常使用splitChunks来拆分bundle,试图优化资源加载时间和提高缓存命中率。但是配置splitChunks很复杂,有时达不到想要的效果。
所以Farm引入了PartialBundling,根据依赖关系和资源大小自动将应用程序打包到多个资源中。5。3StaticAssets静态资源
从v0。4Farm开始支持三种资源加载方式:url,inline,raw。下面是url模式:importrocketUrlfrom。assetsrocket。svg;returntheurlofthisimageexportfunctionMain(){returnimgsrca2020imgdataimg。jpgdatasrc{rocketUrl};usingtheurl}
使用query?inline告诉Farm想要内联资产,然后资产将转换为base64,例如:importerimportlogofrom。assetslogo。png?inline;logoisabase64strtheimagemoduleexportdefaultdata:imagepng,base64,xxxxx;
例如,使用?raw告诉Farm想要读取资产的原始字符串importimportlogofrom。assetslicense。txt?raw;returnthecontentstringoftheassetslicense。txtexportdefaultMITxxxx;5。4Script脚本
Farm支持开箱即用地编译JsJsxTsTsx,默认将JsxTsx编译为React。importButtonfrom。Button;functionButtonGroup(props:ButtonProps){return({props。buttons。map((b)(Button{b}Button))});}
默认情况下Farm使用swc来编译脚本,可以使用compilation。script修改配置。6。本文总结
本文主要和大家介绍Farm,即一个快速、强大、本地与生产环境保持一致的Web打包器,目标是解决Vite面临的主要问题。当然,正如文中所言,Farm的很多能力还在陆续开发、增强中,但是它目的非常明确,是一个值得长期关注的方案。
因为篇幅有限,文章并没有过多展开,如果有兴趣,文末的参考资料提供了优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!
参考资料
https:farmfe。github。iodocswhyfarm
https:github。comfarmfefarm
https:github。comfarmfeperformancecompare
https:farmfe。github。iodocsfeaturesstatic
https:farmfe。github。iodocsfeaturesscript