Community程式設計與開發github.com

bright-y/prototype-maintenance

維護現有的互動原型,釐清頁面、元件、對話框、資料、狀態、樣式及驗證的歸屬。適用於持續的結構迭代與維護對應,而非初次靜態交付封裝。

prototype-maintenance 是什麼?

此技能專為需要長期迭代的互動原型設計,核心目標是提升可維護性,而非重新設計產品。它幫助開發者釐清原型中各個部分(如頁面、元件、對話框、資料、狀態、樣式和驗證)的明確歸屬,讓後續的修改更快速且不易出錯。技能支援多種平台與框架,從純靜態原型到複雜的應用皆可適用,提供的指南涵蓋了檔案結構建議、各層級(頁面、元件、資料、樣式等)的責任劃分、以及建立變更對應檔(CHANGE-MAP)與維護說明文件的最佳實踐。其運作方式遵循一套嚴謹的工作流程,包括檢查現有檔案、識別當前歸屬、謹慎分割、驗證語法與預覽效果,並提供明確的分割粒度規則以避免過度或不足的拆分。最終會產出一份清晰的結構,讓開發者能迅速定位並修改特定功能,同時保留既有行為與視覺方向。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bright-y/prototype-skills/tree/HEAD/skills/prototype-maintenance

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

原型維護

使用此技能讓現有的原型在多次產品迭代中更容易修改。

目標不是重新設計產品。在改善可維護性、檔案所有權和驗證速度的同時,保留當前的行為和視覺方向。

範圍與交接

  • 在現有原型中,將此技能用於持續的結構迭代和所有權對應。對於初次靜態拆分或封裝,請使用 static-prototype-splitter(若可用);它不是必需的依賴項。
  • 一個小型的複製、版面或行為請求不需要進行目錄大改造。僅拆分與該請求相關的職責。
  • 保留現有的進入點檔案名稱、框架、腳本模型和預覽工作流程。下面的 app.html 佈局只是一個範例,並非重新命名的要求。
  • 遵循使用者對於檔案取代、設定、依賴項、網路存取、本地伺服器和儲存資料的授權規則。此技能不授予這些權限。

觸發時機

當使用者要求以下事項時觸發此技能:

  • 改善後續原型修改的速度。
  • 按頁面、元件、欄位、模態框、儲存庫或資料層拆分 JavaScript。
  • 按 base、layout、page、component、modal 和 field 範圍拆分 CSS。
  • 分離模擬資料、種子資料、結構描述和狀態/儲存邏輯。
  • 建立或更新原型維護 README。
  • 建立或更新 CHANGE-MAP,將未來請求對應到檔案。
  • 繼續優化現有的互動原型。
  • 讓組合預覽和拆分檔案能共同保持可維護性。
  • 解釋未來原型修改應該在哪裡進行。

預設原則

  • 遵循使用者的語言和原型的現有術語。
  • 在編輯前先讀取當前的進入點和活動腳本參考。
  • 保留原始的視覺設計和互動意圖,除非使用者要求重新設計。
  • 除非明確要求,否則不要將所有內容重寫成某個框架。
  • 避免產生第二個分歧的實作。組合預覽應載入共享/拆分的模組,或從它們產生。
  • 將變更範圍集中在可維護性和所要求的產品行為上。
  • 當僅添加新檔案時,拆分尚未完成。每個拆分還必須減少舊檔案的職責,以便未來的編輯有唯一且明確的負責人。
  • 保留不相關的變更不變,並保留原始的輸入和已取代的檔案。將授權的編輯集中在活動實作上;未經批准,請勿刪除舊有檔案或取代受保護的文件。
  • 變更後,在可行時驗證語法和主要預覽互動。

建議結構

根據專案調整名稱,但對於靜態互動原型,偏好以下形狀:

