Farm 持久化缓存(Persistent Cache)完全指南:增量构建原理与配置实战
前端构建构建工具开发工具【免费下载链接】farmExtremely fast Vite-compatible web build tool written in Rust项目地址https://gitcode.com/gh_mirrors/fa/farm点击查看免费下载Farm 从v0.14.0起支持将编译结果持久化到磁盘通过compilation.persistentCache开启后热启动hot start与热构建hot build可显著提速官方文档给出的实测数据显示编译时间最高可减少80%。本文将基于 website/docs/advanced/persistent-cache.md 的完整内容结合 packages/core/src/config/normalize-config/normalize-persistent-cache.ts 与 crates/core/src/config/persistent_cache.rs 等源码系统讲解持久化缓存的开关方式、失效校验规则、缓存键生成策略、构建依赖追踪以及插件适配注意事项帮助你在真实项目中安全、高效地开启并使用这一能力。一、为什么需要持久化缓存冷启动与热启动的差距Farm 本身是基于 Rust 编写的高性能构建工具单次编译已经很快但面对大型项目如 Ant Design Pro 级别的应用每次启动都重新解析、加载、转换全部模块仍然耗时。持久化缓存的核心思路是把上一次编译得到的模块转换结果、依赖图信息、资源产物等序列化到磁盘下次启动时直接复用跳过可跳过的构建阶段。官方文档使用 examples/arco-pro 项目给出了冷启动无缓存与热启动有缓存的对比数据阶段冷启动无缓存热启动有缓存提升幅度start启动1519ms371ms减少 75%build构建3582ms562ms减少 84%从源码实现看Farm 的缓存体系由 crates/core/src/cache/mod.rs 中的CacheManager统一管理内部包含module_cache模块及模块依赖图的缓存resource_cache最终资源资源束的缓存plugin_cache各插件自定义数据的缓存custom / lazy_compile_store自定义缓存与懒编译缓存。CacheManager在构造时会根据配置创建CacheType::Disk磁盘缓存或CacheType::Memory内存缓存磁盘缓存通过DiskCacheFactory落地到指定目录crates/core/src/cache/mod.rs。二、开启与关闭缓存persistentCache 配置2.1 一键开启使用compilation.persistentCache即可开启/关闭缓存import { defineConfig } from farmfe/core; export default defineConfig({ compilation: { persistentCache: true, }, });注意persistentCache配置在compilation字段下而buildDependencies示例中出现了直接写在顶层的情况实际使用时请统一放在compilation.persistentCache内。2.2 默认值展开true 等价于完整对象官方文档明确persistentCache: true等价于以下完整配置({ persistentCache: { // 缓存存储目录 cacheDir: node_modules/.farm/cache, // 缓存命名空间 namespace: farm-cache, buildDependencies: [ farm.config.ts, farmfe/core, farmfe/plugin-react, // ... 其他所有依赖 ], moduleCacheKeyStrategy: { timestamp: true, hash: true, }, }, });这一展开逻辑在 Rust 侧有直接印证。在 crates/core/src/config/persistent_cache.rs 中get_default_config返回的默认对象正是namespace: farm-cachecache_dir: node_modules/.farm/cache基于 root 解析为绝对路径module_cache_key_strategy: { timestamp: true, hash: true }envs、build_dependencies为空后者由 Node 侧填充而PersistentCacheConfig::default()返回Bool(true)即不配置时默认开启。配置为false则完全禁用缓存。此外在 normalize-persistent-cache.ts 中还有一个细节当检测到禁用缓存的环境开关isDisableCache()时persistentCache会被强制置为false。2.3 完整配置项速查依据 compilation-options.mdpersistentCache的类型定义如下export type PersistentCache | boolean | { namespace?: string; // 默认 farm-cache cacheDir?: string; // 默认 node_modules/.farm/cache buildDependencies?: string[];// 默认 farm.config 及其全部深层依赖 moduleCacheKeyStrategy?: { timestamp?: boolean; // 默认 true hash?: boolean; // 默认 true }; envs?: Recordstring, string; // 默认 Farm Env见环境变量与模式 globalBuiltinCacheKeyStrategy?: { define?: boolean; // 默认 true buildDependencies?: boolean; // 默认 true lockfile?: boolean; // 默认 true packageJson?: boolean; // 默认 true env?: boolean; // 默认 true }; };三、缓存校验Cache Validation什么情况会导致缓存失效缓存并非无条件复用。Farm 在尝试复用缓存前会按以下条件校验任一条件发生变化全部缓存立即失效Env 对象由persistentCache.envs配置默认为Farm Env Mode即process.env.NODE_ENV、process.env.DEV、process.env.PROD详见 Environment Variables and Modes。lockfile如果package-lock.json、yarn.lock或pnpm-lock.yaml发生变化意味着依赖集合有变动缓存整体失效。构建依赖Build Dependencies由persistentCache.buildDependencies配置任一构建依赖文件发生变化全部缓存失效。缓存命名空间Cache Namespace不同namespace下的缓存互不通用。想强制清空全部缓存时换一个新的namespace即可。内部缓存版本Internal Cache VersionFarm 内部维护一个缓存版本号当 Farm 自身版本变化且可能影响输出例如渲染优化时会提升缓存版本号触发全部缓存失效。该版本号在 crates/core/src/cache/store/constant.rs 中以常量FARM_CACHE_VERSION当前为0.9.1定义并作为缓存目录的组成部分。如果发现缓存不生效请优先排查以上条件若缓存已损坏可直接删除node_modules/.farm/cache目录手动清除。3.1 缓存目录的磁盘结构从 crates/core/src/cache/store/disk.rs 可以看到缓存目录的层级组织方式{cacheDir}/{FARM_CACHE_VERSION}-{cacheDir 末级目录名}/{namespace}/{development 或 production}/...即在cacheDir基础上追加FARM_CACHE_VERSION前缀目录 →namespace子目录 → 按开发/生产模式区分的子目录。这从实现层面印证了「内部缓存版本 命名空间 环境模式」共同参与缓存隔离的设计也解释了为何手动清缓存时删掉node_modules/.farm/cache即可。3.2 自定义环境变量参与缓存键envs使用persistentCache.envs指定额外的环境变量键值对参与缓存键计算。当其中任一值变化时全部缓存失效import { defineConfig } from farmfe/core; export default defineConfig({ compilation: { persistentCache: { envs: { MY_API_URL: process.env.MY_API_URL ?? , }, }, }, });在 persistent_cache.rs 中所有envs键会先排序再拼接成keyvaluekeyvalue...字符串经sha256哈希后作为一条「配置哈希」追加到buildDependencies中最终参与全局缓存键计算——因此任何 env 值的变化都会改变哈希进而使整份缓存失效。3.3 全局内置缓存键策略globalBuiltinCacheKeyStrategypersistentCache.globalBuiltinCacheKeyStrategy控制哪些内置键参与缓存失效判断。默认情况下define、buildDependencies、lockfile、packageJson、env这五类变化都会让整份缓存失效可针对已知不会影响构建的键选择性关闭import { defineConfig } from farmfe/core; export default defineConfig({ compilation: { persistentCache: { globalBuiltinCacheKeyStrategy: { define: true, // define 配置变化时失效缓存 buildDependencies: true, // 构建依赖变化时失效缓存 lockfile: true, // lockfile 变化时失效缓存 packageJson: true, // package.json 变化时失效缓存 env: true, // env 模式变化时失效缓存 }, }, }, });源码中的默认值在 normalize-persistent-cache.ts 中定义随后与用户配置浅合并且该策略字段不会透传给 Rust 侧会在归一化时删除见第 54 行。其底层行为是env: true时把已解析的用户 env 全部并入persistentCache.envs第 56-61 行define: true时把config.define的每个键值非字符串值会先JSON.stringify并入envs第 63-81 行——这也解释了为什么源码注释写明「所有 define 选项都应进入 envs」packageJson: true时读取 root 下package.json中type、name、exports、browser、main、module六个关键字段作为package.json[键名]形式的 env 键值第 86-107 行lockfile: true时自动把package-lock.json、yarn.lock、pnpm-lock.yaml追加进buildDependencies第 113-124 行。四、构建依赖Build Dependencies构建依赖是指可能影响编译过程或编译产物的依赖例如插件或配置文件。任一构建依赖发生变化全部缓存即失效。buildDependencies中的每一项可以是文件路径也可以是包名例如import { defineConfig } from farmfe/core; import path from node:path; export default defineConfig({ compilation: { persistentCache: { buildDependencies: [ // 一个文件路径 path.resolve(process.cwd(), ./plugins/my-plugin.js), // 一个包名注意该包必须暴露 package.json farm-plugin-custom-xxx, ], }, }, });默认情况下所有配置文件及其依赖都会被纳入如果希望额外添加一些文件或依赖来触发缓存失效通过buildDependencies追加即可一旦这些文件变化全部缓存失效。从 normalize-persistent-cache.ts 可以看到默认追踪逻辑的完整实现若存在configFileDependencies直接复用否则调用traceDependencies深度追踪配置文件的依赖绝对路径的依赖直接加入buildDependencies以字符串/数组形式声明的 Rust 插件plugins中类型为string或数组的项会通过require.resolve(${p}/package.json)解析为包名版本号形式的依赖键如farmfe/plugin-react1.x.x版本号变化即触发缓存失效。在 Rust 侧persistent_cache.rs 会把全部构建依赖排序拼接后统一做sha256哈希并将该哈希追加到cacheDir后面作为最终实际使用的缓存目录——构建依赖变了哈希就变等于换了一个全新的缓存目录这就是「全部缓存失效」在实现层面的具体体现。五、模块缓存键策略Module Cache Key StrategyFarm 提供两种策略控制模块缓存键的生成方式timestamp检查模块的更新时间戳若时间戳未变化则跳过该模块的构建性能最优hash在load与transform之后检查内容哈希若内容未变化则跳过该模块后续的构建阶段。默认两者同时开启即{ timestamp: true, hash: true }。两种策略的取舍在于timestamp最快但依赖文件系统时间戳的准确性hash更严谨但需要先执行load/transform才能拿到内容做比对。更细化的行为可参考 compilation-options.mdtimestamp: true且模块时间戳未变化时load、transform等构建阶段钩子全部跳过直接复用缓存的模块hash: true且内容未变化时仍会调用load和transform获取转换后的内容其余钩子跳过并复用缓存模块。5.1 Node 目标下的自动降级Farm 会在output.targetEnv为node时自动将timestamp置为false。该逻辑在 normalize-persistent-cache.ts 中实现——因为 Node 环境下模块文件可能由外部进程写入或热更新时间戳判断不可靠必须依赖内容哈希保证正确性。六、插件适配注意事项Caveats For Plugins这是持久化缓存最容易踩坑的地方当timestamp开启时load、transform等所有构建阶段钩子都不会被调用。因此如果插件依赖load/transform收集信息却未实现plugin_cache_loaded与write_plugin_cache钩子插件行为可能不符合预期。典型反例某插件在load与transform中收集信息、在finish钩子中统一输出就必须实现plugin_cache_loaded加载缓存与write_plugin_cache写入缓存两个钩子否则热启动时拿不到数据。这两个钩子在 Rust 侧是Plugintrait 的一部分crates/core/src/plugin/mod.rs 与 crates/core/src/plugin/mod.rsplugin_cache_loaded(self, cache: Vecu8, context)命中缓存时把插件缓存字节数据交还给插件write_plugin_cache(self, context) - OptionVecu8构建结束时插件返回自己的序列化缓存数据。调用链位于 plugin_driver.rs 与 plugin_driver.rsplugin_cache_loaded会在构建开始时遍历所有插件从PluginCacheManager读取以插件名非字母数字字符替换为_为键的缓存并逐个回调write_plugin_cache则在结束时收集各插件返回的数据写入缓存。底层存储由 crates/core/src/cache/plugin_cache.rs 的PluginCacheManager负责写盘前还会对缓存内容再做一次sha256摘要参与键管理。另外Plugintrait 还提供了handle_persistent_cached_module钩子crates/core/src/plugin/mod.rs命中持久化缓存的模块会先经过该钩子返回false即可主动失效该模块的缓存——这是插件在缓存命中时进行二次校验如自定义校验逻辑的扩展点。七、实战排查与调优建议确认开启检查配置文件中compilation.persistentCache是否为true默认即为 true或完整对象并确认没有禁用缓存的环境开关生效。看缓存目录构建后查看node_modules/.farm/cache下是否出现以FARM_CACHE_VERSION前缀命名的目录目录中包含 namespace 子目录与farm-cache.json清单文件constant.rs。缓存不生效按「缓存校验」一节逐条排查——env 是否变化、lockfile 是否变化、buildDependencies 指向的文件是否变化、namespace 是否被改动、Farm 版本是否升级。手动清缓存删除node_modules/.farm/cache目录或直接换一个namespace。Node/SSR 场景output.targetEnv为node时 timestamp 自动关闭属预期行为不必手动干预。开发自定义插件只要插件依赖load/transform且需要跨构建保留状态就必须成对实现plugin_cache_loaded与write_plugin_cache否则请在缓存策略或插件逻辑上做出取舍。参考资源官方文档原文website/docs/advanced/persistent-cache.md配置参考website/docs/config/compilation-options.mdpersistentCache小节环境变量与模式website/docs/features/env.md配置归一化实现packages/core/src/config/normalize-config/normalize-persistent-cache.tsRust 侧配置与默认值crates/core/src/config/persistent_cache.rs缓存管理器与磁盘存储crates/core/src/cache/mod.rs、crates/core/src/cache/store/disk.rs插件缓存机制crates/core/src/cache/plugin_cache.rs、crates/core/src/plugin/plugin_driver.rs赞分享前端构建构建工具开发工具【免费下载链接】farmExtremely fast Vite-compatible web build tool written in Rust项目地址https://gitcode.com/gh_mirrors/fa/farm点击查看免费下载相关推荐JAX 持久化编译缓存Persistent Compilation Cache配置与原理完全指南JAX 持久化编译缓存Persistent Compilation Cache配置与原理完全指南 JAX 的编译缓存Persistent Compilat机器学习深度学习Dragonfly 高级技巧5个实用方法优化你的附件处理流程Dragonfly 高级技巧5个实用方法优化你的附件处理流程 Dragonfly 是一款强大的 Ruby gem专为动态处理附件而设计特别适合在 Rail人工智能机器学习深度学习编译器高性能计算vllm-ascend 持久化增量 csrc 构建缓存Persistent Incremental Csrc Build Cache设计全解析vllm ascend 持久化增量 csrc 构建缓存Persistent Incremental Csrc Build Cache设计全解析 导读 本文基人工智能大模型模型推理服务AscendCANN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MATLAB虹膜识别实战:从定位到匹配的完整链路与避坑指南

