iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0

在配置了 ESLint 規則、Agent 技能與 MCP 伺服器之後,Gemini 的表現依然沒有完全符合我的預期。

Gemini 難以捉摸的行為

在進行 AI 輔助寫程式時,有些行為讓我非常困擾:

  1. Gemini 太過躁進:每次進行微小編輯後,它都會提示執行格式化、程式碼檢查與測試。我發現自己得在鍵盤上不斷按「Y」,按到手指都快麻了。
  2. Gemini 沒有遵循 Angular 的良好實作做法來生成程式碼:
    • 元件使用 effect() 來更新 Signal,這是不好的做法。
    • 應用程式使用 ReactiveForm 來建立新表單,而非使用 Angular v22 中的 SignalForm
    • 直接存取 window 或 document,而不是使用 Angular 的注入權杖。如果該應用程式是 Angular SSR 應用程式,直接存取 window 或 document 可能會導致應用程式當機。
  3. 即使應用程式使用了 TailwindCSS V4,元件樣式依然不一致:要麼範本充斥著雜亂的行內 TailwindCSS 類別,要麼生成的元件 CSS 檔案使用的是原生 CSS 樣式而非 TailwindCSS 類別。
  4. Gemini 沒有為任務選擇最佳工具:當我詢問 Angular 相關問題時,Gemini 使用 WebSearch 工具在網際網路上搜尋,而不是使用 angular-cli MCP 伺服器的 search_documentations 工具。

當我遇到不盡理想的情況時,我會請 AI 協助我更新 GEMINI.mdAGENTS.mdCONTEXT.md,這樣類似的問題就不會再次發生。

自訂 GEMINI.md

我從 Angular 官方網站複製了 GEMINI.md,並在其中加入了新規則

Angular 團隊提供了 effect,但他們期望我們不要在許多使用案例中使用它

- **DOM Manipulation and Side-Effects**:
  - **No `effect()` for DOM Manipulation**: Never use the standard `effect()` function to interact with or manipulate the DOM (doing so is unsafe, can cause layout thrashing, and crashes during Server-Side Rendering).
  - **Prefer `afterRenderEffect()` for DOM**: For manual DOM tasks (e.g., measuring dimensions, focusing inputs, or integrating non-Angular charts), always use `afterRenderEffect()` or `afterNextRender()`. Perform any DOM-write operations strictly inside the scheduled `write` phase callback.
  - **Prefer `linkedSignal()` for State Synchronization**: Never use `effect()` to reset or synchronize local signal states. Use `linkedSignal()` to cleanly reset, synchronize, or clamp values in response to other source signal changes.

effect() 雖然不是反模式,但它的設計初衷是用於更新非響應式資料(如本機儲存空間)或發出輸出。如果某個 Signal 取決於一或多個 Signal 的變更,我們應該使用 linkedsignal()。如果我們需要寫入 DOM 元素,我們應該在元件建構函式中呼叫 afterREnderEffect() 回呼函式。

## SSR & Browser Globals Protection

- **Avoid SSR Crashes**: Never access raw browser global objects (`window`, `document`, `navigator`, `localStorage`, etc.) directly inside components, services, or utilities. Doing so crashes Server-Side Rendering (SSR) or pre-rendering contexts.

- **Inject `DOCUMENT`**: Always inject Angular's built-in `DOCUMENT` token from `@angular/common` instead of referencing the global `document` keyword.

- **Composed Browser-Global Injection Tokens**: To safely reference browser-only global objects (such as `window`, `localStorage`, `sessionStorage`, `navigator`, etc.) without crashing during SSR:
  1. Define a global cached `IS_BROWSER` token to identify the platform context.
  2. **Compose other global tokens** by injecting `IS_BROWSER` into their factory callbacks.
  3. Explicitly type these composed tokens as `<Type> | null` so that TypeScript natively compile-checks and forces developers to verify existence before accessing them:

我新增了 SSR & Browser Globals Protection 章節來解釋存取全域物件(例如 window)的安全方式。我們使用 isPlatformBrowser()PLATFORM_ID 注入權杖來判斷應用程式目前是用戶端渲染(CSR)還是伺服器端渲染(SSR)。如果是前者,window 已被定義且可安全使用;否則,我們應該回傳 undefinednull 以避免非預期的當機。

