SSR 用のコンポーネント集約エンドポイントを追加
Web Awesome に dist/ssr/all.js エンドポイントが新たに導入され、サーバーサイドでのコンポーネント一括インポートが容易になりました。
背景
サーバーサイドレンダリング(SSR)において、個別コンポーネントを逐次インポートする手間とバンドルサイズの増大が課題でした。既存のクライアント向けエクスポートは軽量化が目的で、サーバ側で全部を読み込むケースを想定していませんでした。今回の PR では、SSR 用に /ssr プレフィックスでエンドポイントを明示し、サーバー側のみが利用すべきことを文書化しています。これにより、開発者はクライアントとサーバーでインポート戦略を明確に分離できます。
技術的な変更
packages/webawesome/scripts/build.js に generateAllComponentFile ステップが追加され、ビルドフローの steps 配列に組み込まれました。ステップは cleanup、generateManifest、generateAllComponentFile、generateReactWrappers…と続き、SKIP_SLOW_STEPS 環境変数でスキップ可能です。スピナーで進行状況を表示し、スキップ時には情報メッセージを出す実装となっています。
@@
- const steps = [cleanup, generateManifest, generateReactWrappers, generateTypes, generateStyles];
+ const steps = [
+ cleanup,
+ generateManifest,
+ generateAllComponentFile,
+ generateReactWrappers,
+ generateTypes,
+ generateStyles,
+ ];
generateAllComponentFile 関数 は新規に導入された make-all.js を呼び出し、ssr/all.js(実際は TypeScript の all.ts)を生成します。関数内部では process.env.SKIP_SLOW_STEPS による早期リターンと、execSync で make-all.js --outdir を実行するロジックが実装されています。
function generateAllComponentFile() {
if (process.env.SKIP_SLOW_STEPS === 'true') {
spinner.info('Skipping "ssr/all.js" file generation.');
return Promise.resolve();
}
spinner.start('Generating "ssr/all.js" file');
try {
execSync(`node ${join(__dirname, 'make-all.js')} --outdir "${getCdnDir()}"`, { stdio: 'inherit' });
} catch (error) {
// error handling omitted for brevity
}
}
packages/webawesome/scripts/make-all.js は新規追加されたスクリプトで、custom-elements.json から全コンポーネントメタデータを取得し、src/ssr/all.ts にエクスポート文を自動生成します。生成前に既存ファイルを削除し、prettier でフォーマットした上で書き出すことで、コード整形と一貫性を保ちます。
const allFile = path.join(process.env.ROOT_DIR || '.', 'src', 'ssr', 'all.ts');
deleteSync(allFile);
const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.json'), 'utf8'));
const components = getAllComponents(metadata);
const index = [];
components.sort((a, b) => a.tagName.localeCompare(b.tagName));
for (const component of components) {
if (!component.tagName) continue;
const tagWithoutPrefix = component.tagName.replace(/^wa-/, '');
index.push(`export { default as ${component.name} } from '../components/${tagWithoutPrefix}/${tagWithoutPrefix}.js';`);
}
let text = `// This file is auto-generated. Do not edit it directly.\n` + index.join('\n');
text = await prettier.format(text, { ...prettierConfig, parser: 'babel-ts' });
fs.writeFileSync(allFile, text, 'utf8');
packages/webawesome/src/ssr/all.ts は自動生成されたファイルで、各コンポーネントを名前付きエクスポートとしてまとめています。例として WaButton や WaAccordion などが列挙され、サーバー側で import * as Wa from 'dist/ssr/all.js' のように一括取得できます。ファイル冒頭に自動生成コメントが入っており、手動編集は推奨されません。
// This file is auto-generated. Do not edit it directly.
export { default as WaAccordionItem } from '../components/accordion-item/accordion-item.js';
export { default as WaButton } from '../components/button/button.js';
export { default as WaCard } from '../components/card/card.js';
// ...(以下同様に全コンポーネントがエクスポートされる)
packages/webawesome/docs/docs/resources/changelog.md には、dist/ssr/all.js エンドポイントが追加された旨が追記され、エンドポイントがサーバー向けであることが明示されています。この変更はドキュメントにも反映され、利用者が新機能をすぐに把握できるようになっています。
設計判断
SSR 用エンドポイントを /ssr に限定した設計は、クライアントバンドルへの負荷増大を防ぎつつ、サーバー側でのコンポーネント一括取得をシンプルにする意図が読み取れます。ビルドプロセスにスキップ可能なステップを導入し、CI 環境でのビルド時間を最適化できる点も設計上の配慮です。既存のクライアント向けエクスポート構造を変更せず、generateAllComponentFile のみを追加したことで後方互換性を保ちつつ新機能を提供しています。
まとめ
dist/ssr/all.js エンドポイントの追加により、Web Awesome の SSR 連携が格段に簡便化されました。ビルドスクリプトの拡張、メタデータ駆動の自動生成スクリプト、そしてドキュメントへの記載という三位一体の改修により、開発者はサーバー側で必要なコンポーネントを一括インポートでき、クライアントバンドルへの影響を回避できます。