MATLAB虹膜识别实战:从定位到匹配的完整链路与避坑指南

简介:这份资源聚焦虹膜识别中的特征提取环节,面向正在学习生物特征识别、图像处理或准备相关课程设计的学生与开发者,帮助理解如何用2D-Gabor滤波器从归一化虹膜图像中提取二进制特征编码。压缩包共10个文件,约939KB,包…

2026/10/13 16:18:31 阅读更多 →
MySQL 4.0 实战指南:老版本环境搭建、避坑与迁移要点

MySQL 4.0 实战指南:老版本环境搭建、避坑与迁移要点

简介:《MySQL 4.0.pdf》是一份聚焦MySQL 4.0版本的开源关系型数据库参考资料,适合数据库管理员、后端开发人员及系统学习数据库原理的读者,用于理解经典版本的功能体系与运维思路。资源为单个PDF文件,压缩包仅334KB,内…

2026/10/13 16:17:31 阅读更多 →
C++刷题指南:双指针反转、区间反转与原地扩容的字符串三题精讲

C++刷题指南:双指针反转、区间反转与原地扩容的字符串三题精讲

最近又刷了一轮力扣字符串题,把 344、541 和一道很经典的“替换数字”放到一起过了三遍。这三题单独看都不难,C 解法也都不超过 30 行,但把它们串在一起刷,你会发现它们正好覆盖了字符串操作中最容易被忽略的三类基本功&#xff1…