AGENTS.md

當我們在 Antigravity CLI 中執行 /setup-matt-pocock-skills 時,它在專案中新增了一個基礎的 AGENTS.md。我透過反覆迭代修改它以建立新規則,進而解決我的痛點。

AGENTS.md 規則設定檔

Tailwind CSS 規則

2. **Tailwind CSS v4 Component Styling**: Always prioritize Tailwind CSS v4 `@apply` utility classes over raw vanilla CSS inside component-scoped stylesheets. To compile correctly in isolation, you MUST prepend an explicit `@reference` directive pointing relatively to the global `src/styles.css` stylesheet file.
   - **Correct**:

     @reference "../../../../../styles.css";
     .toast-container {
       @apply fixed top-6 right-6 flex flex-col;
     }

套用 TailwindCSS V4 類別,並將行內 CSS 類別提取至外部 CSS 檔案中。

Angular 最佳實作做法

4. **Signal Forms (`@angular/forms/signals`) Constraint**: All forms in this repository MUST be built using Angular's modern, reactive Signal Forms (`@angular/forms/signals`). The use of legacy Reactive Forms (`FormGroup`, `FormControl`, `FormBuilder` from `@angular/forms`) or template-driven forms is strictly prohibited. This guarantees optimal performance, native reactivity, and a unified state management architecture.

我的技術堆疊是 Angular v22,而 SignalForm 在此版本中已經穩定,因此我強制要求所有新表單都必須使用 Signal Forms 來實作。

文件查詢規則

When researching framework/platform APIs, architecture, or resolving errors:

1. **Angular Questions (`angular-cli` MCP)**:
   - Primary: Query the `angular-cli` MCP server (`search_documentation`, `get_best_practices`, `ai_tutor`) targeting the project's current major Angular version (`22`).
   - Fallback: Use web search if the MCP server is unavailable or returns no results.

Gemini 變得很偷懶,選擇使用 WebSearch 工具來尋找 Angular 問題的答案。我建立了一條規則,強制使用 angular-cli MCP 伺服器來搜尋文件,並以網路搜尋作為備援方案。這對 Firebase 查詢也是一樣:優先使用 Firebase MCP 伺服器,並以網路搜尋作為備援。

品質保證規則

2. **Defer Full-Suite Verification to End-of-Task**:
   - Do NOT run full repo-wide commands (`npm run lint`, `npm run format`, `npm test`, full `npm run test:once`, `npm run build`) recursively after every individual contiguous block edit. Gather all contiguous and related edits, apply them first, and run full validation commands EXACTLY ONCE at the end of the complete task milestone.

這條規則將格式化、程式碼檢查與測試延後至對所有檔案完成修改之後。這縮短了開發時間,並減少了我需要按「Y」以繼續的次數。

3. **ESLint Compliance in Spec Files**:
   - When generating or updating unit tests (`*.spec.ts`), ensure they adhere to the project's ESLint config. Avoid common violations like relative imports in TypeScript (always use absolute path aliases starting with `@/` for TS files; relative paths are strictly for CSS `@reference` directives) and missing curly braces. Do not use legacy reactive forms or custom test classes that expand member visibility just for testing.

雖然模型能夠高效率地生成新的測試與程式碼,但它有時會投機取巧以讓測試通過。例如將變數轉型為 as any 而不是 as unknown。當變更推送到存放庫時,自動化管線會因為 ESLint 錯誤而失敗。這條規則要求模型在宣告任務完成之前,必須先修正所有違反 ESLint 規則的生成程式碼。

CONTEXT.md

包含領域詞典的完整 CONTEXT.md 內容

當專案剛啟動或正在進行中時,該檔案應該用 1 到 2 句話來說明問題的背景脈絡。例如:它從文字生成語音,並使用 Web Audio API 播放語音。當程式碼趨於穩定後,可以請 AI 掃描程式碼工作區以進行更新。

相關資源:
官方 Angular GEMINI.md 文件


上一篇
Day 5 - 在 Antigravity CLI 註冊全域 Chrome DevTool 與 Vitest MCP 伺服器 - Part 2
系列文
2026年,如何利用 Antigravity CLI、Gemini、各項技能及 MCP Server 建構基於 Firebase 的 Angular 應用6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言