百度日志中台前端重构实践

日志中台是百度内部针对打点数据的全生命周期管理平台,作为公司日志数据的唯一入口,承担以下核心职能:1.功能覆盖:提供从数据采集、传输、存储到查询分析的一站式服务,支持产品运营分析、研发性能监控、运维管理等多元场景。2.业务赋能:通过标准化流程实现用户行为日志的埋点申请、审批及退场管理,助力APP端、服务端等业务线挖掘数据价值。3.生态协同:与大数据平台、推荐中台、性能平台深度联动,避免重复建设,提升资源利用率,强化业务中台能力。

01 项目背景

2020年初启动的日志中台前端项目,随着业务发展逐渐暴露出严重问题。整个前端项目技术负债多,有500多个文件,共11万多行源码。项目已经变得老旧而臃肿。面临线上bug频发、排查问题效率低下等各种问题,陈旧的技术栈与低效的流程也制约了团队的生产力。因此需进行全面全面重构,通过基于业务导向的架构优化、开发测试流程规范化,从而提升前端开发效率,使项目具备长期稳健发展的技术基础。本文将重点介绍我在重构项目过程中的一些实践经验。

02 前端项目面临的问题

先介绍下日志中台前端项目的基本情况

  • 核心框架:Vue 2.6 + Vuex 3.1.1 + VueRouter 3.0.6

  • UI组件库:ElementUI 2.15.13

  • 构建工具:@vue/cli-service 3.11.0(基于Webpack 4)

  • 部署平台:测试环境(FIS3)、生产环境(Tower)

下面我将从4个维度来分析下前端项目所面临的各种问题。

2.1 代码质量

由于项目没有接入代码格式化 prettier 和 代码规范检查 eslint,导致项目的代码质量堪忧,各种各样的代码风格并存。在开发需求过程中,各自的编码风格不一致,维护时需额外适应时间,甚至由此引发线上问题。

2.2 基础建设

1. 代码臃肿,维护困难

  • 全项目500+源文件中,30+文件超1000行,5+文件超2000行,最大文件达5000行。

  • 巨型文件导致:

    IDE卡顿(Mac开发时频繁卡住)。

    热更新失效(>2s延迟,大文件需手动刷新浏览器)。

2. 技术栈陈旧

  • 仍使用已停止维护的vue-cli(Webpack 4时代工具链),与现代构建工具(Vite、Webpack 5)存在代差。

2.3 构建和部署

测试环境

测试环境的部署采用的是 fis3,这是百度FE团队早期自研的集构建、部署于一身前端构建工具,日志中台项目使用其部署测试环境的功能。具体流程就是在开发者本地执行打包操作,然后将打包产物通过fix3推送到后端的服务器上去,替换掉之前的打包产物,从而实现部署新版本。

  • 这种方式存在诸多问题:

  • 本地构建依赖不一致,易引发环境差异问题。

  • 无CDN缓存,静态资源直推后端服务器。

  • 无版本管理,存在代码覆盖风险。

  • FIS3已停止维护,社区无支持。

  • 本质问题:前后端未完全分离,违背当前主流协作模式。

生产环境

生产环境的部署则采用的是Tower平台,这是百度内部的线上部署平台,通过平台的形式将master分支的代码在服务器上编译构建,将打包后的产物推送到线上环境对应的服务器上,从而实现完整的上线流程。这种上线方式同样存在诸多不足:

  • 上线耗时长达30分钟,无增量构建能力。

  • 多服务器部署时存在"漂移现象"(请求路由不一致)。

  • 操作流程复杂,平台限制多(如回滚困难)。

  • 仍缺失CDN加速,影响页面加载性能。

2.4 优质组件

在Vue技术栈中,模块和组件的模糊概念,导致很多开发者无法区分其区别。

1. 组件与模块概念混淆

  • src/components目录下堆积40+文件夹,但90%为一次性业务模块(如5个重复封装的Table组件),缺乏真正的复用价值。

