前言

上一篇 把 Theme 驗收拆成 Theme Check、preview、響應式、Theme Editor 與 resource cases。通過一次驗收後,另一個問題才真正開始:Shopify 發布新版 Dawn 時,客製功能怎麼留下來?

這篇不是一份「已成功升級」報告。案例只有一個標示 Dawn 15.3.0 的工作目錄,沒有任何 Git commit;我先從 Shopify 官方 Dawn tag 重建基線,才看見為什麼缺少 lineage 會讓一次小客製變成大範圍人工比對。

原本的做法與問題症狀

常見的第一個做法是下載目前 Theme,直接在原檔上改:

  • 新增一個據點查詢 section 與對應 page template。
  • 在 Theme Editor 調整 header、footer、首頁與商品頁。
  • formatter 順手改寫 Liquid 排版。
  • 多語系與 JSON template 被 Shopify admin 重新輸出。

畫面可以工作,但升級時只剩兩個極端:

  1. 以新版 Dawn 整包覆蓋,客製 section、settings 與 merchant content 可能消失。
  2. 以舊 Theme 整包保留,錯過 upstream bug fix、schema 與相容性更新。

更麻煩的是,目錄 diff 裡每一行都長得一樣重要。手寫功能、Theme Editor state、translation 更新、formatter noise 與真正的 Dawn core change 混在一起,reviewer 無法判斷該 port、merge 還是重新設定。

問題是怎麼推敲出來的?

案例的 settings_schema.json 留下 Dawn 15.3.0 這條線索。我取出 Shopify 官方 v15.3.0 tag 做 read-only baseline diff,得到 104 個不同檔案,約 3,437 行新增與 966 行刪除。

這個數字不能直接叫做「客製規模」:

  • 51 個 locale files 有差異。
  • 20 個 templates 有差異,很多是 Theme Editor 產生的狀態。
  • settings_data.json、header group 與 footer group 保存 merchant configuration。
  • 新增的據點 section 與 page template 才是明確功能。
  • header.liquid 顯示 80 行新增、60 行刪除,但逐段看大多是 formatter 改排版。

也就是說,raw diff 很大,semantic diff 卻小得多。若沒有 upstream tag 與每次客製的 commit,工程師會花時間審查無意義變化,真正需要重測的核心修改反而容易漏掉。

最後採用的架構

未來維護要把 Theme 拆成三條軌:

upstream
  → Shopify/Dawn tag + commit

custom code
  → 新 section / snippet / asset
  → 必要且最小的 core patch
  → 每個功能一個可讀 commit

merchant state
  → settings_data.json
  → JSON templates / section groups
  → Theme Editor 與 app embed 設定

升級時不是把三條軌混成一次 copy,而是:

新 upstream tag
  → 建立 draft branch / draft theme
  → port custom commits
  → 合併或重建 merchant state
  → Theme Check + preview + Editor QA
  → controlled publish

新功能優先放在新增 section、snippet、asset 與 template。不是因為「永遠不能改 Dawn 核心」,而是新增檔案的 ownership 最清楚;真的需要改 core file 時,patch 應小、帶原因、帶測試,不要和全檔 formatter 混在一起。

關鍵實作

第一步是在 repository 保存來源:

UPSTREAM_THEME=Dawn
UPSTREAM_TAG=v15.3.0
UPSTREAM_COMMIT=<official-commit>

接著把差異依責任分類:

A. hand-written feature
   sections/store-locator.liquid
   templates/page.store-locator.json

B. merchant state
   config/settings_data.json
   sections/header-group.json

C. core patch
   sections/header.liquid

D. generated / translation / formatting noise
   locales/*
   formatter-only hunks

升級 branch 只移植 A 與經審查的 C;B 需要用 Theme Editor 或受控 merge 驗證,D 不應自動當成功能需求。

若 Theme 連接 Shopify GitHub integration,Shopify admin 的 code editor 與 Theme Editor changes 會回寫 commit。這能保留變更來源,但仍需要 branch policy:published theme 對應哪個 branch、哪些 bot commits 可直接接受、誰負責解 conflict,都要明確。

實際驗證

2026-07-30 完成的驗證只有:

  • 來源 schema 確認為 Dawn 15.3.0。
  • 官方 v15.3.0 tag 與工作目錄的 read-only diff。
  • 人工區分新增功能檔、merchant state 與 formatter-heavy core diff。
  • 查核官方 Dawn releases;當日最新公開 release 為 v15.4.1。
  • 比對 15.3.0 與 15.4.1,確認 upstream 變更跨 assets、sections、snippets、locales 與 schema,不適合用單檔覆蓋處理。

本次沒有改來源 Theme,沒有執行 15.4.1 merge、Theme Check、development preview、Theme Editor save/reload、真實商品與 app embed regression,也沒有 publish 或 rollback 演練。

仍然存在的限制

第一,來源沒有 Git history,因此無法證明每個差異是誰、何時、為什麼產生。重建 baseline 只回答「現在和官方 tag 不同」,不能還原完整決策歷史。

第二,schema 裡的版本字串可能被保留或手動修改;它是強線索,不是不可偽造的 artifact identity。正式流程還要保存 upstream commit 與 theme artifact checksum。

第三,Shopify 的標準更新流程會嘗試帶入 Theme Editor customizations 與不衝突的 code edits,但官方也明確說 code edits 可能無法包含。自動顯示成功不代表 custom CSS selector、JavaScript hook 與 app embed 都相容。

第四,uploaded theme 不一定具備 Theme Store 的標準更新資格;是否可直接 Add to draft themes 取決於 Theme 來源與授權狀態。Git merge 流程不能假裝取代平台的 license/update eligibility。

第五,新增檔案也可能依賴 upstream DOM、CSS variable 或 Liquid object。把功能放在新 section 能減少 merge conflict,不能免除 preview、accessibility、performance 與 resource edge-case 測試。

最後,案例新增 section 把 JSON 轉成前端 HTML;這類 inner HTML rendering 還要另做 escaping、資料 schema、XSS 與空值驗證,不能因為升級邊界清楚就視為 production-ready。

可以延伸到哪些情境?

同一套三軌模型也適用付費 Theme、forked design system 與 app-owned storefront:

可追溯 upstream
  + 小而有語意的 custom commits
  + 可重建的 merchant configuration
  = 可審查的升級

降低升級成本的重點不是追求 zero customization,而是讓每個差異都有 owner、reason、baseline 與 validation。這樣遇到新版 Theme 時,團隊是在移植已知需求,不是在幾千行 diff 裡猜哪一行不能丟。

下一批從新版會員中心開始:Shopify Customer Account UI Extension 如何掛載訂單列表、狀態與個人資料頁?

參考資料

以上平台文件與官方 repository 查核日期:2026-07-30。