配置 HTML 模板

在构建的过程中,Rsbuild 会基于 HTML 模板文件和模板参数进行编译,生成若干份 HTML 文件。

Rsbuild 提供了一些配置项来对 HTML 模板进行设置。通过本章节你可以了解到这些配置项的基本用法。

设置模板文件

在 Rsbuild 中,你可以使用 html.template 配置项来设置自定义的 HTML 模板文件。

  1. export default {
  2. html: {
  3. template: './static/index.html',
  4. },
  5. };

未设置 html.template 时,Rsbuild 会使用内置的 HTML 模板:

defaultTemplate.html

  1. <!doctype html>
  2. <html>
  3. <head></head>
  4. <body>
  5. <div id="<%= mountId %>"></div>
  6. </body>
  7. </html>

设置页面标题

你可以通过 html.title 配置项来设置 HTML 的 <title> 标签。

当你的项目中只有一个页面时,直接使用 html.title 设置即可:

  1. export default {
  2. html: {
  3. title: 'example',
  4. },
  5. };

当你的项目中有多个页面时,可以基于入口名称来为不同的页面设置对应的标题。

  1. export default {
  2. html: {
  3. title({ entryName }) {
  4. const titles = {
  5. foo: 'Foo',
  6. bar: 'Bar',
  7. };
  8. return titles[entryName];
  9. },
  10. },
  11. };

设置页面图标

Rsbuild 支持设置 favicon 图标 和 iOS 系统下的 apple-touch-icon 图标。

你可以通过 html.favicon 配置项来设置 favicon 图标。

  1. export default {
  2. html: {
  3. favicon: './src/assets/icon.png',
  4. },
  5. };

你也可以通过 html.appIcon 配置项来设置 Web 应用的图标,用于在添加到移动设备的主屏幕时显示。

  1. export default {
  2. html: {
  3. appIcon: {
  4. name: 'My Website',
  5. icons: [
  6. { src: './src/assets/logo-192.png', size: 192 },
  7. { src: './src/assets/logo-512.png', size: 512 },
  8. ],
  9. },
  10. },
  11. };

设置 meta 标签

你可以通过 html.meta 配置项来设置 HTML 的 <meta> 标签。

Rsbuild 默认设置了 charset 和 viewport meta 标签:

  1. <meta charset="UTF-8" />
  2. <meta name="viewport" content="width=device-width, initial-scale=1.0" />

你也可以添加自定义的 meta 标签,比如设置 description:

  1. export default {
  2. html: {
  3. meta: {
  4. description: 'a description of the page',
  5. },
  6. },
  7. };

最终在 HTML 中生成的 meta 标签为:

  1. <meta name="description" content="a description of the page" />

默认模板引擎

Rsbuild 内置了一个默认的模板引擎来处理 HTML 模板文件,它的语法接近 EJS 的子集,但也有一些不同。当 HTML 模板文件的后缀为 .html 时,Rsbuild 会使用内置的模板引擎来解析 HTML 模板。

例如,在模板中定义一个 text 参数,值为 'world'。Rsbuild 在构建时会自动将 <%= text %> 替换为指定的值。

  1. <!-- 输入 -->
  2. <div>hello <%= text %>!</div>
  3. <!-- 输出 -->
  4. <div>hello world!</div>

模板参数

在 HTML 模板中,你可以使用丰富的模板参数,Rsbuild 默认注入的模板参数包括:

  1. type DefaultParameters = {
  2. mountId: string; // 对应 html.mountId 配置
  3. entryName: string; // 入口名称
  4. assetPrefix: string; // 对应 dev.assetPrefix 和 output.assetPrefix 配置
  5. compilation: Compilation; // 对应 Rspack 的 compilation 对象
  6. rspackConfig: Rspack.Configuration; // Rspack 的配置对象
  7. // html-rspack-plugin 生成的参数
  8. htmlPlugin: {
  9. tags: {
  10. headTags: HtmlTagObject[];
  11. bodyTags: HtmlTagObject[];
  12. };
  13. files: {
  14. publicPath: string;
  15. js: Array<string>;
  16. css: Array<string>;
  17. favicon?: string;
  18. };
  19. };
  20. };