2. 基础建设缺失

  • 无通用业务组件库,开发依赖Element UI原始组件。

  • 高频逻辑(如表单校验、数据请求)需重复实现,通过"复制粘贴"开发,导致代码冗余和一致性风险。

03 全面重构拆分

下面是针对以上项目中的各个痛点的重构具体手段。

3.1 接入工程化

前端项目若缺乏统一的代码规范和质量控制,随着业务增长,代码可维护性会急剧下降,最终导致开发效率低下、线上问题频发。因此,引入业界成熟的工程化方案是提升代码质量的关键。

工程化改造步骤

1. 清理冗余配置

  • 移除项目中无用的、过时的配置(如废弃的.babelrc、冗余的webpack配置等),减少干扰项。

2. 统一基础配置文件

  • 在项目根目录下添加必要的配置文件,确保团队开发环境一致:

  • .vscode/settings.json(统一VSCode编辑器配置)

  • .editorconfig(统一缩进、换行等基础格式)

  • .npmrc(设置为百度npm镜像)

  • .browserslistrc(明确目标浏览器兼容范围)

3. 接入代码规范工具

  • Prettier:自动格式化代码,统一风格(如缩进、引号、分号等)。

  • ESLint:检查JavaScript/Vue代码质量,避免常见错误。

  • Stylelint(可选):规范CSS/Less代码风格。

4. 优化开发体验

  • 推荐安装必要的VSCode插件(如ESLint、Prettier、Volar等),提升开发效率。

5. 提交时增量强制校验(Git Hooks)

  • 接入husky+lint-staged,在git commit时自动执行代码检查,阻止不合规代码提交。

配置参考

历史代码修复策略

原则:"自动修复优先,手动修复补充",避免无限制添加eslint-disableignore规则,导致规范形同虚设。

具体执行步骤

1. 自动格式化(Prettier)

2. ESLint自动修复

3. 分析剩余问题

  • 使用eslint-formatter-html生成报告,评估剩余问题。

  • 调整ESLint规则(如放宽部分历史代码限制),拆解为多个小任务手动修复。

4. 回归测试

  • 联合熟悉业务的同学进行全量测试,确保修复过程不影响系统功能。
效果验证
  • 代码风格统一:所有新提交的代码均符合规范,减少风格争议。

  • 错误率下降:低级语法错误、边界条件导致的JS报错大幅减少。

  • 开发体验提升:IDE卡顿减少(格式化后代码更简洁),热更新效率提高。

3.2 升级基建

3.2.1 源码优化与依赖治理

问题现状

项目存在大量技术债务,包括:

  • 冗余资源(未压缩图片约2M)

  • 无效依赖(22个未使用的npm包)

  • 混合模块规范(require/import混用)

  • 废弃技术栈(如已停止维护的iView)

优化措施

1. 资源优化

  • 使用基于Tinypng封装的工具批量压缩图片,体积减少65%

  • 清理已下架页面的遗留代码(约15个路由)

2. 依赖治理

  • 移除22个无用依赖

  • 统一使用ES Module规范(手动替换require为import)

3. 技术栈升级

  • 替换老旧组件库:vue-json-diff、vue-code-diff、vue-codemirror 替换为 monaco-editor

3.2.2 构建相关

相对于以往的 Webpack 或者 Vue CLI,存在开发服务器启动慢(平均45秒)、热更新延迟高(2.5秒)、构建流程复杂(需Babel转译ES5)。

Vite 配置详见:www.yuque.com/shuoshubao/...

接入Vite后,低配置电脑同学开发时的平均热更新时间由2.5秒缩短到100毫秒。在单个需求完成耗时方面,由之前的4.2人天缩减到3.4人天,综合人效提高19%

另一方面,由于 Vue CLI 是基于babel将esnext代码转成es5,而Vite基于esbuild不需要进行降级编译。在将 Vite 的配置 build.target 设置为 'chrome100' 后,甚至连非常新的esnext语法糖都不需要转换,浏览器直接可以使用前端的源码,极大的利用了esnext带来的开发便利,而不需要关注Babel的版本以及各种依赖包和复杂的配置。

