Communitygithub.com

靜態 HTML 提取工具

從已建置的網頁應用程式或 React 元件中,透過內嵌 CSS 與圖片,提取自包含的靜態 HTML 檔案。

靜態 HTML 提取工具 是什麼?

此技能旨在從本地運行的網頁應用程式(React、Vue、Angular 等)中提取自包含的靜態 HTML 檔案。它提供了兩種主要策略:策略 A(Puppeteer 快照)是推薦預設方案,可透過無頭 Chrome 瀏覽器捕捉完整渲染的 DOM,自動內嵌所有 CSS 並將圖片轉換為 base64,適用於任何框架且無需 Mock 檔案;策略 B(瀏覽器子代理程式)則適用於需要先與頁面互動(點擊、填寫表單)的情境。技能內含完整的 Puppeteer 腳本,支援多項進階功能(例如登入驗證、Canvas 內嵌、暗黑模式 class 設定),以及針對 React/Vite、Next.js、Angular 等框架的專門筆記與故障排除指引。此外,還提供一個「靜態備援(MockPage.jsx)」方法,作為應用程式無法在本機運行時的最後手段。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beavon2010/claude-skills/tree/HEAD/.claude/skills/extract-static-html

在你喜歡的 AI 中提問

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

說明文件

提取靜態 HTML

從任何網頁應用程式中提取一個自包含的靜態 HTML 檔案。

選擇策略

在繼續之前,你必須要求使用者選擇要使用的策略。清楚呈現選項,推薦策略 A 作為預設首選,並為每個選項提供簡短的優缺點摘要,以協助使用者做出明智的決定。

策略 A (Puppeteer)策略 B (瀏覽器子代理程式)
適用時機應用程式在本機運行,無需驗證需要先與頁面互動(點擊、填寫表單)
保真度最高 — 計算樣式已解析高 — 渲染後的 DOM
設定零 — 無需 Mock零 — 無需 Mock
框架任何任何
輸出寫入檔案 — 無大小限制在代理人上下文中可能截斷

[!WARNING] 檢查點 — 需要使用者確認。 你必須詢問使用者偏好哪種策略。 呈現上述比較表,推薦策略 A 為預設,並 等待明確批准。在獲得使用者確認之前,請勿自行決定或繼續進行。


策略 A:Puppeteer 快照 (建議)

啟動無頭 Chrome,捕捉完整渲染的 DOM,並產生一個自包含的 HTML 檔案,其中所有 CSS 都已內嵌,圖片也已轉換為 base64。適用於任何框架 — 不需要 MockPage.jsx。

先決條件

  • 應用程式在本機運行(例如 npm run dev)
  • Node.js 且已安裝 puppeteer(檢查:node -e "require('puppeteer')")

工作流程

  1. 啟動應用程式並記下埠號。

    [!WARNING] 檢查點 — 需要使用者確認。 啟動本地伺服器後,你必須暫停並要求使用者 在執行快照腳本或啟動瀏覽器子代理程式之前進行確認。向使用者回報 URL 和埠號,以便他們 驗證應用程式是否正在運行並正確渲染。在使用者確認之前,請勿進行快照步驟。

  2. 執行快照腳本:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 \
      --output .stitch/home.html \
      --wait 2000
    
  3. 多個頁面 — 每個路由執行一次:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 --output .stitch/home.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/pricing --output .stitch/pricing.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/dashboard --output .stitch/dashboard.html --wait 2000 --html-class dark
    
  4. 清理開發伺服器: 如果是為了執行快照提取而專門啟動的本地開發伺服器,請確保在提取完成後停止伺服器程序或終止背景任務。

腳本標誌

標誌預設值說明
--url(必填)要捕捉的 URL
--output(必填)輸出檔案路徑
--wait1000網路閒置後的額外等待時間(毫秒)。對於延遲加載的應用程式,請增加此值。
--viewport1280x800視口大小,格式為 WIDTHxHEIGHT
--html-class—要添加到 <html> 元素的 class(例如 dark)
--remove-fixedfalse移除固定/黏性元素(Cookie 橫幅、聊天小工具)
--full-heightfalse將視口大小調整為完整的捲動高度
--title—覆蓋頁面標題(設定為路由路徑,例如 /dashboard 或 /settings/profile)
--auth-script—指向一個 JS/TS 模組的路徑,該模組匯出一個 async (page) => void 函數,用於身份驗證
--inline-canvasfalse將 <canvas> 元素(ECharts、Chart.js、D3)轉換為 base64 <img> 標籤

