mcpField
W
web-master

web-master

github.com/robot-inventor開発349 回インストール5 日前に更新
リポジトリ

web-master について

Web Masterは、Web関連コードを書くエージェント向けのスキルで、TypeScript、CSS、HTML/JSX、テストの指針を示します。型安全な設計、簡潔なスタイル、観測可能な動作に基づくテストを重視します。

主な機能

  1. 01TypeScriptの型安全性に関する指針
  2. 02CSSとタイポグラフィの規約
  3. 03HTMLとJSXの簡素化
  4. 04観測可能な動作に基づくテスト設計
  5. 05不要なモックを避けるための指針

活用シーン

  1. 01TypeScriptによるWeb機能の実装
  2. 02CSSとタイポグラフィの調整
  3. 03コンポーネントマークアップのレビュー
  4. 04Web動作を検証するテストの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/robot-inventor/agent-skills --skill web-master

インストール後、Claude Code で/web-masterを入力して読み込まれたか確認します。

詳細

Web Master

Web 関連のコードを書く際は、以下の指示に従ってください。

TypeScript

型アサーションを使用しない

必要な場合を除き、型アサーションは使用しないでください。後で必要になるかもしれないという理由で、最初から型アサーションを追加してはいけません。次の条件をすべて満たす場合に限り、型アサーションを使用できます。

  • まず型アサーションを使わずにコードを書き、型エラーが発生する。
  • 別の箇所の型定義を改善しても、その型エラーを解決できない。
  • 型アサーションを追加しても、型安全性が損なわれない。
ReturnType を使用しない

必要な場合を除き、ReturnType は使用しないでください。代わりに、以下の方法を使用してください。

プロジェクト内の特定の関数の戻り値の型を、その関数以外の場所で使用する必要がある場合:

  • boolean や string などの単純なプリミティブ型の場合は、型を直接記述してください。
  • 複雑な型の場合は、名前付きの型を定義し、関数の戻り値の型として指定して((): T => {})、T を再利用してください。

ライブラリ関数の戻り値の型が必要な場合:

  • まず関数の型定義を確認してください。
  • ライブラリがその型をエクスポートしている場合は、エクスポートされた型を使用してください。
    • 別のライブラリ関数の戻り値を型引数として渡す必要があり、そのライブラリが関数の戻り値の型をエクスポートしていない場合は、型引数の中で ReturnType を使用できます。
  • ライブラリがその型をエクスポートしていない場合:
    • 単純なプリミティブ型の場合は、型を直接記述してください。
    • それ以外の場合は、ReturnType を使用できます。
// Incorrect
import foo from "foo";

const myFunc = (): string => {...};

const myFunc2 = (arg: ReturnType<typeof foo>, arg2: ReturnType<typeof myFunc>): number => {...};

// Correct
import type { FooResult } from "foo";

const myFunc = (): string => {...};

const myFunc2 = (arg: FooResult, arg2: string): number => {...};
型注釈より as const satisfies を優先する

必要な場合を除き、型注釈を追加しないでください。まず型注釈なしでコードを書いてください。それによって型エラーが発生する場合は、まず別の箇所の型定義を改善して解決できないか試してください。そうした変更で問題を解決できない場合の最終手段としてのみ、型注釈を使用してください。

オブジェクトを記述する際、特定の型に準拠することを保証する必要がある場合は、satisfies を使用してください。文字列の配列など、型が明らかな値に satisfies を使用する必要はありません。as const satisfies の値の型に ReadOnly を指定する必要もありません。

// Incorrect
const foo: T = {
    bar: "bar"
};

const foo = {
    bar: "bar"
} as const satisfies ReadOnly<T>;

// Correct
const foo = {
    bar: "bar"
} as const satisfies T;
ESLint ルールを無効にしない

手軽な回避策として ESLint ルールを無効にしないでください。ESLint のエラーは、通常、無意味な障害を作り出すのではなく、コードの品質の低さを指摘しています。エラーを黙らせるためにルールを無効にしても、根本的な問題は残ります。

より良い方法がない場合の最終手段としてのみ、ESLint ルールを無効にしてください。ESLint エラーには、次のように対処してください。

  1. ESLint が何を指摘しているのかを理解します。該当するコードと、そのルールの目的を特定します。
  2. その目的に対応するようにコードを改善します。
  3. ルールに従うことでコードが過度に複雑になる場合、警告が明らかに誤検知である場合、ルールを無効にする正当な理由がほかにある場合、または修正案がルールの根本的な意図に反する可能性がある場合に限り、ルールを無効にします。
例

ESLint の sort-imports ルールは、一貫性のあるインポート順を定めています。適切にモジュール化されたコードでは、動作がインポート順に依存しないはずなので、このルールに従ってください。

// Incorrect
/* eslint-disable sort-imports */
import foo from "foo";
import bar from "bar";

// Correct
import bar from "bar";
import foo from "foo";

no-magic-numbers ルールは、数値の用途が明確でない場合に、意味のある名前を付けるためにあります。1 分間の秒数を表す 60 のように、値の意味が明らかな場合は、ルールを満たすためだけに定数にする必要はありません。その場合は、ルールを無効にしても問題ありません。1 を ONE という名前の定数に置き換えるのも、no-magic-numbers の目的に反します。値に意味のある名前を付けるか、すでに意味が明らかな場合はルールを無効にしてください。また、そもそもその数値をハードコードする必要があるかどうかも検討してください。