prototype/
├── app.html
├── README-prototype.md
├── CHANGE-MAP.md
├── assets/
│   ├── css/
│   │   ├── base.css
│   │   ├── layout.css
│   │   ├── components.css
│   │   ├── modals.css
│   │   ├── fields.css
│   │   └── pages/
│   │       ├── home.css
│   │       ├── editor.css
│   │       └── fill.css
│   └── js/
│       └── app/
│           ├── core.js
│           ├── runtime.js
│           ├── pages/
│           ├── components/
│           ├── fields/
│           ├── modals/
│           ├── data/
│           ├── store/
│           └── utils/
└── pages/
    └── ...

當原型領域不同時,使用等效的名稱。重要的是責任劃分。

對於小型原型,較扁平的結構即可。對於頻繁變更的原型,較偏好上述目錄結構,這樣每個未來的請求都能對應到一個小檔案。

各層責任

進入點層

保留當前的組合預覽進入點;下方使用 app.html 作為範例名稱。

它應包含:

  • 裝置框架或預覽外殼(若有的話)。
  • 根容器。
  • CSS 連結。
  • 有序的腳本參考。

它不應包含大部分業務邏輯。

頁面層

使用頁面檔案處理頁面渲染和頁面特定的佈局:

  • 首頁/列表/搜尋/分頁標籤。
  • 編輯器/建立/編輯頁面。
  • 填寫/預覽/提交/詳細頁面。
  • 登入/註冊/引導頁面。
  • 設定/帳戶頁面。

當使用者要求更改頁面佈局或頁面文案時,從這裡開始。

如果一個頁面檔案包含多個頻繁編輯的子視圖,則再次拆分。範例:

pages/home/
├── index.js
├── search.js
├── my-forms.js
└── submitted.js

欄位或元件層

使用欄位/元件檔案處理重複的 UI 區塊:

  • 欄位類型標籤。
  • 欄位預設值。
  • 編輯器中的欄位預覽。
  • 填寫頁面控制項。
  • 上傳/圖片/檔案/單選鈕/核取方塊/OCR/日期渲染器。

當使用者要求變更某一元素類型時,避免先搜尋整個應用程式。從欄位設定和渲染器檔案開始。

當原型有許多表單控制項或重複的卡片時,偏好使用註冊表:

fields/
├── registry.js
├── text.js
├── image.js
├── file.js
├── options.js
└── ocr.js

模態框層

使用模態框檔案處理:

  • 欄位設定面板。
  • 類型選取器面板。
  • 排序抽屜。
  • 確認對話框。
  • 新增元素庫面板。

盡可能保持模態框狀態為局部,並僅在確認動作後提交資料。

資料層

將資料與儲存庫行為分離。

使用 data/ 處理:

  • 模擬模板。
  • 產業/類別列表。
  • 欄位類型定義。
  • 示範使用者和範例。
  • 種子記錄和測試用資料。

使用 store/ 處理:

  • 本地儲存金鑰。
  • 表單儲存/刪除/更新。
  • 提交紀錄儲存/刪除/更新。
  • 資料正規化和遷移。

除非原型非常小,否則不要將儲存規則混入頁面渲染器中。

當現有本地資料可能已存在時,保留其金鑰和使用者的編輯。僅透過穩定的 ID 添加缺少的種子記錄,並使種子植入具有冪等性;不要覆寫已編輯的記錄、複製項目或在重新載入時重設本地儲存。將結構描述遷移視為一個獨立的、已授權的操作,並附有文件記錄的復原路徑。

CSS 層

