バンドルのインライン化

Parcel には、コンパイルされた 1 つのバンドルの内容を別のバンドル内にインライン化する幾つかの方法があります。

バンドルをテキストとしてインライン化する

#

bundle-text: スキームを使用すると、バンドルの内容をプレーンテキストとしてインライン化できます。 Parcel は、すべての依存関係のバンドルを含め、解決されたファイルを通常どおりコンパイルし、結果を文字列として親バンドルにインライン化します。

これは多くの方法で使用できます。たとえば、コンパイルされた CSS バンドルをインライン化し、その結果を使用して実行時にスタイルタグを挿入できます。これは、Shadow DOM ルートなど、スタイルタグの挿入場所を制御する必要がある場合に役立ちます。

import cssText from 'bundle-text:./test.css';

// inject <style> tag
let style = document.createElement('style');
style.textContent = cssText;
shadowRoot.appendChild(style);

データ URL としてインライン化する

#

data-url: スキームを使用すると、バンドルをデータ URL としてインライン化できます。解決されたファイルは、すべての依存関係を含めてコンパイルされ、データ URL に変換されます。ファイルがバイナリ形式の場合、Base64 としてエンコードされます。そうでない場合は、URI としてエンコードされます。

これが役立つ例としては、CSS ファイル内に小さな画像をインライン化することが挙げられます。

.foo {
background: url(data-url:./background.png);
}

内部実装

#

bundle-text:data-url: は、名前付きパイプライン を使用したデフォルトの Parcel 設定で実装されています。 @parcel/transformer-inline-string トランスフォーマー プラグインは、コンパイルされたアセットをインラインとしてマークします。これにより、Parcel はバンドルをディスクに書き込まず、親バンドルにインライン化します。データ URL を実装するために、@parcel/optimizer-data-url オプティマイザー プラグインを使用して、コンパイルされたバンドルをデータ URL に変換します。

Parcel 設定では、次のようになります。各パイプラインの "..." は、Parcel にファイルに一致する通常のトランスフォーマーを実行してから、@parcel/transformer-inline-string を実行するように指示します。

@parcel/config-default
{
"transformers": {
"bundle-text:*": ["...", "@parcel/transformer-inline-string"],
"data-url:*": ["...", "@parcel/transformer-inline-string"]
},
"optimizers": {
"data-url:*": ["...", "@parcel/optimizer-data-url"]
}
}

上記のプラグインを再利用したり、カスタムプラグインを作成したりして、独自の 名前付きパイプラインを作成してインライン化をカスタマイズできます。詳細は、Parcel 設定 を参照してください。

役立つ可能性のある別の Parcel プラグインは、@parcel/transformer-inline です。 @parcel/transformer-inline-string と同様に、アセットをインラインとしてマークしますが、結果は文字列としてエンコードされません。これは、インラインバンドルにコードが含まれている場合、文字列をユーザーに返すのではなく、親バンドルで *実行* されることを意味します。これは、バンドルを何らかの方法でラップし、実行時にデコードする必要があるカスタムプラグインがある場合に役立ちます。

たとえば、ファイルを ArrayBuffer またはその他のカスタムエンコーディングとしてインライン化したい場合があります。これは、バンドルの出力を後処理するカスタム オプティマイザープラグインを使用して実装できます。

import {Optimizer} from '@parcel/plugin';
import {blobToBuffer} from '@parcel/utils';

export default new Optimizer({
async optimize({contents}) {
let buffer = await blobToBuffer(contents);
return {
contents: `new Uint8Array(${JSON.stringify(Array.from(buffer))}).buffer`
};
}
});

これで、新しいプラグインを使用して名前付きパイプラインを定義し、コンパイルされたファイルを配列バッファーとしてインポートできます。

カスタムプラグインの作成の詳細については、プラグインシステム ドキュメントを、名前付きパイプラインの詳細については、Parcel 設定 ドキュメントを参照してください。

blob URL としてインライン化する

#

バンドルの内容を blob URL としてインライン化することができます。これは、ブラウザの多くの Web API に渡すことができます。 @parcel/optimizer-blob-url プラグインは、@parcel/transformer-inline と組み合わせて使用することで、これを実現できます。これらの名前付きパイプラインはデフォルトでは含まれていないため、.parcelrc に作成する必要があります。

.parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"blob-url:*": ["...", "@parcel/transformer-inline"]
},
"optimizers": {
"blob-url:*": ["...", "@parcel/optimizer-blob-url"]
}
}

変換せずにインライン化する

#

JavaScript では、Parcel トランスフォーマーを介して実行せずにファイルの内容をインライン化できます。これは、Parcel が静的に分析する fs Node モジュールを使用して行うことができます。これは、さまざまなエンコーディングの文字列として、または Buffer としてインライン化できます。詳細は、Node エミュレーション ドキュメントを参照してください。

import fs from 'fs';

const sourceCode = fs.readFileSync(__dirname + '/foo.js', 'utf8');

上記の例では、sourceCode 変数は、コンパイル *されていない* foo.js の内容、つまりバンドルされた結果ではなく元のソースコードになります。

他のツールとの統合

#

バンドルのインライン化は Parcel 固有の機能であるため、TypeScript や Flow などの他のツールがそれをサポートするように設定する必要があります。これを行う方法の詳細は、依存関係解決ドキュメントの 他のツールの設定 セクションを参照してください。