// Incorrect
// eslint-disable-next-line no-magic-numbers
if (myArray.length !== 0) {...}

// Correct
if (myArray.length) {...}

max-lines と max-lines-per-function ルールは、コードの可読性と保守性を示す指標として用意されています。これらのルールによる警告は、コードの設計に問題がある可能性を示しています。ルールを満たすために改行を削除するだけでは表面的な解決にすぎず、実際にはコードが読みにくくなり、ルールの本質に反します。代わりに、冗長なコードを削除するか、適切に再構成してモジュール化し、問題を解決してください。制限をわずかに超えているだけで、コードの設計に問題がない場合は、改行を削除したり、無理に分割したりするのではなく、ルールを無効にしてください。

自分で検証しないでください

TypeScript の型は、JavaScript に後付けするものではありません。型を意識して設計することで、コードをすっきりと効率的に保てます。型を適切に設計すれば、ユーザー入力や Web API のレスポンスなど、プロジェクトの境界を除いて検証が必要になることはほとんどありません。型に基づいてコードを適切に設計すると、関数の入力と出力が信頼できるものになり、値を繰り返し検証する必要がなくなります。

プロジェクトの依存関係を確認し、検証ライブラリがインストールされているか調べてください。インストールされている場合は、独自のバリデーターを作成するのではなく、そのライブラリの機能を活用してください。

// Incorrect
const isRecord = (value: unknown): value is Record<string, unknown> =>
    typeof value === "object" && value !== null && !Array.isArray(value);
const isParson = (value: unknown): value is Person =>
    isRecord(value) && typeof value.name === "string" && typeof value.age === "number" && value.age >= 0;

isParson(externalValue) ? externalValue : "Unknown";

// Correct
import { type } from "arktype";

const Person = type({
    name: "string",
    age: "number >= 0"
});

const parsed = Person(externalValue);
parsed instanceof type.errors ? "Unknown" : parsed;

CSS

必要なスタイルだけを定義する

CSS を記述する際は、まずプロジェクトにリセット CSS が読み込まれているか、また、そのリセット CSS が現在作業しているページまたはレイアウトファイルに適用されているかを確認してください。リセット CSS が適用されている場合は、margin: 0 のようにリセット CSS と重複するスタイルを定義する必要はありません(これは一例であり、これに限りません)。

CSS では、親要素から変更する必要があるプロパティだけを指定し、再度変更する必要のないプロパティは指定しないでください。CSS には継承があることを念頭に置いて、それに応じたスタイルを設定してください。

/* reset.css */
* {
    margin: 0;
}
/* style.css */

/* Incorrect */
h1 {
    margin: 0;
    font-weight: bold;
}

h1 div {
    font-weight: bold;
}

/* Correct */
h1 {
    font-weight: bold;
}
意図的なタイポグラフィ設計

コードブロックなど、どうしても必要な場合を除き、ドキュメントルートの外で font-family を指定しないでください。また、重要でない通知を小さくしたり、見出しを大きくしたりするなど、明確な理由がない限り、フォントサイズを変更しないでください。基本のフォントサイズはブラウザーの設定によって上書きされる場合があるため、フォントサイズやフォントサイズに依存する領域には、px ではなく em または rem を使用してください。

/* Incorrect */
h1 {
    font-size: 32px;
}

/* Correct */
h1 {
    font-size: 2rem;
}

HTML と JSX

冗長な定義を避ける

UI コンポーネントライブラリが利用できる場合は、コンポーネントを積極的に使用し、どうしても必要な場合を除いて独自の実装を減らしてください。

また、不要な属性を追加しないでください。たとえば、アイコンコンポーネントライブラリでは aria-hidden がデフォルトで設定されている場合があります。そのような場合は、コンポーネントの使用時にこの属性を再度設定する必要はありません。

テスト

テストを適切に設計する

アプリケーションが所有するモジュールをモックしないでください。実際の実装を優先し、実装のつなぎ込みではなく、観察可能な振る舞いをテストしてください。モックは、処理に時間がかかる場合、非決定的な場合、破壊的な場合、または外部との境界でのみ使用してください。アサーションがモックの呼び出しや、モックに設定した値を検証するだけのテストは避けてください。

内部実装ではなく、外部から見た振る舞いをテストしてください。つまり、リファクタリングのたびに変更が必要になるテストは、よいテストではありません。ブラウザーや外部ライブラリではなく、プロジェクトのコードをテストしてください。たとえば、ボタン要素を記述すればブラウザーに表示されるのは明らかです。これはプロジェクトのコードではなく、ブラウザーの振る舞いをテストしています。

必要なテストだけを追加してください。テストでコードが正しく動作することを検証でき、コードが壊れたときにそれを検出できるようにしてください。すでに起きると予想されている結果をテストしても意味がなく、コードが壊れても検出できないテストには価値がありません。通常値、境界値、異常値を入力したときの、コードの外部から観察可能な振る舞いをテストしてください。

テスト目的でエクスポートしない

テスト目的だけで関数、値、その他のデータをエクスポートしてはいけません。テスト以外ではファイルの外部で使用されない要素をテストする場合は、それらをエクスポートして別のテストファイルを作成するのではなく、インソーステストを使用してください。

外部環境をモックしない

データベースや外部サーバーへのアクセスが必要なテストには、モックではなく Testcontainers を使用してください。タイマーが必要な場合は、テストライブラリのフェイクタイマーを使用してください。

コメント