3.2.3 部署相关

百度内部主流的部署平台是 Fcnap。这是一个类似Vercel的前端一站式部署平台,基于git分支,只要检测到分支变动,就会触发自动构建和部署。

只需配置好各个测试环境以及生产环境的基本信息,后续在需要开发中,只需要将分支和测试环境关联起来,就可以达到随时提交代码随时部署的效果;上线过程更是丝滑,只需要将代码合到master分支,就会自动上线。

将 fis3 以及 Tower 迁移到 Fcnap 后有如下优势:

  • 测试和生成环境使用一套部署逻辑

  • 上线部署耗时由30分钟缩减至2分钟

  • 提供cdn功能,每次上线后增量更新的静态资源只有500kb

  • 上线期间访问系统不会出现白屏现象

  • 上线过程对用户无任何影响

3.2.4 接口调试

传统开发模式的痛点

在传统前后端协作中,存在典型的"接口依赖症":

1. 开发阻塞:前端必须等待后端接口Ready才能开始调试

2. 效率低下:联调阶段频繁出现接口变更,导致重复返工

3. 数据不可控:依赖真实测试环境数据,难以覆盖边界场景

数据表明:在接口未就绪阶段,前端开发效率会下降60%以上

真正的"前后端分离"实践

核心原则:开发阶段解耦,联调阶段对接

1. 规范先行

  • 后端通过YAPI等平台提供完整的接口文档

  • 包含:请求方法、参数结构、响应体示例、状态码定义

2. Mock数据要求

  • 真实业务数据(非简单根据接口文档生成各种随机数据)

  • 可自定义异常场景(404, 502等真实场景还原)

  • 支持动态响应(根据参数返回不同数据)

针对这个开发环节,我们也基于Vite实现了一个非常好用的插件:vite-plugin-mock,用于提升开发效率。整体的设计如下:

相比于传统的 mock 方案,vite-plugin-mock在开发体验、数据维护上有更好的开发体验。

|-------|------------|----------------------|
| 特性 | 传统Mock方案 | vite-plugin-mock |
| 数据真实性 | 随机生成,不可用 | 可在真实接口数据上任意修改 |
| 开发体验 | 需要启动Mock服务 | 配置简单,可随时修改数据 |
| 联调切换 | 手动修改请求地址 | 自动代理无缝切换 |
| 数据维护 | 独立维护Mock数据 | 数据存放在本地,每个人都可维护单独的数据 |

3.3 构建体积优化

这一部分主要从以下三个技术方案着手优化,再配合其他人工优化手段,打包体积由开始的 14M 优化到 1.8M,接入cdn功能后,则仅有500kb。

3.3.1 element-ui

fork element-ui 源码, 采用rollup进行打包,优化部分源码,修复部分 bug,重新发包为 @baidu-log/element-ui

这一步骤,js 体积从 1.2M 优化到 500kb。并结合下面 externals 功能,进一步使用cdn功能缓存这部分文件体积。

3.3.2 引入externals功能

将基础包通过cdn的形式在 index.html 模板中引入其umd格式的文件,从而避免打包这部分内容。这部分会用到cdn的缓存功能,会节约掉大约 2M 的体积。

vite-plugin-externals

这个是开源的vite插件,配置也比较简单,详见配置:www.yuque.com/shuoshubao/...

vite-plugin-assets

这个是为了配合上面vite-plugin-externals插件,将对应的externals的npm包对应的umd文件插入到模板中,代码详见:www.yuque.com/shuoshubao/...

为什么不直接写在 index.html 里呢?因为像 vue 和 react 这样的框架,在开发时都提供了对应的开发调试工具:dev-tools。而使用 dev-tools 则需要提供对应的 dist/vue.js ,而react对应的则是 react.development.js

3.3.3 大包的特殊处理

  1. monaco-editor

