写点什么

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

作者:百度Geek说
  • 2025-06-24
    上海
  • 本文字数:5591 字

    阅读完需:约 18 分钟

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

日志中台是百度内部针对打点数据的全生命周期管理平台,作为公司日志数据的唯一入口,承担以下核心职能: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 配置详见:https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#wyx0p


接入 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 在开发体验、数据维护上有更好的开发体验。

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 插件,配置也比较简单,详见配置:https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#LiR2X


vite-plugin-assets


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


为什么不直接写在 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 镜像服务提供支持。


代码详见:https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#gozcq


2. xlsx, fabric 等

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


代码详见:https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#rEBee


以上两种优化方案,与常见的动态引入方案(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 个业务组件


组件库文档:https://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 次。


项目地址:https://www.npmjs.com/package/@nbfe/tools

04 总结与展望

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

用户头像

百度Geek说

关注

百度官方技术账号 2021-01-22 加入

关注我们,带你了解更多百度技术干货。

评论

发布
暂无评论
百度日志中台前端重构实践_百度Geek说_InfoQ写作社区