你可以通过 html.templateParameters 配置项来传入自定义的模板参数,比如:

rsbuild.config.ts

  1. export default {
  2. html: {
  3. templateParameters: {
  4. text: 'world',
  5. },
  6. },
  7. };

接下来,你可以在 HTML 模板中,通过 <%= text %> 来读取参数:

index.html

  1. <div>hello <%= text %>!</div>

编译后的 HTML 代码如下:

dist/index.html

  1. <div>hello world!</div>

参数转义

使用 <%= text %> 时,参数不会被转义。你可以使用 <%- text %> 来 escape 参数。

比如参数 text 的值是 '<script>',则会被转义为 &lt;script&gt;

  1. <!-- 输入 -->
  2. <div>hello <%- text %>!</div>
  3. <!-- 输出 -->
  4. <div>hello &lt;script&gt;!</div>

TIP

注意,Rsbuild 默认的转义语法是与 EJS 不同的。在 EJS 中,默认的转义语法是 <%= text %>,而 Rsbuild 的默认转义语法是 <%- text %>

其他模板引擎

Rsbuild 也支持通过插件来使用其他模板引擎,如 EJSPug 等。

EJS

Rsbuild 内置的模板语法与 EJS 存在一些差异,如果你需要使用完整的 EJS 语法,可以通过插件来支持,详见 rsbuild-plugin-ejs

Pug

Rsbuild 通过插件来支持 Pug 模板引擎,详见 @rsbuild/plugin-pug

注入标签

通过配置 html.tags 选项,可以在 Rsbuild 生成的 HTML 文件中插入任意标签。

在 HTML 的模版中,可以通过 htmlPlugin.tags 变量来访问被注入到 HTML 的所有标签:

index.html

  1. <html>
  2. <head>
  3. <%= htmlPlugin.tags.headTags %>
  4. </head>
  5. <body>
  6. <div id="root"></div>
  7. <%= htmlPlugin.tags.bodyTags %>
  8. </body>
  9. </html>

html.tags 的作用就是调整这些 tags 变量,从而修改 HTML 里的标签,下面是一个基本的例子:

  1. export default {
  2. html: {
  3. tags: [
  4. { tag: 'script', attrs: { src: 'https://cdn.example.com/my-script.js' } },
  5. ],
  6. },
  7. };
  • 生成的 HTML 文件如下:
  1. <html>
  2. <head>
  3. <script src="https://cdn.example.com/my-script.js"></script>
  4. <!-- some other headTags... -->
  5. </head>
  6. <body>
  7. <!-- some other bodyTags... -->
  8. </body>
  9. </html>

更多用法请参考:html.tags

TIP

通常你不需要手动使用 htmlPlugin.tags.headTagshtmlPlugin.tags.bodyTags 模板参数,因为 Rsbuild 会自动注入这些标签。参考 html.inject 了解调整标签注入位置。

HTML 插件

Rsbuild 内部基于 html-rspack-plugin 实现 HTML 相关的能力。它是 html-webpack-plugin 的一个 fork 版本,具备完全一致的功能和选项。

你可以通过 tools.htmlPlugin 来修改 html-rspack-plugin 的选项,也可以禁用内置的 html-rspack-plugin 插件。

比如:

rsbuild.config.ts

  1. export default {
  2. tools: {
  3. htmlPlugin(config, { entryName }) {
  4. if (process.env.NODE_ENV === 'production') {
  5. config.filename = `${entryName}.[contenthash:8].html`;
  6. }
  7. },
  8. },
  9. };

HTML 压缩

Rsbuild 目前不对 HTML 文件进行压缩,如果你需要压缩 HTML 文件,可以使用 rsbuild-plugin-html-minifier-terser 插件