[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"post-\u002Fblog\u002Fone-change-many-projects":3},{"id":4,"title":5,"body":6,"category":261,"date":262,"description":263,"draft":264,"extension":265,"meta":266,"navigation":267,"path":268,"readingTime":269,"seo":270,"stem":271,"tags":272,"__hash__":276},"blog\u002Fblog\u002Fone-change-many-projects.md","同一個修改要改好幾個專案：維護多個前端的心得",{"type":7,"value":8,"toc":248},"minimark",[9,13,16,21,24,40,43,99,111,114,117,120,123,126,130,133,162,165,169,172,175,178,181,184,187,190,197,208,213,221,224,227,230,244],[10,11,12],"p",{},"我在工作上維護的不是一個前端，而是好幾個：Vue 2 + Vuex 的專案、Vue 3 + Pinia 的專案，還有桌機版和手機版分開的系統。它們服務同一套業務，所以一個需求常常要改好幾次。",[10,14,15],{},"這是課堂上學不到的事。這篇整理我實際遇到的狀況。",[17,18,20],"h2",{"id":19},"同一個需求要做好幾次","同一個需求，要做好幾次",[10,22,23],{},"幾個真實的例子：",[25,26,27,31,34,37],"ul",{},[28,29,30],"li",{},"註冊姓名欄位調整：桌機版和手機版都要改。",[28,32,33],{},"登入後回到原本頁面：兩個版本各做一次。",[28,35,36],{},"圖片檔名中文改英文：每個專案都要處理。",[28,38,39],{},"無障礙修正：多個專案都要符合。",[10,41,42],{},"這些修改的概念相同，但實作不一定能直接複製：",[44,45,46,62],"table",{},[47,48,49],"thead",{},[50,51,52,56,59],"tr",{},[53,54,55],"th",{},"差異",[53,57,58],{},"Vue 2 專案",[53,60,61],{},"Vue 3 專案",[63,64,65,77,88],"tbody",{},[50,66,67,71,74],{},[68,69,70],"td",{},"狀態管理",[68,72,73],{},"Vuex",[68,75,76],{},"Pinia",[50,78,79,82,85],{},[68,80,81],{},"UI 元件庫",[68,83,84],{},"Vuetify 2",[68,86,87],{},"Vuetify 3",[50,89,90,93,96],{},[68,91,92],{},"路由",[68,94,95],{},"Vue Router 3",[68,97,98],{},"Vue Router 4",[10,100,101,102,106,107,110],{},"例如 404 路由，Vue Router 3 寫 ",[103,104,105],"code",{},"path: '*'","，Vue Router 4 要寫 ",[103,108,109],{},"\u002F:pathMatch(.*)*","。同樣的概念，寫法不一樣，測試也要再做一次。",[17,112,113],{"id":113},"最大的風險是漏改",[10,115,116],{},"修改次數變多，時間成本還不是最麻煩的，真正的問題是漏掉。",[10,118,119],{},"我自己就遇過：有一次把註冊頁的姓名拆解邏輯移除，測試也沒問題，後來才發現登入頁的補填資料表單裡還有同一段邏輯。兩個專案都是這樣。",[10,121,122],{},"原因很簡單：相同的邏輯在同一個專案裡就寫了兩份，專案之間又各有一份。需求單只寫「註冊」，我就只改了註冊。",[17,124,125],{"id":125},"我現在的做法",[127,128,129],"h3",{"id":129},"動手前先搜尋",[10,131,132],{},"改之前先在每個專案搜尋相同的函式和關鍵字，確認影響範圍：",[134,135,140],"pre",{"className":136,"code":137,"language":138,"meta":139,"style":139},"language-bash shiki shiki-themes github-dark","grep -rn \"splitName\" src\n","bash","",[103,141,142],{"__ignoreMap":139},[143,144,147,151,155,159],"span",{"class":145,"line":146},"line",1,[143,148,150],{"class":149},"svObZ","grep",[143,152,154],{"class":153},"sDLfK"," -rn",[143,156,158],{"class":157},"sU2Wk"," \"splitName\"",[143,160,161],{"class":157}," src\n",[10,163,164],{},"只改眼前這一支檔案，是最容易漏的做法。",[127,166,168],{"id":167},"用-notion-列出專案功能清單","用 Notion 列出專案功能清單",[10,170,171],{},"發生過漏改之後，我開始用 Notion 把每個專案的功能列成清單，例如註冊、登入、補填資料、會員資料。",[10,173,174],{},"有需求時先對照清單，看看哪些功能會受影響；測試時再照著清單一項一項走過。這樣姓名這類改動，就不會只測到註冊頁，登入頁的補填資料表單也會在測試範圍裡。",[10,176,177],{},"清單要隨著功能更新才有用。新增功能時順手補上，它就是一份不靠記憶的測試範圍。",[127,179,180],{"id":180},"一次改完",[10,182,183],{},"同一個需求盡量同一天處理完所有專案。隔太久，就會忘記當時的上下文，也更容易出現版本不一致。",[17,185,186],{"id":186},"什麼時候該抽成共用模組",[10,188,189],{},"看到重複，第一個想法通常是抽成共用套件。但我現在不會馬上這麼做。",[10,191,192,196],{},[193,194,195],"strong",{},"適合抽出來的","：",[25,198,199,202,205],{},[28,200,201],{},"不依賴框架的純邏輯，例如日期格式、資料驗證。",[28,203,204],{},"真的完全相同，而且會一起改的規則。",[28,206,207],{},"像日期選擇器的鍵盤操作這種，同專案內多個頁面共用的邏輯，就可以先抽成 mixin 或 composable。",[10,209,210,196],{},[193,211,212],{},"不適合馬上抽的",[25,214,215,218],{},[28,216,217],{},"綁定 UI 元件庫的畫面，Vuetify 2 和 3 差異很大。",[28,219,220],{},"只是目前長得像，但各自的需求會往不同方向發展。",[10,222,223],{},"共用模組也有成本：要處理版本、發布，改一個地方可能影響所有專案。Vue 2 和 Vue 3 要共用元件，更是不容易。",[10,225,226],{},"我的判斷方式是：先在專案內抽出來，確認它穩定，而且真的在多處一起變動，才考慮跨專案共用。",[17,228,229],{"id":229},"這次學到的事",[25,231,232,235,238,241],{},[28,233,234],{},"維護多個專案時，「知道要改哪裡」比「怎麼改」更花時間。",[28,236,237],{},"搜尋是最便宜的防護。",[28,239,240],{},"重複程式碼不一定要立刻消除，錯誤的抽象比重複更難維護。",[28,242,243],{},"需求單寫的範圍不一定等於實際影響的範圍。",[245,246,247],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":139,"searchDepth":249,"depth":249,"links":250},2,[251,252,253,259,260],{"id":19,"depth":249,"text":20},{"id":113,"depth":249,"text":113},{"id":125,"depth":249,"text":125,"children":254},[255,257,258],{"id":129,"depth":256,"text":129},3,{"id":167,"depth":256,"text":168},{"id":180,"depth":256,"text":180},{"id":186,"depth":249,"text":186},{"id":229,"depth":249,"text":229},"quality","2026-08-11","公司同時維護多個 Vue 2 與 Vue 3 前端，同一個需求常要改好幾次。整理實際遇到的問題、漏改的情況，以及什麼時候才值得抽成共用模組。",false,"md",{},true,"\u002Fblog\u002Fone-change-many-projects",5,{"title":5,"description":263},"blog\u002Fone-change-many-projects",[273,274,275],"Maintenance","Vue 2","Vue 3","1er6hOdG09YFLnYy2WHvggOBGYc78tRqv1k1qby30fA"]