张泽亚把前端工程化理解为针对具体问题组织研发的过程。复杂业务里,写代码只是链路的一部分;需求、调试、构建、测试和发布之间的等待与协作,也决定团队能否稳定交付。
这段分享来自深圳“前端的挑战与机遇”录播第 3 段,所属稿件发布于 2022 年 5 月 9 日。文中是张泽亚当时在飞书文档及此前团队的经历,工具选择、指标和规划均保留历史语境。
工程化覆盖完整生命周期
前端承担的业务越来越复杂,工程化的目标,是把软件工程的方法用于开发、部署和维护,用规范、框架与工具解决效率、质量和性能问题。脚手架、构建优化和流水线都是手段,任何一项单独存在,都不等于完整的工程化体系。
团队可以先观察实际工作流,沉淀适合自己的规范,再通过工具落实;平台则把分散的能力连接起来,减少开发者在不同入口之间切换。脚手架解决初始化,SSR、国际化等解决方案处理特定业务需求,两者可以进一步组合成工程框架。但这些能力仍应尽可能可拆分,让团队按需要接入。原片 00:32—06:20
团队视角不同,收益与约束也不同
小型业务可能只需要顺畅的本地环境和发布链路,过多规范反而增加负担。复杂业务更重视统一治理;中台团队可能专注于抽象某一项公共能力,如云构建、检查和资源发布。
个体开发者又有另一种感受:完整框架需要学习,规范会限制自由,短期操作甚至可能更繁琐。张泽亚没有回避这种矛盾。他认为设计时要尽量照顾使用体验,但评价最终应回到团队整体是否更有效,而不是只看某一次个人操作是否更快。原片 06:21—09:31
先确认业务阶段和可度量的痛点
他提出两个前提:没有适用所有团队的方案,也不能脱离产品所处阶段谈建设。业务基本能力还未完善时,过度投入基础设施可能得不偿失;但只顾眼前交付,也可能留下将来难以处理的债务。
实践起点是可观察的问题,例如启动时间、热更新时间、单元测试覆盖、构建与发布耗时。再看可用人力和长期目标,优先利用公司已有设施或合适的开源方案。自行造轮子需要理由,不能因为工具看起来先进就引入。原片 09:34—13:21
规范也不只有 lint 或 Git 工作流,还包括按业务还是文件类型组织目录、如何限制模块依赖,以及团队使用怎样的语言与接口约定。最终要通过低成本入口落实,最好能在 IDE、CLI 等日常环境完成常用操作,而不是让开发者记住一串分散的平台网址。原片 13:22—15:16
从规范到自动流转,而不是只增加流程
张泽亚说明,自己没有参与飞书文档最初的基础建设,因此先用此前团队的经历解释常见顺序:规范工作流、提供业务脚手架、接入工程框架能力,再沉淀组件与自动化流程。
到了多人参与的大工程,收益更多来自把调试、构建、发布等环节接起来。在约定时间触发检查、通知和流程推进,必要时由人确认,比反复手工协调更可控。片中对未来自动化的期待也有明确边界:流程可自动通知和流转,不代表代码冲突或业务判断能完全由机器解决。原片 15:16—18:38
飞书文档面对的五类问题
他首先交代既有基础设施:代码托管、在线编译、部署、监控、机器人和开放 API 等能力已经存在,业务工程化很多时候是在这些能力之上整合,而不是从零再造全部平台。
问题主要来自业务本身:付费协作产品对稳定性要求高;工程体积增长使编译和本地更新变慢;跨团队功能可能互相影响;产品希望快速迭代,但大量代码集中进入版本又增加质量压力;复杂上下文让单个开发者很难独立定位所有问题。一次客户反馈可能需要不断拉入上游、下游同事,大家才逐渐拼齐线索。原片 18:38—22:58
依赖、编译与目录结构,分别减掉什么成本
依赖安装方面,团队当时迁移到 pnpm,并根据依赖描述与锁文件等信息判断能否复用已有安装结果,减少重复安装。构建侧则重视中间产物缓存,并尝试把相对稳定的依赖预先处理,降低每次需要重新编译的范围。
本地开发还尝试更快的构建工具。张泽亚明确区分了当时团队用于本地提速的试验与生产环境采用的方案;这不构成对某个工具普遍“不适合生产”的结论。
代码组织则从按文件类型集中,转向按 feature 聚合,以减少大量组件和状态文件混在同一目录带来的理解成本。它解决的是定位、职责和依赖问题,不会仅靠换目录名字就自动降低业务耦合。原片 22:59—25:45
微前端拆分为什么没有消除所有重量
在导航天然隔离的后台系统里,子应用边界相对容易确定;文档业务却不同。一篇文档可能插入表格、多维表格或其他内容,同一个能力又会出现在不同场景,模块之间有真实依赖。
因此,拆分需要先重构和解耦。即使子应用可以独立运行,开发者仍可能依赖一个很重的基座。张泽亚坦陈,基座本身成为进一步提速的阻碍,继续简化与重构仍是当时的工作方向。微前端是应对巨石工程的手段,同时也带来新的运行和协作成本。原片 25:47—27:45
source map 要可用,也要控制访问
生产排查需要把错误映射回源码,但团队不希望 source map 随公开资源暴露。片中介绍的做法,是把生成与上传的一部分工作移出主要上线等待路径,另行处理并上传到受权限控制的平台。
这个方案同时关心两件事:能否在排查时取得匹配版本的信息,以及正常上线是否必须等待所有辅助产物。安全、调试和发布速度需要共同设计,不能只把生成 source map 当成一个孤立的构建开关。原片 27:45—29:03
多人改动合在一起,怎样逐层检查
每个需求通过自己的测试,并不意味着合到同一个版本后就不会互相影响。团队因此在不同阶段设置检查:低成本访问开发测试包,使用预发布环境,运行单元与端到端测试,再对即将进入发布流程的版本进行集成测试。
张泽亚强调,接入测试工具并不是最难的一步,更难的是针对具体业务写出有效测试。片中介绍当时每周版本在发布前还安排集成检查,不能把某个固定天数当作所有团队的标准。原片 29:03—31:21
通过之后,再逐步扩大使用范围:先是相关内部团队,再到更大的内部用户群,观察版本表现,配合回归测试推进。前端资源托管与配置服务负责按用户群下发对应版本。多地区、预发、线上和其他环境的部署,则通过自定义流水线减少手工操作。原片 31:22—33:46
能看见,不等于已经能使用
性能部分专门区分了 Time to View 与 Time to Use。SSR 可以让内容更早出现,但不代表复杂文档已经完成初始化、能够响应操作。工程体量、拆分后的加载以及弱网等因素,仍会影响可用时间。
片中提到团队观察过较长的等待与尾部场景,并以版本性能报告检查改善或退化。这里的数值是当时业务指标,不能作为当前飞书性能结论;更值得保留的是,性能定义要贴近用户能否真正完成操作,而不是只看页面什么时候有内容。原片 33:47—35:17
平台整合的三层结构
他把整合方式分为三层。最上层是开发者直接使用的环境,包括开发服务器、脚手架、IDE 插件、CLI、CI 和机器人;中间是业务定制 API,把公司平台和业务自建能力统一收口;底层则是构建、部署、版本灰度、框架与组件等设施。
中间层使团队可以围绕自己的流程组合能力,又不需要在每个客户端入口重复实现。微前端开发时使用线上基座还是本地基座,也可以在这种统一入口中安排。组件与设计语言则帮助不同端和产品保持一致。原片 35:17—37:42
哪些问题当时仍没有完成
张泽亚把工程化比作先看症状再选择处理方式:有些问题能用现成工具缓解,有些需要影响更大的重构。他没有宣称前面五类问题已经全部解决。
后续方向包括深入编译环节提速,把更多操作收敛到 IDE、浏览器和 IM,自动协调审查、审批、测试与修复流程,以及建设更完整的性能实验室。团队当时已有性能报告的雏形,但仍希望增加独立稳定运行、与同类产品比较、按版本输出完整报告和支持事故前后分析的能力。把已落地部分与这些目标区分开,才能理解工程化是在持续建设,而不是一次完成。原片 37:42—43:15