自動執行的操作

  • 捕捉來自 document.styleSheets 的所有 CSSOM 規則(保留動態的 Vite/Tailwind 開發樣式和 CSS-in-JS)
  • 內嵌所有 <link rel="stylesheet"> → <style> 區塊
  • 將 <img> src 和 srcset → base64 資料 URI(跳過外部字型)
  • 內嵌相同來源和相對路徑的圖標字型檔案(@font-face)為 base64 資料 URI,以防止連字顯示為 ASCII 文字
  • 內嵌 <source srcset> URL 為 base64
  • 移除失敗/無效的 srcset 項目,以便瀏覽器退回使用已內嵌的 src
  • 移除 <script> 標籤、Vite HMR 開發樣式區塊(createHotContext、import.meta.hot)和開發覆蓋層
  • 在內嵌之前解析相對的 CSS url() 路徑

框架注意事項

框架注意事項
React + Vite開箱即用。--wait 1000。
Next.js--wait 3000 以等待 SSR 水合。URL:http://localhost:3000。來自 /_next/image 的 <img srcset> 將自動內嵌為 base64。
Angular (@angular/cli / v17+)使用 ng serve 即可開箱即用(預設 URL:http://localhost:4200)。--wait 2000 以等待 Angular Material / PrimeNG 動畫水合和延遲載入路由。
Vue / Nuxt開箱即用。
Svelte / SvelteKit開箱即用。
Storybook使用 Story URL:--url http://localhost:6006/?path=/story/...
SSR (Webpack)可能需要更長的 --wait。

故障排除

問題解決方案
圖片遺失增加 --wait
伺服器停止後圖片顯示為損壞驗證 srcset 是否已內嵌 — 檢查日誌中的 "Inlined N images"。如果 srcset URL 失敗,它們會自動被移除,以便使用 src(已內嵌)。
圖標顯示為文字 / Serif 未設定樣式的字型確保 snapshot.ts 從 document.styleSheets 捕捉 CSSOM(步驟 0),並且相同來源的圖標字型(@font-face)被內嵌為 base64 資料 URI。
Next.js /_next/image 未內嵌確保快照運行時開發伺服器正在運行 — 腳本會從運行中的伺服器獲取優化後的圖片。
暗黑模式未套用--html-class dark
輸出中有 Cookie 橫幅--remove-fixed
頁面需要登入使用 --auth-script ./auth.ts(請參閱下方的「需要驗證的頁面」)
圖表/圖形顯示為空白框使用 --inline-canvas 將 <canvas> 序列化為 base64 <img>
Cannot find module 'puppeteer'npm install -g puppeteer

需要驗證的頁面

對於具有登入守衛的應用程式(Vue Router beforeEach、React ProtectedRoute 等),建立一個小的驗證腳本,並在 Puppeteer 會話中執行:

// auth-myapp.ts
import type { Page } from 'puppeteer';

export default async function authenticate(page: Page) {
  // 範例 1:填寫並提交登入表單
  await page.type('#username', 'admin');
  await page.type('#password', 'password123');
  await page.click('#login-button');
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  // 範例 2:直接注入 Cookie / localStorage
  // await page.evaluate(() => {
  //   localStorage.setItem('token', 'mock-jwt-token');
  // });

  // 範例 3:透過模組注入呼叫應用程式自身的登入 API(Vue/Vite)
  // await page.evaluate(() => {
  //   return new Promise((resolve) => {
  //     const script = document.createElement('script');
  //     script.type = 'module';
  //     script.textContent = `
  //       import { useUserStore } from '/src/store/modules/user.ts';
  //       import { fetchLogin } from '/src/api/auth.ts';
  //       const res = await fetchLogin({ userName: 'Admin', password: '123456' });
  //       useUserStore().setToken(res.token, res.refreshToken);
  //       window.dispatchEvent(new CustomEvent('auth-done'));
  //     `;
  //     document.head.appendChild(script);
  //     window.addEventListener('auth-done', () => resolve(true), { once: true });
  //   });
  // });
}

然後這樣使用:

npx tsx <SKILL_DIR>/scripts/snapshot.ts \
  --url http://localhost:5173/#/dashboard \
  --output .stitch/dashboard.html \
  --auth-script ./auth-myapp.ts \
  --inline-canvas \
  --wait 5000

腳本會先導航到 --url(可能會重新導向到登入頁面),執行你的驗證函數,然後重新導航到原始 --url(使用已驗證的會話)。


策略 B:瀏覽器子代理程式捕捉

當你需要與頁面互動(點擊按鈕、填寫表單、導航分頁)後再進行捕捉時使用。瀏覽器子代理程式為你提供完全的控制權,但對於大型頁面,輸出可能會被截斷。

工作流程

  1. 啟動應用程式在本機。

  2. 使用瀏覽器子代理程式導航。

  3. 根據需要進行互動(點擊、捲動、填寫表單)。

  4. 提取 DOM:document.documentElement.outerHTML

    [!WARNING] 大型頁面可能會被截斷。為了解決這個問題:

    • 在提取之前移除 <style> 標籤:document.querySelectorAll('style').forEach(el => el.remove())
    • 靜態地重新添加樣式(Tailwind CDN 連結、來源 CSS)
  5. 儲存到檔案。


附錄:靜態備援(MockPage.jsx)

[!NOTE] 此方法是最後的手段,適用於應用程式無法在本機運行(相依性損壞、缺少後端、無法繞過的驗證牆)的情況。它需要將 React 組件手動扁平化為一個單一的 JSX 檔案。在任何可能的情況下,優先使用策略 A。

何時使用

  • 應用程式完全無法在本機運行
  • 頁面需要驗證,且沒有 Mock/繞過方法
  • 你需要一個無法透過導航達到的特定 UI 狀態(錯誤畫面、空白狀態)

快速參考

npx tsx <SKILL_DIR>/scripts/extract_inline_html.ts \
  --index-css src/css/App.css \
  --extra-css index.html \
  --outdir .stitch \
  --page src/MockPage.jsx:Page.html:"Page Title"

關鍵標誌:--no-tailwind(非 Tailwind 應用程式)、--html-class dark(暗黑模式)、--css-files(額外的 CSS 檔案)。

自動偵測:Tailwind 配置會自動偵測。@apply 指令會自動使用 <style type="text/tailwindcss">。

MockPage.jsx 規則

  1. 包含完整佈局 — 頁首、側邊欄、頁尾(先閱讀 App.js)
  2. 扁平化所有條件 — 選擇一個狀態,移除所有三元運算子和 && 守衛
  3. 硬編碼所有資料 — 將 {variable} 替換為具體值,展開 .map() 迴圈
  4. 保留標誌 — 使用帶有本地路徑的 <img>(後處理會將它們內嵌)
  5. 移除浮動元素 — Cookie 橫幅、聊天小工具、意見回饋按鈕

後處理

內嵌本地圖片:

npx tsx <SKILL_DIR>/scripts/post_process.ts \
  .stitch/Page.html --base-dir <app-directory>

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

beavon2010/claude-skills

>- Convert frontend code (Vite, React, Angular, Vue, etc.) to a Stitch Design by chaining static HTML extraction, design system extraction, and file upload. **ALWAYS** use this skill when the user's intent is to move existing web apps or React/Angular/Vue components into Stitch (e.g., requests to "save", "migrate", or "upload"). You must use this skill even for simple "save" operations, as it is the only way to ensure the design system is extracted and assets are properly linked.

beavon2010/claude-skills

Analyze Stitch projects and synthesize a semantic design system into DESIGN.md files

beavon2010/claude-skills

Transforms vague UI ideas into polished, Stitch-optimized prompts. Enhances specificity, adds UI/UX keywords, injects design system context, and structures output for better generation results.

beavon2010/claude-skills

>- Extract a comprehensive design system (DESIGN.md) directly from frontend source code — React, Vue, Svelte, Angular, plain HTML/CSS, or any web framework. Analyzes component files, stylesheets, Tailwind configs, theme definitions, and design tokens to produce a rich, Stitch-compatible design system document. Use this skill whenever the user wants to reverse-engineer a design system from an existing codebase, audit the visual language of a project, extract design tokens from source files, or understand the styling patterns in a frontend repo — even if they just say "what does this app look like?" or "pull out the design from this code.

相關技能