按所有權拆分 CSS,而不僅僅是按大小:

  • base.css:變數、重置、排版。
  • layout.css:外殼、裝置框架、頁面容器、網格原語。
  • components.css:按鈕、輸入框、卡片、分頁標籤、晶片。
  • modals.css:面板、抽屜、確認對話框、吐司提示。
  • fields.css:欄位控制項和表單元素預覽。
  • pages/*.css:頁面特定的佈局和例外。

如果一個選擇器跨頁面重用,則保留在 components 或 fields 中。如果它特定於一個頁面,則將其移至該頁面的 CSS。

變更對應層

為預計會接受多輪編輯的原型添加 CHANGE-MAP.md。

它應將常見的使用者請求直接對應到檔案:

# 變更對應

## 頁面
- 首頁:assets/js/app/pages/home/index.js
- 模板頁面:assets/js/app/pages/templates/index.js
- 表單編輯器:assets/js/app/pages/editor/index.js

## 欄位
- 圖片上傳欄位:assets/js/app/fields/image.js
- 檔案上傳欄位:assets/js/app/fields/file.js
- 單選鈕/核取方塊欄位:assets/js/app/fields/options.js

## 模態框
- 欄位設定模態框:assets/js/app/modals/field-settings.js
- 排序抽屜:assets/js/app/modals/sort.js

## 資料
- 模板資料:assets/js/app/data/templates.js
- 產業類別:assets/js/app/data/industries.js

## 樣式
- 模板頁面樣式:assets/css/pages/templates.css
- 欄位樣式:assets/css/fields.css

保持 CHANGE-MAP 簡短。它是一個編輯索引,而不是產品文件。

執行時期層

使用執行時期檔案處理:

  • 路由器/渲染分派。
  • 事件委派。
  • 手勢處理。
  • 動作分派。
  • 啟動引導。

如果執行時期變得很大,則按互動類型拆分,但保留一個清晰的進入點。

維護 README

當被要求時,在原型根目錄下新增或更新 README-prototype.md。

包含:

  • 總覽進入點。
  • 本地預覽 URL 和保留的連接埠(若有的話)。
  • 頁面對應檔案。
  • 欄位/元件對應檔案。
  • 模態框對應檔案。
  • 資料層位置。
  • CSS 層位置。
  • CHANGE-MAP 位置。
  • 如何在變更後重新整理和驗證。
  • 常見的未來變更範例,例如「變更上傳圖片欄位」或「變更表單提交頁面」。

保持簡潔且有用。它是給維護原型的人類閱讀的,而不是一個冗長的開發日記。

工作流程

  1. 檢查活動進入點檔案。

    • 使用 rg --files、grep 和目標性讀取。
    • 確認哪些腳本實際上被組合預覽載入。
    • 不要假設現有的拆分檔案是活動的。
  2. 識別當前所有權。

    • 頁面渲染器。
    • 欄位渲染器/設定。
    • 模態框/抽屜。
    • 儲存庫/資料輔助程式。
    • 執行時期/事件處理器。
  3. 小心拆分。

    • 當需要保留行為時,優先進行機械式提取。
    • 在 app.html 中明確指定腳本載入順序。
    • 避免在拆分期間變更行為,除非使用者同時要求行為變更。
    • 提取模組後,從舊檔案中移除或縮小對應的責任。不要為同一個頁面、元件、模態框、資料集或 CSS 選擇器留下兩個活動的負責人。
    • 保留舊有的組合檔案不予使用,而不是刪除它們,除非使用者確認刪除。
    • 保留現有的 classic-script 或 ES-module 模型。移動函式後,檢查載入順序、匯出和內聯事件處理器。
    • 使視圖掛載/卸載的責任明確。離開視圖時,移除陳舊的監聽器和計時器,以便重複導覽不會重複執行動作。
  4. 當資料增長時拆分資料。

    • 將大型模擬資料移出頁面渲染器和儲存庫檔案。
    • 保持種子測試用資料具確定性且易於掃描。
    • 盡可能將新的種子資料合併到現有的本地資料中。
    • 如果資料被移到 data/,讓儲存庫/狀態檔案消費該資料,而不是保留一份重複的活動副本。
  5. 當視覺變更變慢時拆分 CSS。

    • 從 base/layout/components/pages 開始。
    • 將僅頁面使用的選擇器移至頁面 CSS。
    • 將可重用的控制項移至 components 或 fields CSS。
    • 移動選擇器後,從先前的全域樣式表中移除重複的活動選擇器,除非有意保留它們作為共享的元件樣式。
    • 保留階層順序和回應式斷點;重新調整 CSS 中的 url(...)、字型和匯入路徑,使其相對於新檔案位置。
  6. 更新或建立 README 和 CHANGE-MAP。

    • 記錄最終的活動結構。
    • 明確指出常見的未來請求應編輯哪個檔案。
    • 包含本地預覽 URL、保留的連接埠和快取清除說明(若相關)。
  7. 驗證。

    • 遞迴檢查原型實際擁有的 JavaScript 檔案,包括巢狀的頁面/元件檔案。當 Python 和 Node 已可用時,此範例檢查 assets/js 下方的 .js、.mjs 和 .cjs 檔案;根據專案調整根目錄。不要僅為了執行它而安裝執行時期。
      python3 - <<'PY_CHECK'
      from pathlib import Path
      import subprocess
      import sys
      
      root = Path("assets/js")
      files = sorted(p for p in root.rglob("*")
                     if p.is_file() and p.suffix in {".js", ".mjs", ".cjs"}
                     and not {"node_modules", "vendor", ".git"}.intersection(p.parts))
      if not files:
          sys.exit("No JavaScript files found; verify the check root.")
      failed = False
      for path in files:
          failed |= subprocess.run(["node", "--check", str(path)]).returncode != 0
      sys.exit(1 if failed else 0)
      PY_CHECK
      
    • 對於框架專案或不同的模組模式,使用現有的專案檢查。語法檢查通過並不能證明瀏覽器行為。
    • 開啟組合預覽。
    • 將受影響的行為與基準線進行比較,包括前進/後退導覽、重新訪問已編輯的視圖、模態框確認/取消,以及在適用時重新整理後保存的狀態。
    • 在可行時檢查瀏覽器主控台錯誤。

拆分粒度規則

使用這些規則來避免拆分不足和拆分過度:

  • 如果一個檔案因不相關的請求而被重複編輯,則拆分它。
  • 如果一個頁面包含多個獨立變更的子視圖,則拆分子視圖。
  • 如果模擬資料佔用的空間比其周圍的邏輯還多,則將其移至 data/。
  • 當多個欄位/控制項類型獨立變更時,考慮使用 fields/;不要僅僅為了達到某個數量而拆分。
  • 當對話框或抽屜有獨立的狀態或維護需求時,考慮使用 modals/。
  • 如果 CSS 變更需要搜尋大型的全域樣式表,則按頁面和元件拆分。
  • 如果一個檔案穩定且很少被編輯,不要僅僅為了美觀而拆分它。

驗證輔助工具

偏好簡單、無依賴的靜態原型驗證方式:

  • 使用 node --check 檢查 JS 語法。
  • 對於快取清除,代入實際值,例如 app.html?t=20261109-153000;在 URL 中直接鍵入 Date.now() 是一個固定字串。單靠 HTML 查詢字串無法重新整理獨立快取的 JS/CSS,因此請在需要時使用瀏覽器快取控制項或現有的資產版本化策略。
  • 當使用者已選擇了一個連接埠時,保持本地預覽連接埠穩定。
  • 在結構重構後,在瀏覽器中驗證已變更的互動。
  • 對於相容的靜態頁面,直接開啟檔案是可以接受的。擷取的片段和瀏覽器 ES 模組通常需要 HTTP;記錄開啟模式並在可用時重用現有的預覽伺服器。啟動新伺服器需遵循使用者的授權規則。

回應風格

完成時,告訴使用者:

  • 哪些內容被拆分或記錄。
  • 活動的進入點檔案。
  • 最重要的新檔案路徑。
  • README-prototype.md 或 CHANGE-MAP.md 是否已建立或更新。
  • 完成了哪些驗證。
  • 任何有意保留在原位的舊有檔案。

保持最終的回應簡短且實用。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能