transformTypes フックの追加で Pro コンポーネントの型解決を改善

shoelace-style/webawesome

Web Awesome Pro の型定義が内部エイリアス $webawesome/ を参照できず、TS コンパイルが失敗していた問題を、transformTypes フックの導入で根本的に解決します。これにより、プロジェクト側での手作業の paths 設定が不要になり、型安全な開発体験が向上します。

背景

Web Awesome Pro の型定義が $webawesome/* エイリアスを解決できず、コンパイルエラーが発生していました。 具体的には WaToastWaFileInput などのコンポーネントを型インポートすると、TS2307: Cannot find module '$webawesome/internal/webawesome-element.js' が出力され、開発が中断されました(#2578、#2557、#2540 参照)。

このエイリアスは npm パッケージ内で内部的に使用されているため、利用者側で tsconfig.json に手動で paths を追加するしかありませんでした。 その結果、プロジェクトごとに同じ設定を繰り返す必要があり、保守コストが増大していました。

tsc-alias を利用してビルド時にエイリアスを相対パスへ変換することで、型解決を自動化する方針が採られました。 この方針を実装するために、ビルドプロセスにフックポイントを設けることが決定されました。

技術的な変更

packages/webawesome/scripts/build.jstransformTypes フックがオプションとして追加されました。 BuildOptions インターフェースに (dir: string) => void 型の transformTypes が定義され、デフォルトは何もしない空関数 (_dir => {}) です。

@@ -46,6 +46,7 @@ if (!process.env.NODE_ENV) {
  * @property {(eventName: "change" | "add" | "unlink", filePath: string) => unknown} [afterWatchEvent]
  * @property {(dir: string) => void} [transformTypes]
  */
@@ -68,6 +69,8 @@ export async function build(options = {}) {
     options.watchedDocsDirectories = [getDocsDir()];
   }

+  const transformTypes = options.transformTypes || (_dir => {});
+
   /**
    * Runs the full build.
    */

tsc のビルド完了後に transformTypes(cdnDir) が呼び出され、生成された CDN ディレクトリを対象に型変換が実行されます。 これにより tsc-alias が生成物に対して走り、$webawesome/ エイリアスが正しい相対パスへ置換されます。

@@ -235,7 +238,9 @@ export async function build(options = {}) {
       if (process.env.ROOT_DIR) {
         process.chdir(process.env.ROOT_DIR);
       }
+      const cdnDir = getCdnDir();
       execSync(`tsc --project ./tsconfig.prod.json --outdir "${getCdnDir()}"`, { stdio: 'inherit' });
+      transformTypes(cdnDir);
       process.chdir(cwd);
     } catch (error) {
       process.chdir(cwd);

custom-elements-manifest.jscomponentTypePath 関数が拡張され、タグ名が無い場合は従来通り ./${modulePath} を返し、タグがある場合は ./components/${unprefixedTag}/${unprefixedTag}.js へリダイレクトします。 これにより CEM が生成する型パスと実際のファイル構成が一致し、型解決に寄与します。

@@ -215,8 +215,12 @@ export default {
       defaultExport: true,
       includeDefaultDOMEvents: true,
-      componentTypePath: (_name, _tag, modulePath) => {
-        return `./${modulePath}`;
+      componentTypePath: (name, tag, modulePath) => {
+        if (!tag) {
+          return `./${modulePath}`;
+        }
+        const unprefixedTag = tag.replace('wa-', '');
+        return `./components/${unprefixedTag}/${unprefixedTag}.js`;
       },

package-lock.jsonpackage.json@wc-toolkit/jsx-types が 1.3.0 から 1.6.0 に更新され、依存関係として @prettier/syncmake-synchronized が新たに導入されました。 これにより型定義の生成が最新ツールチェーンに追随し、ビルド全体の安定性が向上します。

@@ -3203,9 +3203,40 @@
       "license": "MIT"
     },
     "node_modules/@wc-toolkit/jsx-types": {
-      "version": "1.3.0",
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@wc-toolkit/jsx-types/-/jsx-types-1.6.0.tgz",
+      "integrity": "sha512-xx1g8yYw9ZYX5sG47eEVhVcSm3nWfDqrcix0heN9Vu36Fuhmu1baSYCqZIUU+J9n29bfuu4vhSgrGKpLa0f2Fg==",
       "dev": true,
-      "license": "MIT"
+      "license": "MIT",
+      "dependencies": {
+        "@prettier/sync": "^0.6.1"
+      }

src/internal/webawesome-element.ts に JSDoc コメントが追加され、@internal が明示されました。 変更自体はビルドロジックに影響しませんが、公開 API と内部実装の境界がドキュメント上で明確化されました。

@@ -45,6 +45,9 @@ function buildStyleAttribute(options: { property?: string | null; value?: unknow
   return null;
 }

+/**
+ * @internal
+ */
 export default class WebAwesomeElement extends LitElement {
   // One or more CSSResultGroup to include in the component's shadow root. Host styles are automatically prepended.
   static css?: CSSResultGroup;

全体として、ビルドプロセスにフックポイントを導入し、型エイリアスの自動変換と CEM のパス整合性を確保することで、Pro コンポーネントの型解決問題を根本的に解消しました。 変更はデフォルトで何もしないため、既存のビルドフローへの後方互換性も保持されています。

設計判断

フックを build 関数のオプションとして提供することで、ビルド呼び出し側が必要に応じて型変換ロジックを差し込める柔軟性を確保しました。 これは独立したスクリプトを別途管理するよりも、ビルド設定一元化の観点から好まれます。

デフォルト実装を空関数にすることで、フック未指定時の既存ビルド挙動を完全に保護しています。 これにより、transformTypes を利用しないプロジェクトは変更を感知せず、CI の失敗リスクが低減します。

custom-elements-manifest.js のパス生成ロジック変更は、CEM が生成する型ファイルと実際のコンポーネント実装パスを一致させ、型解決エラーの原因であったパスミスマッチを防止します。 この設計は CEM の拡張ポイントを利用した最小限の侵入で実現されています。

まとめ

transformTypes フックの導入により、Web Awesome Pro の $webawesome/ エイリアスが自動的に相対パスへ変換され、型解決エラーが根本的に解消されました。ビルドオプションとして安全に拡張された点と、CEM パス補正による型定義の一貫性向上が、本変更の主たる成果です。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
94fabb5e

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文→背景→技術的な変更→設計判断(任意)→まとめの構成が明確に存在し、各要素が適切に記述されています。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

PR リンクが `[PR #2577](URL)` という形式で記述されており、要件の `[#2577](URL)` 形式と完全には一致していません。ファイル名付きシンタックスハイライトは使用されていませんが必須ではありません。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門的な用語と具体的なコード変更に焦点を当てており、エンジニア向けに適切なレベルです。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論・各論・結論の流れを保ち、段落はトピックセンテンスで始まり適切な長さで区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中の diff ブロックは提供された Diff 内容と一致しており、コードの追加・変更箇所が正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`transformTypes`, `tsc-alias`, `$webawesome/` などの用語は PR 内容と合致し、誤用は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的な説明は Diff と PR の記述に根拠があり、因果関係も論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての主張は PR タイトル・説明・Diff で裏付けられており、外部知識や推測は含まれていません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号、Issue 番号、バージョン番号などの数値は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR の "add transform-types hook" を的確に日本語で表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTS やリリース日程等、PR に記載されていない外部知識は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PR の記述と一致しています。