2026/10/13 16:17:31 阅读更多 →

最新新闻

虚拟机+Linux入门:从安装配置到快照恢复的完整指南

虚拟机+Linux入门:从安装配置到快照恢复的完整指南

直接学Linux的人,十有八九第一堂课都是在装虚拟机。我自己当年学Linux,一开始直接拿一台老笔记本去装系统,结果分区的时候手一抖,把资料盘给格了,那种酸爽至今记忆犹新。后来老老实实按部就班用虚拟机,才发…

2026/10/13 16:54:42 阅读更多 →
SpringBoot+Vue3+MyBatis乡村政务办公系统开发与部署全解析

SpringBoot+Vue3+MyBatis乡村政务办公系统开发与部署全解析

身边不少朋友做过政务类的管理系统,我经手的项目里也有不少类似的诉求。乡村政务办公系统这类项目,看起来就是典型的CRUD加权限管理,但真正落地时,细节远比想象中多。尤其是面对乡、村两级的工作人员,系统不光要功能完…

2026/10/13 16:54:42 阅读更多 →
t3code:轻量级代码片段管理方案,纯文本与可检索的极简实践

t3code:轻量级代码片段管理方案,纯文本与可检索的极简实践

1. 项目缘起与核心定位第一次看到“t3code”这个名字,我下意识以为是某个新出的终端工具或者代码片段管理器。翻了一圈社区讨论和零散的项目描述之后才反应过来,它其实是一个面向轻量级代码片段与结构化文本的极简组织方案——你可以把它理解成“给开发者…

