HtmlRspackPlugin
Rspack 専用
rspack.HtmlRspackPlugin
はRustで実装された高性能なHTMLプラグインです。RspackプロジェクトでHTMLファイルを生成するために使用できます。
new rspack.HtmlRspackPlugin(options);
比較
rspack.HtmlRspackPlugin
を使用する前に、rspack.HtmlRspackPlugin
とコミュニティのhtml-webpack-pluginとの間にいくつかの違いがあることに注意してください。
パフォーマンス
rspack.HtmlRspackPlugin
はRustで実装されているため、特に多くのHTMLファイルをビルドするシナリオでは、html-webpack-pluginよりもビルドパフォーマンスが大幅に向上します。
機能
rspack.HtmlRspackPlugin
の機能はhtml-webpack-plugin
のサブセットです。プラグインのパフォーマンスを確保するために、html-webpack-pluginが提供するすべての機能を実装していません。
オプションがニーズを満たしていない場合は、コミュニティのhtml-webpack-pluginを直接使用することもできます。
警告
rspack.HtmlRspackPlugin
は完全なejs
構文をサポートしていません。ejs
構文のサブセットのみをサポートしています。完全なejs
構文のサポートが必要な場合は、html-webpack-plugin
を直接使用してください。html-webpack-plugin
のデフォルトのテンプレート構文に合わせるため、RspackはデフォルトのEJSのエスケープとエスケープ解除をhtml-webpack-plugin
のデフォルト構文と同じに変更しました。
サポートされるEJS構文
次の基本的な補間式と一部の制御文のみがサポートされています。ここで、補間式は最も基本的な文字列型のみをサポートし、任意のJavaScript式はサポートしていません。その他のEJS構文は現在サポートされていません。
<%-: エスケープされた出力
補間内のコンテンツをエスケープします
ejs
<p>Hello, <%- name %>.</p>
<p>Hello, <%- 'the Most Honorable ' + name %>.</p>
html
<p>Hello, Rspack<y>.</p>
<p>Hello, the Most Honorable Rspack<y>.</p>
<%=: エスケープされていない出力
補間内のコンテンツをエスケープしません
ejs
<p>Hello, <%- myHtml %>.</p>
<p>Hello, <%= myHtml %>.</p>
<p>Hello, <%- myMaliciousHtml %>.</p>
<p>Hello, <%= myMaliciousHtml %>.</p>
locals
{
"myHtml": "<strong>Rspack</strong>",
"myMaliciousHtml": "</p><script>document.write()</script><p>"
}
html
<p>Hello, <strong>Rspack</strong>.</p>
<p>Hello, <strong>Rspack</strong>.</p>
<p>Hello, </p><script>document.write()</script><p>.</p>
<p>Hello,</p>
<script>
document.write();
</script>
<p>.</p>
制御文
for in
文を使用してリストのトラバースを実装し、if
文を使用して条件付き判定を実装します
ejs
<% for tag in htmlRspackPlugin.tags.headTags { %>
<% if tag.tagName=="script" { %>
<%= toHtml(tag) %>
<% } %>
<% } %>
使用方法
このプラグインは、<script>
タグを使用してすべてのJS出力をheadに含むHTMLファイルを生成します。
プラグインをRspackの設定に追加するだけです。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [new rspack.HtmlRspackPlugin()],
};
これにより、以下を含むdist/index.html
ファイルが生成されます。
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>rspack</title>
<script src="main.js" defer></script>
</head>
<body></body>
</html>
Rspackの設定に複数のエントリポイントがある場合、それらはすべて生成されたHTMLの<script>
タグに含まれます。
ビルド出力にCSSアセットがある場合、それらはHTML headの<link>
タグに含まれます。
オプション
いくつかの設定オプションをrspack.HtmlRspackPlugin
に渡すことができます。許可されるオプションは以下のとおりです。
type HtmlRspackPluginOptions = {
title?: string;
filename?: string | ((entry: string) => string);
template?: string;
templateContent?: string | ((params: Record<string, any>) => string | Promise<string>);
templateParameters?: Record<string, string> | (oldParams: params: Record<string, any>) => Record<string, any> | Promise<Record<string, any>>;
inject?: 'head' | 'body' | boolean;
publicPath?: string;
base?: string | {
href?: string;
target?: '_self' | '_blank' | '_parent' | '_top'
};
scriptLoading?: 'blocking' | 'defer' | 'module' | 'systemjs-module';
chunks?: string[];
excludeChunks?: string[];
sri?: 'sha256' | 'sha384' | 'sha512';
minify?: boolean;
favicon?: string;
meta?: Record<string, string | Record<string, string>>;
hash?: boolean;
};
名前 | 型 | デフォルト | 説明 |
---|
title | string|undefined | undefined | 生成されたHTMLドキュメントに使用するタイトル。 |
filename | string|undefined|((entry: string) => string) | 'index.html' | HTMLを書き込むファイル。デフォルトはindex.html です。ここではサブディレクトリも指定できます(例:pages/index.html)。 |
template | string|undefined | undefined | テンプレートファイルパス |
templateContent | string|undefined|((params: Record<string, any>) => string | Promise<string>) | undefined | テンプレートファイルの内容。templateよりも優先順位が高いです。関数を用いる場合、テンプレートパラメータを渡し、返された文字列をテンプレートの内容として使用します。 |
templateParameters | Record<string, string>|(oldParams: params: Record<string, any>) => Record<string, any> | Promise<Record<string, any>> | {} | テンプレートで使用されるパラメータを上書きできます。関数を用いる場合、元のテンプレートパラメータを渡し、返されたオブジェクトを最終的なテンプレートパラメータとして使用します。 |
inject | 'head' | 'body' | boolean | undefined | undefined | template におけるscriptタグとlinkタグの挿入位置。falseを指定すると挿入されません。指定しない場合、scriptLoading に基づいて自動的に決定されます。 |
publicPath | string | '' | scriptタグとlinkタグで使用されるpublicPath。 |
scriptLoading | 'blocking'|'defer'|'module'|'systemjs-module'|undefined | 'defer' | 最新のブラウザは非ブロッキングJavaScript読み込み('defer')をサポートしており、ページの起動パフォーマンスを向上させます。'module'に設定すると、属性type='module'が追加されます。これは、モジュールは自動的に遅延されるため、'defer'も意味します。 |
chunks | string[]|undefined | undefined | 一部のチャンクのみを追加できます。 |
excludeChunks | string[]|undefined | undefined | 一部のチャンクをスキップできます。 |
sri | 'sha256'|'sha384'|'sha512'|undefined | undefined | sriハッシュアルゴリズム。デフォルトで無効。 |
minify | boolean | false | 出力を縮小するかどうかを制御します。 |
favicon | string|undefined | undefined | 指定されたfaviconパスを出力HTMLに追加します。 |
meta | Record<string, string|Record<string, string>> | {} | メタタグを挿入できます。 |
hash | boolean | false | trueの場合、含まれるすべてのスクリプトとCSSファイルに一意のrspackコンパイルハッシュを追加します。これはキャッシュバストに役立ちます。 |
base | string|object|undefined | undefined | baseタグを挿入します。 |
例
カスタムHTMLテンプレート
デフォルトで生成されたHTMLがニーズを満たしていない場合は、独自のテンプレートを使用できます。
テンプレートファイルを使用する
最も簡単な方法は、templateオプションを使用してカスタムHTMLファイルを渡すことです。rspack.HtmlRspackPlugin
は、必要なすべてのJS、CSS、faviconファイルをHTMLに自動的に挿入します。
template
を使用してHTMLテンプレートファイルを指定します。
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title><%= htmlRspackPlugin.options.title %></title>
</head>
<body></body>
</html>
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new rspack.HtmlRspackPlugin({
template: 'index.html',
}),
],
};
テンプレート文字列を使用する
templateContent
を使用してHTMLテンプレートの内容を指定します。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new rspack.HtmlRspackPlugin({
title: "My HTML Template"
templateContent: `
<!DOCTYPE html>
<html>
<head>
<title><%= htmlRspackPlugin.options.title %></title>
</head>
<body></body>
</html>
`,
}),
],
};
テンプレート関数を使用する
関数を使用してHTMLテンプレートの内容を生成します。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new rspack.HtmlRspackPlugin({
title: "My HTML Template"
templateContent: ({ htmlRspackPlugin }) => `
<!DOCTYPE html>
<html>
<head>
<title>${htmlRspackPlugin.options.title}</title>
</head>
<body></body>
</html>
`,
}),
],
};
- または、
template
に.js
または.cjs
で終わるファイルパスを渡します。
template.js
module.exports = ({ htmlRspackPlugin }) => `
<!DOCTYPE html>
<html>
<head>
<title>${htmlRspackPlugin.options.title}</title>
</head>
<body></body>
</html>
`;
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new rspack.HtmlRspackPlugin({
title: "My HTML Template"
template: "template.js",
}),
],
};
テンプレートパラメータ
templateParameters
を使用してHTMLテンプレートレンダリングパラメータを拡張できます。デフォルトで次の変数が使用できます。
htmlRspackPlugin
: プラグインのデータ
htmlRspackPlugin.options
: プラグインの設定オブジェクト
htmlRspackPlugin.tags
: テンプレートへの挿入用に準備されたタグ情報
htmlRspackPlugin.tags.headTags
: <head>
への挿入のための<base>
、<meta>
、<link>
、<script>
タグのリスト
htmlRspackPlugin.tags.bodyTags
: <body>
への挿入のための<script>
タグのリスト
htmlRspackPlugin.files
: このコンパイルで生成されたアセットファイル
htmlRspackPlugin.files.js
: このコンパイルで生成されたJSアセットのパス一覧
htmlRspackPlugin.files.css
: このコンパイルで生成されたCSSアセットのパス一覧
htmlRspackPlugin.files.favicon
: favicon
が設定されている場合、計算された最終的なfaviconアセットパスがここにあります。
htmlRspackPlugin.files.publicPath
: アセットファイルのpublicPath
rspackConfig
: このコンパイルで使用されたRspack設定オブジェクト
compilation
: このコンパイルのCompilationオブジェクト
警告
テンプレートレンダリング中にタグを挿入するためにhtmlRspackPlugin.tags
を使用する場合は、inject
をfalse
に設定してください。設定しないと、タグが2回挿入されます。
相違点
HtmlWebpackPluginとのいくつかの違いがあります。
!
を使用してローダーを追加してテンプレートファイルを処理することはサポートされていません。
rspackConfig
オブジェクトは現在、mode
、output.publicPath
、output.crossOriginLoading
のみサポートしています。
compilation
オブジェクトは、現在テンプレート関数を使用する場合のみサポートされています。
- テンプレート内でタグリスト(例:
htmlRspackPlugin.tags.headTags
)または単一のタグ(例:htmlRspackPlugin.tags.headTags[0]
)をレンダリングする場合は、HTMLコードを生成するためにtoHtml()
関数が必要です。
チャンクのフィルタリング
挿入する必要があるチャンクは、次の設定で指定できます。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new HtmlRspackPlugin({
chunks: ['app'],
}),
],
};
特定のチャンクは、次の設定で除外することもできます。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new HtmlRspackPlugin({
excludeChunks: ['app'],
}),
],
};
メタタグ
meta
が設定されている場合、HtmlRspackPluginは<meta>
タグを挿入します。
利用可能なほぼすべてのメタタグの、よく管理されたリストをご覧ください。
次の設定でキーバリューペアを追加して<meta>
タグを生成します。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
plugins: [
new HtmlRspackPlugin({
meta: {
// Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no',
// Will generate: <meta name="theme-color" content="#4285f4">
'theme-color': '#4285f4',
// Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
'Content-Security-Policy': {
'http-equiv': 'Content-Security-Policy',
content: 'default-src https:',
},
},
}),
],
};
ベースタグ
base
が設定されている場合、HtmlRspackPluginは<base>
タグを挿入します。
<base>
タグの詳細については、ドキュメントを参照してください。
<base>
タグは、次の設定で生成できます。
rspack.config.js
new HtmlWebpackPlugin({
// Will generate: <base href="http://example.com/some/page.html">
base: 'http://example.com/some/page.html',
});
new HtmlWebpackPlugin({
// Will generate: <base href="http://example.com/some/page.html" target="_blank">
base: {
href: 'http://example.com/some/page.html',
target: '_blank',
},
});
複数のHTMLファイルの生成
複数のエントリーポイントがあり、各エントリーごとにHTMLファイルを生成する場合は、複数のrspack.HtmlRspackPlugin
を登録できます。
filename
を使用して、各HTMLファイルの名前を指定します。
chunks
を使用して、各HTMLファイルに含めるJSバンドルを指定します。
たとえば、次の設定ではfoo.htmlとbar.htmlが生成され、foo.htmlにはfoo.jsによって生成されたJSバンドルのみが含まれます。
rspack.config.js
const rspack = require('@rspack/core');
module.exports = {
entry: {
foo: './foo.js',
bar: './bar.js',
},
plugins: [
new rspack.HtmlRspackPlugin({
filename: 'foo.html',
chunks: ['foo'],
}),
new rspack.HtmlRspackPlugin({
filename: 'bar.html',
chunks: ['bar'],
}),
],
};
フック
HtmlRspackPluginは、タグや生成されたHTMLコードを変更できるいくつかのフックを提供します。フックオブジェクトは、HtmlRspackPlugin.getCompilationHooks
から取得できます。
rspack.config.js
const HtmlModifyPlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('HtmlModifyPlugin', compilation => {
const hooks = HtmlRspackPlugin.getCompilationHooks(compilation);
// hooks.beforeAssetTagGeneration.tapPromise()
// hooks.alterAssetTags.tapPromise()
// hooks.alterAssetTagGroups.tapPromise()
// hooks.afterTemplateExecution.tapPromise()
// hooks.beforeEmit.tapPromise()
// hooks.afterEmit.tapPromise()
});
},
};
module.exports = {
//...
plugins: [new HtmlRspackPlugin(), HtmlModifyPlugin],
};
beforeAssetTagGeneration
このフックは、コンパイルからアセットを収集してロードパスを生成した後、タグを生成する前に呼び出されます。
ここでassets
を変更して、カスタムJSおよびCSSアセットファイルを追加できます。
- 型:
AsyncSeriesWaterfallHook<[BeforeAssetTagGenerationData]>
- パラメータ:
type BeforeAssetTagGenerationData = {
assets: {
publicPath: string;
js: Array<string>;
css: Array<string>;
favicon?: string;
};
outputName: string;
plugin: {
options: HtmlRspackPluginOptions;
};
};
警告
assets.js
、assets.css
、assets.favicon
のみ変更できます。他の項目の変更は有効になりません。
次のコードは、追加のextra-script.js
を追加し、最終的なhtmlコンテンツに<script defer src="extra-script.js"></script>
タグを生成します。
rspack.config.js
const AddScriptPlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('AddScriptPlugin', compilation => {
HtmlRspackPlugin.getCompilationHooks(
compilation,
).beforeAssetTagGeneration.tapPromise('AddScriptPlugin', async data => {
data.assets.js.push('extra-script.js');
});
});
},
};
module.exports = {
//...
plugins: [new HtmlRspackPlugin(), AddScriptPlugin],
};
alterAssetTags
このフックは、アセットファイルに基づいてアセットタグを生成した後、タグの挿入位置を決定する前に呼び出されます。
ここでタグを調整できます。
警告
assetTags
のみ変更できます。他の項目の変更は有効になりません。
- 属性値を
true
に設定すると、値のない属性が追加され、<script defer specialattribute src="main.js"></script>
が生成されます。
- 属性値を
string
に設定すると、値のある属性が追加され、<script defer specialattribute="some value" src="main.js"></script>
が生成されます。
- 属性値を
false
に設定すると、属性が削除されます。
次のコードは、すべてのscript
タイプのタグにspecialAttribute
プロパティを追加します。
rspack.config.js
const AddAttributePlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('AddAttributePlugin', compilation => {
HtmlRspackPlugin.getCompilationHooks(
compilation,
).alterAssetTags.tapPromise('AddAttributePlugin', async data => {
data.assetTags.scripts = data.assetTags.scripts.map(tag => {
if (tag.tagName === 'script') {
tag.attributes.specialAttribute = true;
}
return tag;
});
});
});
},
};
module.exports = {
//...
plugins: [new HtmlRspackPlugin(), AddAttributePlugin],
};
alterAssetTagGroups
このフックは、head
とbody
のタググループを生成した後、テンプレートが関数またはテンプレートエンジンによってレンダリングされる前に呼び出されます。
ここでタグの挿入位置を調整できます。
- 型:
AsyncSeriesWaterfallHook<[AlterAssetTagGroupsData]>
- パラメータ:
type AlterAssetTagGroupsData = {
headTags: Array<HtmlTag>;
bodyTags: Array<HtmlTag>;
outputName: string;
plugin: {
options: HtmlRspackPluginOptions;
};
};
警告
headTags
とbodyTags
のみ変更できます。他の項目の変更は有効になりません。
次のコードは、async
script
タグをbody
からhead
に移動します。
rspack.config.js
const MoveTagsPlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('MoveTagsPlugin', compilation => {
HtmlWebpackPlugin.getCompilationHooks(
compilation,
).alterAssetTagGroups.tapPromise('MoveTagsPlugin', async data => {
data.headTags.push(data.headTags.bodyTags.filter(i => i.async));
data.bodyTags = data.bodyTags.filter(i => !i.async);
});
});
},
};
module.exports = {
//...
plugins: [
new HtmlRspackPlugin({
inject: 'body',
}),
AllHeadTagsPlugin,
],
};
afterTemplateExecution
このフックは、テンプレートのレンダリングが完了した後、タグが挿入される前に呼び出されます。
ここでHTMLコンテンツと挿入するタグを変更できます。
-
関数templateContent
または.js/.cjs
で終わるtemplate
を使用し、この関数を使用してテンプレートをレンダリングする場合、html
は関数によって返される結果です。
-
他のシナリオでは、HTMLテンプレートは内部のテンプレートエンジンによってコンパイルされ、html
はコンパイルされた結果になります。
-
型: AsyncSeriesWaterfallHook<[AfterTemplateExecutionData]>
-
パラメータ:
type AfterTemplateExecutionData = {
html: string;
headTags: Array<HtmlTag>;
bodyTags: Array<HtmlTag>;
outputName: string;
plugin: {
options: HtmlRspackPluginOptions;
};
};
:::warning 警告 html
、headTags
、bodyTags
のみ変更できます。他の項目の変更は有効になりません。::
次のコードは、本文の最後にInjected by plugin
を追加します。その後、このテキストの後にタグが挿入されます。そのため、最終的なHTMLコンテンツでは<Injected by plugin<script defer src="main.js"></script></body>
となります。
rspack.config.js
const InjectContentPlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('InjectContentPlugin', compilation => {
HtmlWebpackPlugin.getCompilationHooks(
compilation,
).afterTemplateExecution.tapPromise('InjectContentPlugin', async data => {
data.html = data.html.replace('</body>', 'Injected by plugin</body>');
});
});
},
};
module.exports = {
//...
plugins: [
new HtmlRspackPlugin({
inject: 'body',
}),
InjectContentPlugin,
],
};
beforeEmit
このフックは、HTMLアセットファイルを生成する前に呼び出され、HTMLコンテンツを変更する最後の機会です。
- 型:
SyncHook<[BeforeEmitData]>
- パラメータ:
type BeforeEmitData = {
html: string;
outputName: string;
plugin: {
options: HtmlRspackPluginOptions;
};
};
警告
html
のみ変更できます。他の項目の変更は有効になりません。
次のコードは、本文の最後にInjected by plugin
を追加します。最終的なHTMLコンテンツでは<script defer src="main.js"></script>Injected by plugin</body>
となります。
rspack.config.js
const InjectContentPlugin = {
apply: function (compiler) {
compiler.hooks.compilation.tap('InjectContentPlugin', compilation => {
HtmlWebpackPlugin.getCompilationHooks(compilation).beforeEmit.tapPromise(
'InjectContentPlugin',
async data => {
data.html = data.html.replace('</body>', 'Injected by plugin</body>');
},
);
});
},
};
module.exports = {
//...
plugins: [
new HtmlRspackPlugin({
inject: 'body',
}),
InjectContentPlugin,
],
};
afterEmit
このフックは、HTMLアセットファイルの生成後に呼び出され、通知のみに使用されます。
- 型:
SyncHook<[AfterEmitData]>
- パラメータ:
type AfterEmitData = {
outputName: string;
plugin: {
options: HtmlRspackPluginOptions;
};
};