项目中用到了 monaco-editor 这个编辑器组件,直接打包将会非常大,有10M以上的体积。根据官方提供的方案即可进行如下封装,其中 cdn 地址由百度的 npm 镜像服务提供支持。

代码详见:www.yuque.com/shuoshubao/...

  1. xlsx, fabric 等

在项目中用到了 xlsx, fabric, markdown-it, echarts, draw.io 这几个体积很大的包,但又不属于很基础的包,只有少部分页面的某个功能点才会用到。针对这些包采用从cdn异步加载其umd包的形式来引入,而不是通过 import npm包的形式。

代码详见:www.yuque.com/shuoshubao/...

以上两种优化方案,与常见的动态引入方案(dynamic import)是有很大区别的,dynamic import 是通过编译工具将对应的npm包打包成一个独立的chunk,然后在使用的时候再通过loadScript方式引入。这种问题在于文件的缓存,一是chunk可能会变,二是像Vercel这种平台,每次发布都是一个全新的 s3 bucket,上线后缓存功能也就失效了。而上述这种方案,则利用npm镜像服务,每次都访问固定的cdn地址,也就达到了cdn的缓存目的了。

3.4 建设组件库

鉴于项目没有优质组件的背景,从零到一搭建了组件库,组件库主要包含以下内容:

  1. 基于 Vuepress 建设高质量组件库文档

  2. 迁移 element-ui 文档,并修复其中大量劣质示例代码

  3. 采用 Vitest 编写工具方法的测试用例

  4. 提供9个高频优质通用组件,10个业务组件

组件库文档:logsfe.vercel.app/

文档分为以下几大模块

实际效果:组件库中的组件在项目中目前已被使用240次,用户使用体验良好。

3.4.1 通用组件

基于大量的B端系统开发经验,提炼出配置化表格和配置化表单组件,满足项目中90%的开发场景,通过重构部分页面后比较分析,在写对应模块时,能减少40%的代码。

通用组件均与业务解耦,设计优雅的api,并提供大量示例。组件库里只提供少量的优质组件,严格把控每一行提交的代码,并为组件中的工具函数提供符合 JSDoc-style 规范的注释,且通过 Vitest 来编写单元测试。

3.4.2 element-ui 文档集成

在实际工作中,发现 element-ui 文档存在很多问题且早已不维护。

  • 主题与日志中台不符,不利于查看

  • 组件默认size过大,一页都看不了多少示例

  • 右侧没有 toc 功能,不方便快速定位

  • 示例很多写法不优雅,以及很多冗余代码被人机的复制到了项目中

  • 在线调试示例采用的是 codepen 平台,这个平台很慢而且经常挂了

基于以上各种问题,将 element-ui 官方的示例 fork 到组件库中,使用和日志中台一样的主题,并修复上述各种问题。

并使用纯前端来实现了一个完全可用的 codepen 组件使用示例功能。

3.4.3 通用工具库

基于B端系统抽象的实用工具方法集合。在组件库中提供优质的说明文档和使用示例。这个已经发布到npm上,并在多个公司和团队使用。

包括日期处理、数据处理、接口数据格式化、针对element-ui的一些实用封装。目前已在项目中被93个文件使用150次。

项目地址:www.npmjs.com/package/@nb...

04 总结与展望

在频繁的需求迭代过程中,项目迟早会变成臃肿老旧的样子。当开发体验、开发速度、代码质量、项目可维护性、联调测试体验、线上质量等全方位令人举步维艰的时候,就该发起大规模的全面重构了。对每一项重构技术需要深刻掌握,才能掌握重构的深度和保证重构后的项目质量。另外,还定制了很多开发规范和最佳实践指导,但项目中仍存在大量不符合规范的地方,将在未来继续进行全量修复,直到将一个老旧的项目重构到更接近现代化前端项目的程度。

相关推荐
小小小小宇9 分钟前
LLM 长期记忆构建
前端
lichenyang45321 分钟前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__2 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富2 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇2 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇2 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆2 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马2 小时前
Verilog开发常见问题汇总解析
前端
子兮曰2 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端