日志中臺是百度內部針對打點數據的全生命周期管理平臺,作為公司日志數據的唯一入口,承擔以下核心職能: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
時自動執行代碼檢查,阻止不合規代碼提交。
配置參考:
VSCode統一配置
https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#NStKP
工程化配置方案https://www.yuque.com/shuoshubao/bg00go/wc87bknptk3lomed#SJTr2
歷史代碼修復策略
原則:“自動修復優先,手動修復補充”,避免無限制添加eslint-disable
或ignore
規則,導致規范形同虛設。
具體執行步驟:
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在開發體驗、數據維護上有更好的開發體驗。
特性 | 傳統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插件,配置也比較簡單,詳見配置: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/
文檔分為以下幾大模塊
-
優質組件:https://logsfe.vercel.app/components/Table/
-
組件庫里的方法:https://logsfe.vercel.app/utils.html
-
@nbfe/tools工具庫方法: https://logsfe.vercel.app/tools/date.html
-
ElementUI 文檔:https://logsfe.vercel.app/element/icon.html
-
前端定制的開發規范:https://logsfe.vercel.app/contribute/
實際效果:組件庫中的組件在項目中目前已被使用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 總結與展望
在頻繁的需求迭代過程中,項目遲早會變成臃腫老舊的樣子。當開發體驗、開發速度、代碼質量、項目可維護性、聯調測試體驗、線上質量等全方位令人舉步維艱的時候,就該發起大規模的全面重構了。對每一項重構技術需要深刻掌握,才能掌握重構的深度和保證重構后的項目質量。另外,還定制了很多開發規范和最佳實踐指導,但項目中仍存在大量不符合規范的地方,將在未來繼續進行全量修復,直到將一個老舊的項目重構到更接近現代化前端項目的程度。