このページとあなたの好きなAIアシスタントを使ってドキュメントを要約します
バージョン履歴
- "`purge` と `minify` が `@intlayer/swc` を通じて Next.js で動作するようになりました — `babel.config.js` は不要です"v9.2.12026/8/9
- "リファレンス表で Babel プラグインを必要なパイプライン順(extract → purge → minify → optimize)で列挙"v8.12.02026/6/24
- "Babel/Webpack用の `intlayerPurgeBabelPlugin` と `intlayerMinifyBabelPlugin` を追加、プラグインのパイプラインを明確化"v8.12.02026/6/7
- "ビルド設定に `minify` と `purge` オプションを追加"v8.7.02026/4/8
このページのコンテンツはAIを使用して翻訳されました。
英語の元のコンテンツの最新バージョンを見るこのドキュメントを改善するアイデアがある場合は、GitHubでプルリクエストを送信することで自由に貢献してください。
ドキュメントへのGitHubリンクドキュメントのMarkdownをクリップボードにコピー
i18nバンドルサイズとパフォーマンスの最適化
JSONファイルに依存する従来のi18nソリューションで最も一般的な課題の1つは、コンテンツサイズの管理です。開発者が手動でコンテンツを名前空間に分割しない場合、ユーザーは1つのページを表示するためだけに、すべてのページ、さらにすべての言語の翻訳をダウンロードすることになることがよくあります。
たとえば、10言語に翻訳された10ページのアプリケーションの場合、ユーザーは1つ(現在の言語での現在のページ)しか必要としないにもかかわらず、100ページ分のコンテンツをダウンロードすることになります。これは、帯域幅の無駄遣いと読み込み時間の遅延につながります。
Intlayerは、ビルド時の最適化によってこの問題を解決します。 コードを分析して各コンポーネントで実際に使用されている辞書を検出し、必要なコンテンツのみをバンドルに再注入します。
目次
バンドルの分析
バンドルを分析することは、「重い」JSONファイルやコード分割の機会を特定するための第一歩です。これらのツールは、アプリケーションのコンパイル済みコードの視覚的なツリーマップを生成し、どのライブラリが最もスペースを消費しているかを正確に確認できるようにします。
Vite / Rollup
Viteは内部でRollupを使用しています。rollup-plugin-visualizerを使用すると、グラフ内のすべてのモジュールのサイズを示すインタラクティブなHTMLファイルが生成されます。
コードをクリップボードにコピー
コードをクリップボードにコピー
Next.js (Turbopack)
App RouterとTurbopackを使用しているプロジェクトの場合、Next.jsは追加の依存関係を必要としない組み込みの実験的なアナライザーを提供しています。
コードをクリップボードにコピー
Next.js (Webpack)
Next.jsでデフォルトのWebpackバンドラーを使用している場合は、公式のバンドルアナライザーを使用してください。ビルド中に環境変数を設定することでトリガーされます。
コードをクリップボードにコピー
コードをクリップボードにコピー
使用方法:
コードをクリップボードにコピー
標準の Webpack
Create React App (ejected)、Angular、またはカスタムのWebpackセットアップの場合は、業界標準の webpack-bundle-analyzer を使用します。
コードをクリップボードにコピー
コードをクリップボードにコピー
仕組み
Intlayerはコンポーネントごとのアプローチを使用します。グローバルなJSONファイルとは異なり、コンテンツはコンポーネントの横、またはコンポーネント内に定義されます。ビルドプロセス中に、Intlayerは以下を実行します。
- 分析: コードを分析して、
useIntlayerの呼び出しを見つけます。 - 構築: 対応する辞書コンテンツを構築します。
- 置換: 設定に基づいて、
useIntlayerの呼び出しを最適化されたコードに置き換えます。
これにより、以下が保証されます。
- コンポーネントがインポートされていない場合、そのコンテンツはバンドルに含まれません(デッドコードの削除)。
- コンポーネントが遅延読み込みされる場合、そのコンテンツも遅延読み込みされます。
プラグインリファレンス
Intlayerのビルド最適化は、それぞれ単一の責任を持つ複数の個別のプラグインに分割されています。それぞれが何を行うかを理解することで、設定時の混乱を防ぐことができます。
Babel プラグイン (@intlayer/babel)
これらは、Webpackベースのセットアップ(Babelを使用したNext.js、CRA、カスタムWebpackなど)の babel.config.js で直接使用されます。
以下の表は、必要なパイプライン順(babel.config.js に記述しなければならない順序と同じ)で列挙しています:
テーブルをモーダルで開き、すべてのデータを明確に表示
| プラグイン | 役割 |
|---|---|
intlayerExtractBabelPlugin | .content.ts ファイルをスキャンし、コンパイルされた辞書を .intlayer/ に書き込みます |
intlayerPurgeBabelPlugin | すべてのソースファイルをスキャンし、コンパイルされた .intlayer/**/*.json から未使用のフィールドを削除します |
intlayerMinifyBabelPlugin | JSONファイルとソースコードの両方で、コンテンツフィールドキーを短いアルファベットのエイリアス(例:title → a)に名前変更します |
intlayerOptimizeBabelPlugin | useIntlayer('key') を useDictionary(hash) に書き換え、一致する辞書の import を注入します |
プラグインの順序は重要です。babel.config.jsでは、purgeとminifyのプラグインは、optimizeのプラグインの前に記述する必要があります。最適化パスはuseIntlayer('key')を不透明なuseDictionary(hash)呼び出しに置き換えるため、purgeパスとminifyパスが使用されているフィールドを識別するために必要な辞書キー情報が消去されてしまいます。
各Babelプラグインには、設定読み込み時に intlayer.config.ts を1回読み込み、事前解決された値を返す対応するオプションヘルパーがあります。
テーブルをモーダルで開き、すべてのデータを明確に表示
| オプションヘルパー | 一緒に使用するプラグイン |
|---|---|
getExtractPluginOptions() | intlayerExtractBabelPlugin |
getPurgePluginOptions() | intlayerPurgeBabelPlugin |
getMinifyPluginOptions() | intlayerMinifyBabelPlugin |
getOptimizePluginOptions() | intlayerOptimizeBabelPlugin |
Vite プラグイン (vite-intlayer)
Viteユーザーはこれらを直接設定することはありません。これらは、vite.config.ts で withIntlayer() を呼び出したときに自動的に設定されます。intlayer.config.ts の build.purge および build.minify フラグは、追加のプラグイン登録なしに対応する動作を切り替えます。
テーブルをモーダルで開き、すべてのデータを明確に表示
| 内部の Vite プラグイン | 同等の動作 |
|---|---|
| Usage analyzer | intlayerPurgeBabelPlugin の分析パスと同じ |
| Dictionary prune | intlayerPurgeBabelPlugin のJSON書き込みパスと同じ |
| Dictionary minify | intlayerMinifyBabelPlugin のJSON書き込みパスと同じ |
| Babel transform | intlayerMinifyBabelPlugin のソースコード名変更 + intlayerOptimizeBabelPlugin と同じ |
SWC プラグイン (@intlayer/swc)
Next.js ユーザーもこれらを直接設定することはありません。v9.2.1 以降、next.config.ts の withIntlayer() が build.purge と build.minify フラグだけを元に、パージ・ミニファイ・インポート書き換えというパイプライン全体を実行します。
SWC の Wasm プラグインは一度に 1 ファイルしか変換できず、ファイルシステムにアクセスできないため、処理は 2 つに分かれています:
テーブルをモーダルで開き、すべてのデータを明確に表示
| パス | 実行場所 | 処理内容 |
|---|---|---|
| 使用状況の解析 + JSON のパージ/ミニファイ | Node、withIntlayer() の内部 | すべてのコンポーネントのソースファイルを読み取り、.intlayer/**/*.json を書き換え、リネームテーブルを生成します |
ソースの書き換え (content.title → .a) | @intlayer/swc (Wasm) | リネームテーブルをコード内の該当するプロパティアクセスに適用します |
インポートの書き換え (useIntlayer → dict) | @intlayer/swc (Wasm) | intlayerOptimizeBabelPlugin と同じ |
どの フィールドが未使用か、そして各フィールドが どの エイリアスを受け取るかを決定するには、ファイル横断の状態とファイル I/O が必要です。そのためこの半分は Node 上で実行され、SWC プラグインは生成されたテーブルだけを受け取ります。
プラットフォーム別の設定
Next.js
Next.js はビルドに SWC を使用するため、@intlayer/swc プラグインが必要です。v9.2.1 以降、このパッケージ 1 つでパイプライン全体 — 最適化(インポート書き換え)、パージ、ミニファイ — をカバーします。
SWCプラグインはNext.jsではまだ実験的であるため、このプラグインはデフォルトではインストールされません。将来的に変更される可能性があります。
Next.js 16.1.0 が最小バージョンです。 SWC の前方互換な Wasm プラグイン ABI 上に構築された最初のリリースであり、それ以前のリリースはプラグインを拒否します。withIntlayer はプロジェクトの Next.js バージョンを読み取り、16.1.0 未満ではプラグインを登録しません — それらのビルドは引き続き成功し、単にバンドル最適化なしで実行されます。
コードをクリップボードにコピー
コードをクリップボードにコピー
インストールされると、Intlayerはプラグインを自動的に検出して使用します。
パージとミニファイのパス(フィールドの削除とリネーム)には、追加パッケージも babel.config.js も不要です。設定を withIntlayer でラップし、intlayer.config.ts でフラグを有効にしてください:
コードをクリップボードにコピー
コードをクリップボードにコピー
next build の実行中、withIntlayer はソースを解析し、コンパイル済み辞書を書き換え、生成されたフィールドのリネームテーブルを @intlayer/swc に渡します。プラグインはコード内の該当するプロパティアクセスを更新します。
withIntlayerSyncではなく、非同期のwithIntlayerを使用してください。同期版は解析パイプラインを実行しないため、パージとミニファイは効果がありません。
パージとミニファイはnext build時にのみ実行されます — 最適化パイプラインはnext dev中は無効です。
互換アダプターの呼び出し元が設定されている場合(swcExtraCallers。@intlayer/next-intlや@intlayer/react-i18nextなどの互換パッケージが設定します)も無効になります。これらの呼び出し箇所は使用状況アナライザーから見えないため、パージするとコードがまだ読んでいるフィールドを削除してしまいます。インポートの書き換えは有効なままです。
それ以前のバージョン(9.2.1 より前) では @intlayer/babel と、intlayerPurgeBabelPlugin および intlayerMinifyBabelPlugin を宣言する babel.config.js が必要でした。このファイルはもう不要で、削除できます。
Vite
Viteは @intlayer/babel プラグインを使用し、これは vite-intlayer の依存関係として含まれています。インポートの書き換え、パージ、ミニファイの完全な最適化パイプラインはデフォルトで有効になっており、追加のプラグイン登録は必要ありません。
intlayer.config.ts で対応するフラグを設定して、パージとミニファイを有効にします。
コードをクリップボードにコピー
Webpack (および Babel を使用した Next.js)
@intlayer/babel をインストールします。
コードをクリップボードにコピー
正しい順序で4つすべてのプラグインを babel.config.js に追加します。
コードをクリップボードにコピー
設定
intlayer.config.ts の build プロパティを介して、Intlayerがバンドルを最適化する方法を制御できます。
コードをクリップボードにコピー
ほとんどの場合、optimizeにはデフォルト値(undefined)を保持することをお勧めします。
すべてのオプションについては、設定リファレンスを参照してください:設定
ビルドオプション
テーブルをモーダルで開き、すべてのデータを明確に表示
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
optimize | boolean / undefined | undefined | インポートの書き換えパスを有効にします。undefined = 本番ビルドでのみアクティブになります。false の場合、purgeとminifyも無効になります。 |
minify | boolean | false | コンパイルされたJSONファイル内のコンテンツフィールドキーを短いアルファベットのエイリアスに名前変更します。ソースコード内の対応するプロパティアクセスも書き換えます。optimize が false の場合は効果がありません。 |
purge | boolean | false | コンパイルされたJSONファイルから、ソースコードで静的にアクセスされないコンテンツフィールドを削除します。optimize が false の場合は効果がありません。 |
最小化(Minification - フィールドキーの名前変更)
build.minify はJavaScriptバンドルを最小化しません。それはバンドラーが処理します。代わりに、ユーザー定義の各コンテンツフィールドキーを短いアルファベットのエイリアスに置き換えることで、コンパイルされた辞書のJSONファイルを縮小します。
コードをクリップボードにコピー
ソースコード内のすべてのプロパティアクセスにも同じ名前の変更が適用されるため、コンパイルされた出力では content.title が content.a になります。実行時の動作は同じです。
コードをクリップボードにコピー
optimizeがfalseの場合、最小化はスキップされます。editor.enabledがtrueの場合でも実行されますが、フィールドのリネーム処理は行われません — ビジュアルエディタはkeyPathで編集内容を解決するため、元のフィールド名を維持する必要があります。
Next.js では、@intlayer/swc がインストールされていない、または読み込めない場合(16.1.0 未満の Next.js)にもミニファイはスキップされます。ソース側のアクセスを書き換えるのはこのプラグインなので、これなしで辞書をリネームすると、コードが存在しないフィールド名を読むことになります。
importMode: 'fetch' 経由で読み込まれた辞書の場合も最小化はスキップされます。これは、そのJSONが元のフィールド名を使用してリモートAPIから提供されるためであり、クライアント側のキーの名前を変更するとサーバー/クライアントの規約が壊れるためです。
パージ(Purging - 未使用フィールドの削除)
build.purge は、ソースコード内で実際にアクセスされているコンテンツフィールドを分析し、コンパイルされたJSONファイルから他のすべてのフィールドを削除します。
コードをクリップボードにコピー
例: 5つのフィールドがあり、そのうち2つだけが使用されている辞書:
コードをクリップボードにコピー
optimizeがfalseの場合、パージはスキップされます。editor.enabledがtrueの場合でも有効なままです — パージされたフィールドはどのコンポーネントからも読み取られないため、エディタがそれを描画することはありません。Next.js では、さらに@intlayer/swcが利用できない場合、および互換アダプターの呼び出し元が設定されている場合にもスキップされます。
ソースファイルが解析できない場合、または useIntlayer の結果が変数に割り当てられ、静的アナライザーが追跡できない方法(例:オブジェクトへのスプレッド、分割代入せずにプロップとして渡すなど)で渡された場合も、パージは保守的にスキップされます。このような場合は、完全な辞書が保持されます。
インポートモード
複数のページとロケールを含む大規模なアプリケーションの場合、JSONはバンドルサイズの大部分を占める可能性があります。Intlayerでは、importMode オプションを使用して辞書の読み込み方法を制御できます。
グローバル定義
インポートモードは、intlayer.config.ts ファイルでグローバルに定義できます。
コードをクリップボードにコピー
辞書ごとの定義
個々の辞書のインポートモードを、その .content.{{ts|tsx|js|jsx|mjs|cjs|json|jsonc|json5|md|mdx|yaml|yml}} ファイルで上書きすることができます。
コードをクリップボードにコピー
テーブルをモーダルで開き、すべてのデータを明確に表示
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
importMode | 'static', 'dynamic', 'fetch' | 'static' | 非推奨: 代わりに dictionary.importMode を使用してください。辞書の読み込み方法を決定します(以下を参照)。 |
importMode 設定は、辞書のコンテンツをコンポーネントに注入する方法を決定します。これを intlayer.config.ts の dictionary オブジェクトでグローバルに定義するか、辞書ごとの .content.ts ファイルで上書きすることができます。
1. 静的モード (default)
静的モードでは、Intlayerは useIntlayer を useDictionary に置き換え、辞書をJavaScriptバンドルに直接注入します。
- メリット: 即時レンダリング(同期)、ハイドレーション時の追加のネットワークリクエストなし。
- デメリット: バンドルには、その特定のコンポーネントで利用可能なすべての言語の翻訳が含まれます。
- 最適なケース: シングルページアプリケーション(SPA)。
変換されたコードの例:
コードをクリップボードにコピー
2. 動的モード
動的モードでは、Intlayerは useIntlayer を useDictionaryAsync に置き換えます。これにより、import()(Suspenseのようなメカニズム)を使用して、現在のロケールのJSONを特別に遅延読み込みします。
- メリット: ロケールレベルでのツリーシェイキング。 英語バージョンを表示しているユーザーは、英語の辞書のみをダウンロードします。日本語の辞書は読み込まれません。
- デメリット: ハイドレーション中にコンポーネントごとにネットワークリクエスト(アセットの取得)をトリガーします。
- 最適なケース: バンドルサイズが重要な大規模なテキストブロック、記事、または多くの言語をサポートするアプリケーション。
変換されたコードの例:
コードをクリップボードにコピー
importMode: 'dynamic'を使用する場合、1つのページにuseIntlayerを使用するコンポーネントが100個あると、ブラウザは100回の個別のフェッチを試みます。このリクエストの「ウォーターフォール」を避けるために、アトムコンポーネントごとに1つではなく、より少ない数の.contentファイル(例:ページのセクションごとに1つの辞書)にコンテンツをグループ化してください。同じキーを使用する複数の.contentファイルを使用することもできます。Intlayerはそれらを1つの辞書に統合します。
3. Fetchモード
動的モードと同様に動作しますが、最初に Intlayer Live Sync API から辞書を取得しようとします。API呼び出しが失敗した場合、またはコンテンツがライブ更新の対象としてマークされていない場合は、動的インポートにフォールバックします。
変換されたコードの例:
コードをクリップボードにコピー
詳細については、CMSのドキュメントを参照してください:CMS
fetchモードでは、JSONが元のフィールド名を使用してリモートAPIから提供されるため、purgeとminifyは適用されません。
要約: 静的 vs 動的
テーブルをモーダルで開き、すべてのデータを明確に表示
| 機能 | 静的モード | 動的モード |
|---|---|---|
| JSバンドルサイズ | より大きい(コンポーネントの全言語が含まれる) | 最小(コードのみ、コンテンツなし) |
| 初期読み込み | 即時(コンテンツはバンドル内) | わずかな遅延(JSONを取得) |
| ネットワークリクエスト | 追加のリクエストなし | 辞書キーごとに1つのリクエスト |
| ツリーシェイキング | コンポーネントレベル | コンポーネントレベル + ロケールレベル |
| 最適なユースケース | UIコンポーネント、小規模アプリ | テキストが多いページ、多言語 |
