快速開始

本文帶你從零建立一個 Swift Web 專案並跑起來,核心流程約 5 分鐘(第一步到第五步);後面三步(API / 站點圖示 / 自訂圖示)按需進行,不做也不影響起步。

第一次接觸 Swift Web?不用先讀任何架構文件——照著本文逐步執行即可,每一步都寫了「做什麼、為什麼、做完應該看到什麼」。

前置條件

開始前確認機器上有這三樣:

條件要求怎麼檢查 / 安裝
Node.js^22.22.3 || ^24.15.0 || >=26.0.0node -v;推薦用 nvm 管理版本
pnpm11+pnpm -v;沒有就 npm install -g pnpm
私倉權限能存取內部 npm 私服第一步的安裝腳本會自動設定,無需手動

開發與建構推薦 Node.js 26.13.0 LTS、pnpm 12.16.1。開發機、CI 作業與伺服器的 Node 版本可以不同;伺服器按實際依賴的 engines 校驗,使用 Nuxt 4.6.4 時 Node 24 至少為 24.15.0,無需跟隨開發機升級到 26。

為什麼 pnpm 必須 11+:starter 的 engines.pnpm: ">=11" 是硬閘——低版本跑 pnpm install 會直接報 ERR_PNPM_UNSUPPORTED_ENGINE 並中止,這是刻意設計(pnpm 11 起預設開啟供應鏈安全策略)。

第一步:安裝 CLI

sw 是 Swift Web 的腳手架命令,裝一次全域可用。

macOS / Linux

curl -sSL https://sw.djatm.cloud/install.sh | bash

腳本一鍵完成:檢查 Node.js → 安裝並驗證 pnpm(如缺少)→ 初始化全域命令目錄與目前腳本的 PATH → 設定私倉位址 → 全域安裝 @swift-web/cli。

若提示 Corepack 快取中的 pnpm.cjs 缺失,先用 pnpm 官方安裝腳本重新安裝 pnpm,成功後重新開啟終端再試。安裝腳本會保留原始錯誤,並在 pnpm 或 pnpm setup 失敗時中止。安裝成功後,已開啟的終端若找不到 sw,重新開啟終端載入新的 PATH。

Windows(PowerShell)

irm https://sw.djatm.cloud/install.ps1 | iex

Windows 需要先自行安裝 Node.js(^22.22.3 || ^24.15.0 || >=26.0.0);PowerShell 5.1+(Windows 10/11 預設內建)。

手動安裝

如果不想用一鍵腳本,分兩步手動來。先設定私有 npm 倉庫(每台機器只需一次):

macOS / Linux:

echo '@swift-web:registry=https://npm.djatm.cloud/' >> ~/.npmrc

Windows(PowerShell):

Add-Content "$env:USERPROFILE\.npmrc" "`n@swift-web:registry=https://npm.djatm.cloud/"

再全域安裝:

pnpm add -g @swift-web/cli

發布當天升級裝到舊版? pnpm ≥11 預設有 24 小時「冷靜期」(minimumReleaseAge),剛發布的版本一天內解析不到, pnpm add -g 會靜默裝到上一版。專案裡 pnpm-workspace.yaml 的豁免管不到全域安裝,要在使用者級 ~/.npmrc 加一行 minimumReleaseAgeExclude[]=@swift-web/*(一鍵安裝腳本已自動寫入),或暫時釘版本 pnpm add -g @swift-web/cli@<版本>。

驗證安裝

sw -v
# 輸出類似:0.8.x(以當前安裝的 @swift-web/cli 版本為準)

能列印出版本號就說明裝好了。

第二步:建立專案

用 sw create 初始化新專案。出於倉庫命名一致性,它只接受兩種格式:

YC 格式(內部專案的強制命名)

sw create YC001-WEB-專案名稱

命名規則:YC + 數字編號 + -WEB- + 中文或英文專案標題,大小寫不敏感。

範例:

sw create YC117-WEB-影城管理系統
# 生成目錄:yc117_web/
# 專案 name:yc117
# 專案 title:影城管理系統

CLI 自動從名字裡提取 name 和 title,不再重複詢問。

在當前目錄初始化(.)

已經手工建好目錄、或想直接在倉庫根目錄建立時,傳 .:

mkdir my-project && cd my-project
sw create .

此時 CLI 會互動式詢問專案標題和描述;project.name 取當前目錄名。

一般字串專案名會被拒絕(如 sw create my-project)——保證所有內部專案都能從倉庫名一眼識別出編號。

互動式設定精靈

建立過程中 CLI 會依次詢問是否啟用以下能力(不確定就直接按 Enter 選預設,以後都能用 sw config set 改,不是一錘子買賣):

問題預設作用
主題模式固定淺色light / dark / system(跟隨系統)/ toggle(使用者可切,掛 useTheme() + SwThemeSwitch;再追問三態 / 兩態)
啟用多語言(i18n)No整合 @nuxtjs/i18n;可多選語言
啟用 PWANo注入 Service Worker + manifest
啟用 WebSocketNo註冊全域 $ws 用戶端
啟用 Tailwind CSS v4No自動裝相依 + 接入 Vite 外掛
是否立即 pnpm installYes同步安裝相依

選擇結果寫入 swift.config.json,並同步修改 nuxt.config.ts / i18n/locales/ 等相關檔案。

非互動模式(CI / 腳本)

sw create YC001-WEB-專案名稱 --yes        # 跳過互動,全部用預設值
sw create YC001-WEB-專案名稱 --yes --json # 額外輸出結構化 JSON,便於腳本解析

第三步:進入專案目錄

cd yc001_web   # 目錄名根據 YC 編號自動生成

互動模式下 CLI 已經問過「是否立即安裝相依?」——選了 Yes 就不用再手動 pnpm install。

第四步:設定環境變數

sw create 已自動把 .env.dev.example 複製為 .env,直接編輯即可(不需要自己 cp):

# 編輯 .env,至少填寫兩個必填項:
NUXT_PUBLIC_SITE_URL=http://localhost:3000
NUXT_PUBLIC_API_BASE=https://api.your-domain.com
  • NUXT_PUBLIC_SITE_URL:站點自己的位址,本機開發先填 http://localhost:3000 就行。 ⚠️ 它還有第二重作用:設了它,canonical / og:url / sitemap 會收斂到該網域、不再跟隨使用者實際存取的網域。單網域站沒影響;多網域(防封網域)站應留空,讓各鏡像自引用、獨立被收錄(詳見 SEO 指南)
  • NUXT_PUBLIC_API_BASE:後端 API 位址——還沒有後端?沒關係,先隨便留著,第六步會講怎麼在沒後端的情況下開發

其餘欄位(YAPI 程式碼生成等開發期工具配置)按需填寫,範例檔案裡每一行都有註解說明。cookie 名 / 快取前綴 / AES 金鑰等專案常數不在 .env ——它們隨程式碼寫在 nuxt.config.ts 的 runtimeConfig 預設值裡,建置產物自包含、部署後執行期零必填 env(臨時覆蓋可用同名 NUXT_PUBLIC_* 程序環境變數)。

.env 在 .gitignore 裡不會提交,敏感金鑰透過安全管道在團隊內共享。

第五步:啟動開發伺服器

pnpm dev

看到以下輸出即啟動成功:

  ➜  Local:   http://localhost:3000/
  ➜  Network: http://0.0.0.0:3000/

瀏覽器打開 http://localhost:3000,看到 Starter 首頁就算跑通了。🎉


到這裡專案已經能跑了。 下面三步是起步後的常見事項——都不阻塞開發,按你的實際節奏做:

步驟什麼時候做不做會怎樣
第六步 · 初始化 API後端 + YAPI 文件就緒後沒法調真實介面;可用 systemInfo: false 先做靜態頁
第七步 · 生成站點圖示拿到產品 logo 後,上線前做完即可瀏覽器分頁是預設圖示,不影響功能
第八步 · 自訂 SVG 圖示頁面需要業務圖示時隨用隨加無影響

第六步:初始化 API(後端就緒後)

專案的 API 類型和請求函式由腳本從介面文件(YAPI 或 OpenAPI 3 spec)自動生成,不手寫。

後端已就緒

  1. 文件源設定分兩處(向後端同事要值)——非秘密寫在 nuxt.config.ts 的 swiftConfig.apiDocs(入庫隨倉走,範本裡有佔位區塊),秘密只留 .env:
    // nuxt.config.ts → swiftConfig
    apiDocs: { source: 'yapi', url: 'https://your-yapi-host.com', project: 123 },
    
    # .env —— 只放 token
    API_DOCS_TOKEN=xxxxxxxx
    

    OpenAPI 源同理:source 填 openapi、url 填 spec 位址,spec 不在鑑權後面就不需要 token。
  2. 生成:
    sw run generate-api
    

    完成後 app/api/index.ts、app/api/modules/*.ts、app/api/types/*.ts 就是當前後端介面的完整快照,頁面裡直接 api.模組.方法() 呼叫。後端介面有變化時重跑一次即可。

後端 / YAPI 還沒就緒:先做靜態頁

專案初期後端框架還沒搭好、YAPI 文件還沒生成是常態。此時想先開發不調介面的靜態頁面,把 nuxt.config.ts 裡 swiftConfig 的 systemInfo 臨時設為 false:

// nuxt.config.ts → swiftConfig
systemInfo: false,   // 臨時:跳過啟動時拉取 /system/info(後端沒好時整站不拉)

這是什麼:framework 啟動時預設會請求後端的 /system/info 拿站點設定(站點標題、圖片解密金鑰、選單、埋點設定等)。後端不存在時這個請求會失敗刷錯——關掉它,靜態頁面開發就清淨了。

  • 關閉期間依賴 /system/info 的能力(.bnc 加密圖解密、後端選單、埋點設定等)拿不到資料,純靜態開發無影響;
  • 若登入後端也未就緒,dev 主控台可能還有登入介面的報錯,不影響靜態頁面——介意的話可在 swiftConfig.auth 一併關閉(見框架設定);
  • 後端就緒後記得改回(刪掉 systemInfo: false 這行恢復預設),再回到上面跑 sw run generate-api。

第七步:生成站點圖示(拿到 logo 後)

這一步生成瀏覽器分頁 favicon 和 PWA 應用圖示。不必在專案建立後立刻做——拿到產品 logo 再做、上線前補上都來得及。

  1. 把 logo 源圖放到 app/assets/ 下,二選一:
    • icon.svg(推薦):向量;還可以在 SVG 裡內嵌 @media (prefers-color-scheme: dark) 讓 favicon 跟隨系統明暗
    • icon.png:業務 logo 只有點陣圖時用(無主題切換能力)

    兩個都放時優先用 SVG。
  2. 生成:
    sw run generate-icons
    

    一條命令輸出全套:
    產物用途
    public/favicon.svg現代瀏覽器分頁圖示(僅 SVG 輸入時生成)
    public/favicon.png(48×48)分頁 PNG 兜底
    public/icons/apple-touch-icon.png(180×180)iOS Safari「加入主畫面」
    public/icons/icon-192.png / icon-512.pngPWA manifest 圖示

沒開 PWA 也可以放心跑——PWA 尺寸的圖示生成了也只是靜靜躺在 public/icons/,不產生任何副作用;將來開啟 PWA 時 @vite-pwa/nuxt 會自動接管 manifest 並引用它們。

第八步:自訂 SVG 圖示(隨用隨加)

頁面裡需要業務圖示(導覽、按鈕、狀態標識等 SVG)時:

  1. 把 SVG 檔案放進 app/assets/icons/,檔名即圖示名(如 game.svg);
  2. dev 模式下自動生效——starter 內建的 Vite 外掛監聽這個目錄,放入 / 修改 SVG 會立即注入 app/components/AppIcon.vue(寫進 <!-- ICONS:START --> 標記區)並熱更新,通常什麼命令都不用跑;
  3. 模板裡直接用:
    <AppIcon name="game" />
    <AppIcon name="game" :width="32" color="var(--primary)" />
    

極少數情況(比如沒開 dev server 時批次加圖示)才需要手動執行 sw run inject-icons 觸發一次注入。

注意區分:業務 SVG 圖示走 AppIcon(本節);通用 UI 圖示(箭頭/關閉等)用圖示庫如 @phosphor-icons/vue;點陣內容圖用 SwImage。選型詳見開發規範 · 圖像資產選型。

給 AI 用的:MCP 能力(零設定自帶)

如果你用 Claude Code / Cursor 等 AI 程式設計工具開發,這一節會讓效率翻倍——而且什麼都不用配:starter 自帶 MCP 設定(內容就是啟動 sw --mcp)——Claude Code 讀 .mcp.json,Cursor 讀 .cursor/mcp.json,兩份都已入庫、內容相同,AI 工具打開專案目錄即自動接入 Swift Web 的 MCP server。

有哪些能力

分組MCP 工具作用
腳手架sw_add_page / sw_add_component / sw_add_store / sw_add_api按規範模板新建頁面 / 元件 / store / API 模組
專案設定sw_config_get / sw_config_set / sw_config_sync讀寫 swift.config.json 並聯動 nuxt.config.ts
腳本執行sw_run列出 / 執行 package.json 裡的任意腳本(generate-api / generate-icons / test…)
文件查詢sw_framework_docs查當前安裝版本的 framework 元件 / composable / store / util / 設定文件(富 JSDoc + 範例 + props + 關聯 gotcha),不傳名則列目錄
介面查詢sw_project_apis查當前專案後端 API 清單(解析 app/api 產物),開發頁面業務前先查該呼叫哪個介面
專案資訊sw_info / sw_version / sw_upgrade / sw_create專案中繼資料 / CLI 版本 / 檢查升級 / 建立專案

自然語言驅動範例

接入後你不需要記任何命令,對 AI 說人話即可:

你:幫我新建一個「關於我們」頁面 AI:呼叫 sw_add_page 建立 app/pages/about-us.vue(已含 defineRouteRules / useSeo 模板),然後接著填充內容。

你:這個專案開了哪些框架能力? AI:呼叫 sw_config_get 讀取 swift.config.json,告訴你 theme / i18n / pwa / tracker 的當前開關狀態。

你:SwImage 都有什麼 props?加密圖怎麼用? AI:呼叫 sw_framework_docs("SwImage") 拿到你裝的這個版本的完整文件作答——比翻文件站更準(不會有版本錯位)。

你:後端 YAPI 更新了,同步一下介面 AI:呼叫 sw_run("generate-api") 重新生成 app/api/,並彙報變更。

你:把多語言打開 AI:呼叫 sw_config_set("framework.i18n.enabled", true)——自動解開 nuxt.config 註解、建立語言檔案骨架。

你:幫我建一個使用者收藏的 store AI:呼叫 sw_add_store 生成 app/store/user-favorites.ts(Pinia 規範模板),再按需求填充 state / action。

你:framework 出新版了嗎?幫我升級 AI:呼叫 sw_upgrade 檢查私服最新版本並執行升級(內部改寫 package.json 的 framework 版本範圍,再跑 pnpm install --lockfile-only 與 pnpm install --frozen-lockfile),升級完提醒你重啟 dev server。

你:加一個「排行榜」頁面,內容一小時更新一次就行 AI:呼叫 sw_add_page 建立 app/pages/ranking.vue,並把模板裡的 defineRouteRules 改成 { isr: 3600 }——工具管骨架,渲染策略這類判斷由 AI 結合上下文補上。

為什麼這很重要:AI 透過 MCP 拿到的是結構化、帶版本的事實(而不是憑訓練記憶猜 API),加上專案裡的 CLAUDE.md 協作規範,AI 產出的程式碼天然符合本框架約定。這正是 Swift Web「AI 友好」設計初衷的落地。

這裡只示範常見幾類;完整 15 個 MCP 工具與全部可設定欄位見 CLI 命令參考 · AI 工具鏈(MCP)。

生成的專案結構

sw create 從 verdaccio 私服(npm.djatm.cloud)npm pack @swift-web/starter 拉最新 starter 模板,解壓後替換佔位符。當前骨架如下(具體內容隨 starter 迭代而變化):

yc001_web/
├── app/
│   ├── components/         業務元件(AppHeader / AppFooter / LoginForm / TabBar 等)
│   ├── pages/              路由頁面(index / login / register / mine / ...)
│   ├── layouts/            佈局(default.vue / empty.vue)
│   ├── composables/        業務級 composable
│   ├── store/              業務級 Pinia store
│   ├── api/                API 請求模組(第六步 generate-api 生成)
│   ├── assets/             CSS 變數與全域樣式、圖示源圖(icon.svg)、icons/ 業務 SVG
│   ├── middleware/         業務級路由守衛
│   ├── plugins/            業務級外掛
│   ├── utils/              業務工具函式
│   ├── constants/          業務常數
│   ├── types/              業務類型定義
│   └── app.vue / error.vue 應用入口 / 全域錯誤頁
├── public/                 靜態資源(images / icons / favicon——第七步 generate-icons 產物)
├── i18n/                   多語言翻譯檔案(僅啟用 i18n 時生成,按所選語言裁剪)
├── server/                 Nitro 伺服端 API
├── scripts/                建構腳本(inject-icons / optimize-images / generate-api 等薄封裝)
├── tests/                  測試(unit / nuxt 單測 + e2e Playwright)
├── config/                 執行時設定(env 校驗等)
├── types/                  全域類型宣告
├── patches/                pnpm patch 補丁
├── deploy/                 生產部署指令稿 deploy-prod.sh(`pnpm deploy:prod` 入口)
├── .env.dev.example        環境變數範例(提交到 git;生產對應 .env.prod.example)
├── .env                    本機環境變數(sw create 自動生成,不提交 git)
├── .mcp.json               MCP 設定(Claude Code;Cursor 讀 .cursor/mcp.json,內容相同)
├── .gitlab-ci.yml          CI 檢查(型別 / lint / 單元測試覆蓋率 / 建置)
├── CLAUDE.md               AI 協作規範(另有 .cursor/ .github/ 等 AI 工具約定檔案)
├── nuxt.config.ts          Nuxt 設定(含 swiftConfig 選項——第六步的 systemInfo 就在這裡)
├── swift.config.json       Swift Web 專案中繼資料
├── tsconfig.json           TypeScript 設定(另有 eslint / stylelint / prettier / playwright / vitest 各自 config)
└── ecosystem.config.cjs    PM2 生產行程設定(另有 ecosystem.dev.config.cjs 測試環境用;共機測試須改唯一 PORT)

swift.config.json

Swift Web 的專案設定檔,sw 命令靠它識別 Swift Web 專案。--yes 模式建立後的預設結構:

{
  "project": {
    "name": "yc001",
    "type": "web",
    "title": "專案名稱",
    "description": ""
  },
  "framework": {
    "theme": { "mode": "light" },
    "i18n": { "enabled": false, "defaultLocale": "zh-CN", "locales": ["zh-CN"] },
    "pwa": false,
    "websocket": false,
    "errorHandler": false,
    "tracker": { "enabled": true, "autoPageView": true }
  },
  "features": {
    "tailwind": false
  }
}

欄位說明:

  • project.name — 專案 npm 套件名前綴(小寫),由 YC 編號衍生,如 yc001
  • project.type — 鎖死為 'web',sw config set project.type 會報 TYPE_LOCKED
  • project.title / description — 用於 nuxt.config.ts 的 title / meta
  • framework.* — 框架能力開關,與 nuxt.config.ts 的 swiftConfig 聯動,sw config set 會同步更新 nuxt.config.ts
  • framework.tracker — 打點底座開關(預設開,精靈不詢問);關閉上報用 sw config set framework.tracker.enabled false
  • features.tailwind — Tailwind v4 開關;sw config set features.tailwind true 自動裝相依、改設定、建 tailwind.css

常用開發命令

命令說明
pnpm dev啟動開發伺服器(熱更新)
pnpm build建構生產版本
pnpm analyze建構並打開 bundle 體積分析
pnpm preview本機預覽生產建構
pnpm generate靜態站點生成(SSG)
pnpm clean清除 .nuxt 快取目錄
pnpm generate-api從 YAPI 自動生成 API 類型和請求函式(第六步)
pnpm generate-icons從 app/assets/icon.svg 生成 favicon + PWA 圖示(第七步)
pnpm optimize-images批次壓縮 public/images/ 下的圖片並生成多種格式
pnpm inject-icons手動把 assets/icons/ 的 SVG 注入 AppIcon(dev 期自動,一般不用)
pnpm lint串行執行 eslint + stylelint(含 --fix)
pnpm type-checkNuxt TypeScript 類型檢查
pnpm test執行 Vitest 單元測試(一次性)
pnpm test:watchVitest 監聽模式
pnpm test:coverageVitest 覆蓋率
pnpm test:e2ePlaywright 端到端測試
pnpm test:e2e:ui以 UI 模式執行 Playwright 測試

所有 pnpm <script> 都可以等價寫成 sw run <script>(AI 工具 / 終端統一入口)。不確定有哪些腳本時,在專案根目錄跑 sw run 列出全部腳本及一句話描述。

下一步

  • 閱讀 CLI 命令參考 了解所有 sw 命令(含 sw run,starter 自帶 MCP 設定讓 AI 工具鏈開箱即用)
  • 閱讀 開發規範 了解團隊開發約定
  • 閱讀 框架設定 了解 swiftConfig 所有選項