日志中台是百度内部针对打点数据的全生命周期管理平台,作为公司日志数据的唯一入口,承担以下核心职能: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. 代码臃肿,维护困难
2. 技术栈陈旧
- 仍使用已停止维护的
vue-cli
(Webpack 4时代工具链),与现代构建工具(Vite、Webpack 5)存在代差。
2.3 构建和部署
测试环境
测试环境的部署采用的是 fis3,这是百度FE团队早期自研的集构建、部署于一身前端构建工具,日志中台项目使用其部署测试环境的功能。具体流程就是在开发者本地执行打包操作,然后将打包产物通过fix3推送到后端的服务器上去,替换掉之前的打包产物,从而实现部署新版本。
生产环境
生产环境的部署则采用的是Tower平台,这是百度内部的线上部署平台,通过平台的形式将master分支的代码在服务器上编译构建,将打包后的产物推送到线上环境对应的服务器上,从而实现完整的上线流程。这种上线方式同样存在诸多不足:
2.4 优质组件
在Vue技术栈中,模块和组件的模糊概念,导致很多开发者无法区分其区别。
1. 组件与模块概念混淆
-
src/components
目录下堆积40+文件夹,但90%为一次性业务模块(如5个重复封装的Table组件),缺乏真正的复用价值。
2. 基础建设缺失
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-disable
或ignore
规则,导致规范形同虚设。
具体执行步骤:
1. 自动格式化(Prettier)
2. ESLint自动修复
3. 分析剩余问题
4. 回归测试
- 联合熟悉业务的同学进行全量测试,确保修复过程不影响系统功能。
效果验证
-
代码风格统一:所有新提交的代码均符合规范,减少风格争议。
-
错误率下降:低级语法错误、边界条件导致的JS报错大幅减少。
-
开发体验提升:IDE卡顿减少(格式化后代码更简洁),热更新效率提高。
3.2 升级基建
3.2.1 源码优化与依赖治理
问题现状:
项目存在大量技术债务,包括:
-
冗余资源(未压缩图片约2M)
-
无效依赖(22个未使用的npm包)
-
混合模块规范(require/import混用)
-
废弃技术栈(如已停止维护的iView)
优化措施:
1. 资源优化
2. 依赖治理
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 后有如下优势:
3.2.4 接口调试
传统开发模式的痛点
在传统前后端协作中,存在典型的"接口依赖症":
1. 开发阻塞:前端必须等待后端接口Ready才能开始调试
2. 效率低下:联调阶段频繁出现接口变更,导致重复返工
3. 数据不可控:依赖真实测试环境数据,难以覆盖边界场景
数据表明:在接口未就绪阶段,前端开发效率会下降60%以上
真正的"前后端分离"实践
核心原则:开发阶段解耦,联调阶段对接
1. 规范先行:
-
后端通过YAPI等平台提供完整的接口文档
-
包含:请求方法、参数结构、响应体示例、状态码定义
2. Mock数据要求:
针对这个开发环节,我们也基于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/…
2. 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 文档存在很多问题且早已不维护。
基于以上各种问题,将 element-ui 官方的示例 fork 到组件库中,使用和日志中台一样的主题,并修复上述各种问题。

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

3.4.3 通用工具库
基于B端系统抽象的实用工具方法集合。在组件库中提供优质的说明文档和使用示例。这个已经发布到npm上,并在多个公司和团队使用。
包括日期处理、数据处理、接口数据格式化、针对element-ui的一些实用封装。目前已在项目中被93个文件使用150次。
项目地址:www.npmjs.com/package/@nb…
04 总结与展望
在频繁的需求迭代过程中,项目迟早会变成臃肿老旧的样子。当开发体验、开发速度、代码质量、项目可维护性、联调测试体验、线上质量等全方位令人举步维艰的时候,就该发起大规模的全面重构了。对每一项重构技术需要深刻掌握,才能掌握重构的深度和保证重构后的项目质量。另外,还定制了很多开发规范和最佳实践指导,但项目中仍存在大量不符合规范的地方,将在未来继续进行全量修复,直到将一个老旧的项目重构到更接近现代化前端项目的程度。