プラグイン
Parcelは、多くのプロジェクトで設定なしですぐに使用できます。しかし、より詳細な制御が必要な場合や、Parcelのデフォルトを拡張またはオーバーライドする必要がある場合は、プロジェクトに.parcelrcファイルを作成することで可能です。
Parcelは非常にモジュール化されるように設計されています。Parcelコア自体は、JavaScriptやWebページの構築に特化したものではなく、すべての動作はプラグインによって指定されます。ビルドの各フェーズには特定のプラグインタイプがあり、ほぼすべてのことをカスタマイズできます。
.parcelrc
#Parcelの構成は、.parcelrcファイルで指定します。これはJSON5で記述され、JSONに似ていますが、コメント、引用符なしのキー、末尾のコンマなどの機能がサポートされています。
構成の拡張
#Parcelのデフォルト構成は、@parcel/config-defaultで指定されています。ほとんどの場合、独自のParcel構成でそれを拡張することになります。これを行うには、.parcelrcのextendsフィールドを使用します。
{
"extends": "@parcel/config-default"
} 配列を渡すことで複数の構成を拡張することもできます。構成は指定された順序でマージされます。
{
"extends": ["@parcel/config-default", "@company/parcel-config"]
} 相対パスを使用して、プロジェクト内の別の構成を参照することもできます。
{
"extends": "../.parcelrc"
} 拡張された構成は、他の構成を拡張することもでき、構成チェーンを形成します。
グロブマップ
#.parcelrcのtransformersやpackagersのような多くのフィールドでは、グロブからプラグイン名へのマップとしてオブジェクトを使用します。これにより、ファイル拡張子、ファイルパス、または特定のファイル名によってParcelの動作を設定できます。グロブは、.parcelrcを含むディレクトリからの相対パスで照合されます。
グロブマップ内のフィールドの順序は、ファイル名がそれらに対してテストされるときの優先順位を定義します。これにより、特定のディレクトリ内のファイルなど、プロジェクト内の特定のファイルに対して異なる動作を構成できます。
{
"transformers": {
"icons/*.svg": ["highest-priority"],
"*.svg": ["lowest-priority"]
}
} ここで、ファイルicons/home.svgの変換を見つけようとしている場合、icons/*.svgに一致するまでグロブを辿っていきます。*.svgには到達しません。
現在の構成のすべてのグロブがチェックされると、Parcelは拡張された構成で定義されたグロブにフォールバックします。
パイプライン
#.parcelrcのtransformers、optimizers、reportersのような多くのフィールドでは、直列に実行されるプラグインの配列を受け入れます。これらはパイプラインと呼ばれます。
低い優先順位のパイプラインをオーバーライドするのではなく、拡張する優先順位の高いパイプラインを定義したい場合は、特別な"..."構文を使用できます。次の優先順位のパイプラインを埋め込むには、パイプライン内にこれを追加します。パイプラインの先頭、末尾、または途中にも挿入でき、パイプラインの拡張方法を完全に制御できます。
{
"transformers": {
"icons/*.svg": ["@company/parcel-transformer-svg-icons", "..."],
"*.svg": ["@parcel/transformer-svg"]
}
} 上記の例では、icons/home.svgを処理するとき、最初に@company/parcel-transformer-svg-iconsを実行し、次に@parcel/transformer-svgを実行します。
これは、拡張された構成にも適用されます。"..."が使用されており、現在の構成に定義されている低い優先順位のパイプラインがない場合、Parcelは拡張された構成で定義されたパイプラインにフォールバックします。
@parcel/transformer-svgはデフォルトの構成に含まれているため、上記の例は次のように書き換えることができます。
{
"extends": "@parcel/config-default",
"transformers": {
"icons/*.svg": ["@company/parcel-transformer-svg-icons", "..."]
}
} 名前付きパイプライン
#グロブベースのパイプラインに加えて、Parcelは名前付きパイプラインをサポートしており、同じファイルを複数の方法でインポートできます。名前付きパイプラインは、通常のパイプラインと同じように.parcelrcで定義されますが、グロブの先頭にURLスキームを含めます。
たとえば、デフォルトでは、画像を通常どおりインポートすると外部ファイルへのURLが返されますが、デフォルトのParcel構成で定義されたdata-url:という名前付きパイプラインを使用して、代わりにデータURLとしてインライン化できます。詳細については、バンドルインライン化を参照してください。
.logo {
background: url(data-url:./logo.png);
} 独自の名前付きパイプラインを定義することもできます。たとえば、ファイルをArrayBufferとしてインポートできるarraybuffer:という名前付きパイプラインを定義できます。この例では*グロブは任意のファイルに一致しますが、より具体的なグロブを使用することもできます。"..."構文は、Parcelがファイルを通常どおり処理してから、parcel-transformer-arraybufferプラグインを実行してArrayBufferに変換できるようにするために使用されます。
{
"extends": "@parcel/config-default",
"transformers": {
"arraybuffer:*": ["...", "parcel-transformer-arraybuffer"]
}
} import buffer from 'arraybuffer:./file.png'; 名前付きパイプラインは、トランスフォーマーとオプティマイザーのパイプラインでサポートされています。トランスフォーマーの場合、パイプラインはアセットを参照した依存関係で指定されます。オプティマイザーの場合、バンドルのエントリアセットから継承されます。
プラグイン
#Parcelは、ビルドの一部として特定のタスクを実行するさまざまな種類のプラグインをサポートしています。プラグインは、NPMパッケージ名を使用して.parcelrcで参照されます。
トランスフォーマー
#トランスフォーマープラグインは、単一のアセットを変換してコンパイルしたり、依存関係を検出したり、別の形式に変換したりします。これらは、.parcelrcのグロブマップを使用して構成されます。パイプラインを使用して同じアセットに対して複数のトランスフォーマーを直列に実行することができ、名前付きパイプラインは、同じプロジェクト内で同じファイルを複数の異なる方法でコンパイルできるようにサポートされています。"..."構文を使用して、ファイルのデフォルトのトランスフォーマーを拡張できます。
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-react"]
}
} アセットをコンパイルすると、そのファイルタイプが変更される場合があります。たとえば、TypeScriptをコンパイルする場合、アセットのタイプはtsまたはtsxからjsに変更されます。これが起こると、Parcelはアセットをさらに処理する方法を再評価し、.jsファイルに一致するパイプラインを通じて実行します。
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
}
} トランスフォーマーがアセットタイプを変更して現在のパイプラインと一致しなくなると、アセットは別のパイプラインに入れられます。新しいアセットタイプに一致するパイプラインがない場合、変換は完了します。現在のパイプラインで後で定義されたトランスフォーマーは実行されません。
リゾルバー
#リゾルバープラグインは、依存関係指定子をトランスフォーマーによって処理される完全なファイルパスに変換する役割を担います。これがどのように機能するかについての詳細は、依存関係解決を参照してください。リゾルバーは、.parcelrcのプラグイン名の配列を使用して構成されます。解決は、結果を返すプラグインの1つに達するまで、プラグインのリストを辿って進みます。
"..."構文を使用して、デフォルトのリゾルバーを拡張できます。これにより、特定の依存関係の解決をオーバーライドできますが、他の依存関係についてはデフォルトにフォールバックできます。一般に、カスタムリゾルバーは、デフォルトのリゾルバーを実行する前に追加することをお勧めします。
{
"extends": "@parcel/config-default",
"resolvers": ["@company/parcel-resolver", "..."]
} "..."を省略した場合、リゾルバーはすべての依存関係を処理できる必要があり、そうでない場合は解決が失敗します。
バンドラー(実験的)
#バンドラープラグインは、アセットをバンドルにグループ化する役割を担います。バンドラーは、.parcelrcにプラグイン名を指定することで構成できます。
{
"extends": "@parcel/config-default",
"bundler": "@company/parcel-bundler"
} 注意: バンドラープラグインは実験的なものであり、マイナーアップデート間でも変更される可能性があります。
ランタイム(実験的)
#ランタイムプラグインを使用すると、アセットをバンドルに挿入できます。これらは、.parcelrcのプラグイン名の配列を使用して構成できます。このリストのすべてのランタイムプラグインは、各バンドルに対して実行されます。"..."構文を使用して、デフォルトのランタイムを拡張できます。
{
"extends": "@parcel/config-default",
"runtimes": ["@company/parcel-runtime", "..."]
} "..."を省略すると、デフォルトのランタイムは実行されません。これは、多くのParcel機能がデフォルトのランタイムに依存しているため、おそらく壊れるでしょう。
注意: ランタイムプラグインは実験的なものであり、マイナーアップデート間でも変更される可能性があります。
ネーマー
#ネーマープラグインは、バンドルの出力ファイル名を決定します。これらは、.parcelrcのプラグイン名の配列を使用して構成されます。名前付けは、結果を返すネーマーの1つに達するまで、ネーマーのリストを辿って進みます。
"..."構文を使用して、デフォルトのネーマーを拡張できます。これにより、特定のバンドルの名前付けをオーバーライドできますが、他のバンドルの場合はデフォルトにフォールバックできます。一般に、カスタムネーマーは、デフォルトのネーマーを実行する前に追加することをお勧めします。
{
"extends": "@parcel/config-default",
"namers": ["@company/parcel-namer", "..."]
} "..."を省略した場合、ネーマーはすべてのバンドルの名前付けを処理できる必要があり、そうでない場合はビルドが失敗します。
パケージャー
#パケージャープラグインは、バンドル内のすべてのアセットを結合して1つの出力ファイルにする役割を担います。これらは、.parcelrcのグロブマップを使用して構成されます。グロブは、バンドルの出力ファイル名に対して照合されます。1つのパケージャープラグインがバンドルごとに実行されるように構成できます。
{
"extends": "@parcel/config-default",
"packagers": {
"*.{jpg,png}": "@company/parcel-packager-image-sprite"
}
} オプティマイザー
#オプティマイザープラグインは、トランスフォーマーと似ていますが、単一のアセットではなくバンドルを受け取ります。これらは.parcelrc内のグロブマップを使用して構成されます。複数のオプティマイザーは、パイプラインを使用して同じバンドルに対して連続して実行できます。また、名前付きパイプラインもサポートされており、同じプロジェクト内で同じバンドルを複数の異なる方法でコンパイルできます。"..."構文を使用して、バンドルのデフォルトのオプティマイザーを拡張できます。
{
"extends": "@parcel/config-default",
"optimizers": {
"*.js": ["@parcel/optimizer-esbuild"]
}
} コンプレッサー
#コンプレッサープラグインは、最終的なバンドルをディスクに書き込む際に使用され、何らかの方法で圧縮またはエンコード(例:Gzip)することができます。これらは.parcelrc内のグロブマップを使用して構成されます。複数のコンプレッサーは、パイプラインを使用して同じバンドルに対して実行できます。各コンプレッサープラグインは、並行して書き込まれる追加のファイルを生成します。たとえば、bundle.js、bundle.js.gz、bundle.js.brなどです。"..."構文を使用して、バンドルのデフォルトのコンプレッサーを拡張できます。
{
"extends": "@parcel/config-default",
"compressors": {
"*.{js,html,css}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
}
} レポーター
#レポータープラグインは、ビルドプロセス全体で発生するParcelからのイベントを受信します。たとえば、レポーターはステータス情報をstdoutに書き込んだり、開発サーバーを実行したり、ビルドの最後にバンドル分析レポートを生成したりできます。レポーターは、.parcelrc内のパッケージ名の配列を使用して構成されます。このリスト内のすべてのレポーターは、各ビルドイベントに対して実行されます。"..."構文を使用して、デフォルトのレポーターを拡張できます。
{
"extends": "@parcel/config-default",
"reporters": ["...", "@parcel/reporter-bundle-analyzer"]
} 頻繁に使用しないレポーターは、CLIで--reporterオプションを使用するか、APIでadditionalReportersオプションを使用して指定することもできます。.parcelrcで指定されたレポーターは常に実行されます。
ローカルプラグイン
#ほとんどのParcelプラグインはNPMパッケージです。つまり、互換性のあるParcelのバージョンと、依存関係を宣言するpackage.jsonを持っています。また、明確にするための命名システムに従う必要があります。
通常、ParcelプラグインはNPMレジストリ、または社内レジストリ(例:Artifactory)に公開されます。これにより、プラグインをコミュニティまたは社内のプロジェクト間で共有し、重複を避けることが推奨されます。
ただし、プラグインを開発する際には、最初に公開せずにプロジェクトで直接実行すると便利な場合があります。これを行うにはいくつかの方法があります。
相対ファイルパス
#プラグインは、使用される.parcelrc設定ファイルからの相対パスとして参照できます。これらは、.mjsまたは.cjs拡張子、または最寄りのpackage.json内の"type": "module"フィールド(Nodeがモジュールをロードする方法と同様)を使用して決定されるCommonJSまたはESMモジュールである場合があります。
{
"extends": "@parcel/config-default",
"transformers": {
"*.js": ["./my-local-plugin.mjs", "..."]
}
} YarnとNPMワークスペース
#ローカルプラグインを使用するもう1つの方法は、Yarn WorkspacesまたはNPM Workspacesを介してモノレポ設定を使用することです。これにより、公開されたパッケージに依存するのと同じ方法で、リポジトリ内の他のパッケージに依存することができます。これを行うには、次のようなプロジェクト構造を設定します
project
├── .parcelrc
├── package.json
└── packages
├── app
│ └── package.json
└── parcel-transformer-foo
├── package.json
└── src
└── FooTransformer.js
ルートのpackage.jsonで、workspacesフィールドを使用してパッケージを参照します。
{
"name": "my-project",
"private": true,
"workspaces": ["packages/*"]
} 次に、.parcelrcで、公開されたパッケージと同じようにparcel-transformer-fooを参照できます。プラグインのコードを更新すると、Parcelはプロジェクトを再構築します。
アプリをpackages/app内ではなく、ルート(例:srcフォルダー内)に保持することもできます。
link:プロトコル
#Yarnは、link:プロトコルを使用して、ローカルディレクトリをパッケージとして参照する依存関係の定義をサポートしています。たとえば、次のようなプロジェクト構造を設定できます
project
├── .parcelrc
├── package.json
├── src
│ └── index.html
└── parcel-transformer-foo
├── package.json
└── src
└── FooTransformer.js
ルートのpackage.jsonで、link:プロトコルを使用してparcel-transformer-fooパッケージへの依存関係を定義できます。
{
"name": "my-project",
"dependencies": {
"parcel": "^2.0.0",
"parcel-transformer-foo": "link:./parcel-transformer-foo"
}
} 次に、.parcelrcで、公開されたパッケージと同じようにparcel-transformer-fooを参照できます。プラグインのコードを更新すると、Parcelはプロジェクトを再構築します。