2026/10/13 16:54:42 阅读更多 →
用 CLI 终结团队代码规范之争:t3code 的设计与落地

用 CLI 终结团队代码规范之争:t3code 的设计与落地

大概半年前,我们团队在 Code Review 时的画风是这样的:有人坚持单引号,有人只用双引号;有人习惯把工具函数丢进utils.ts,有人喜欢按业务模块建helpers文件夹;新同事入职第一周,光适应"潜规…

2026/10/13 16:54:42 阅读更多 →
用Python打造Mercari新品扫描器:轻量爬虫与增量去重实战

用Python打造Mercari新品扫描器:轻量爬虫与增量去重实战

简介:mercari-scanner 是一套基于 Python 的 Mercari 新商品扫描与提醒工具,面向海淘代购人群和二手市场研究者,旨在解决手动刷新页面容易错过心仪商品的问题。工具支持通过命令行参数 --min-price 与 --max-price 设置价格区间,并…

2026/10/13 16:54:42 阅读更多 →
AI能力图谱日报:从热词到工程落地的决策指南

AI能力图谱日报:从热词到工程落地的决策指南

1. 这份“AI 日报”不是新闻简报,而是一份动态能力图谱很多人看到“AI 日报(2026年10月6日)”这个标题,第一反应是点开看今天又出了什么大模型、哪家公司发了新论文、又有哪个开源项目爆火了——就像刷微博热搜那样扫一眼就划走。…

2026/10/13 16:53:41 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →