Webpack html-loader

2023-05-22 09:18 更新

將 HTML 導(dǎo)出為字符串。當(dāng)編譯器需要時(shí),將壓縮 HTML 字符串。

快速開(kāi)始

首先,你需要安裝 ?html-loader? :

npm install --save-dev html-loader

然后將插件添加到你的 webpack 配置中。例如:

file.js

import html from "./file.html";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
      },
    ],
  },
};

選項(xiàng)

名稱(chēng) 類(lèi)型 默認(rèn)值 描述 sources {Boolean|Object} true 啟用/禁用 sources 處理 preprocessor {Function} undefined 允許在處理前對(duì)內(nèi)容進(jìn)行預(yù)處理 minimize {Boolean|Object} 在生產(chǎn)模式下為 true,其他情況為 false 通知 html-loader 壓縮 HTML esModule {Boolean} true 啟用/禁用 ES modules 語(yǔ)法

sources

類(lèi)型: ?Boolean|Object? 默認(rèn)值: true

默認(rèn)情況下,每個(gè)可加載屬性(例如 - ?<img src="image.png"/>? )都將被導(dǎo)入( const img = require (?'./image.png'?) 或 ?import img from "./image.png""? )。 你可能需要為配置中的圖片指定 loader(推薦使用 asset modules)。

支持的標(biāo)簽和屬性:

  • ?audio? 標(biāo)簽的 src 屬性
  • ?embed? 標(biāo)簽的 src 屬性
  • ?img? 標(biāo)簽的 src 屬性
  • ?img? 標(biāo)簽的 srcset 屬性
  • ?input? 標(biāo)簽的 src 屬性
  • ?object? 標(biāo)簽的 data 屬性
  • ?script? 標(biāo)簽的 src 屬性
  • ?script? 標(biāo)簽的 href 屬性
  • ?script? 標(biāo)簽的 xlink:href 屬性
  • ?source? 標(biāo)簽的 src 屬性
  • ?source? 標(biāo)簽的 srcset 屬性
  • ?track? 標(biāo)簽的 src 屬性
  • ?video? 標(biāo)簽的 poster 屬性
  • ?video? 標(biāo)簽的 src 屬性
  • ?image? 標(biāo)簽的 xlink:href 屬性
  • ?image? 標(biāo)簽的 href 屬性
  • ?use? 標(biāo)簽的 xlink:href 屬性
  • ?use? 標(biāo)簽的 href 屬性
  • 當(dāng) rel 屬性值包含 stylesheet、icon、shortcut icon、mask-icon、apple-touch-icon、apple-touch-icon-precomposed、apple-touch-startup-image、manifest、prefetch、preload 或者當(dāng) itemprop 屬性為 image、logo、screenshot、thumbnailurl、contenturl、downloadurl、duringmedia、embedurl、installurl、layoutimage 時(shí),支持 link 標(biāo)簽的 href 屬性
  • 當(dāng) rel 屬性值包含 stylesheet、icon、shortcut icon、mask-icon、apple-touch-icon、apple-touch-icon-precomposed、apple-touch-startup-image、manifest、prefetch、preload時(shí),支持 link 標(biāo)簽的 imagesrcset 屬性
  • 當(dāng) name 屬性為 msapplication-tileimage、msapplication-square70x70logo、msapplication-square150x150logo、msapplication-wide310x150logo、msapplication-square310x310logo、msapplication-config、twitter:image 或者當(dāng) property 屬性為 og:image、og:image:url、og:image:secure_url、og:audio、og:audio:secure_url、og:video、og:video:secure_url、vk:image,支持 meta 標(biāo)簽的 content 屬性。
  • 當(dāng) name 屬性為 msapplication-task 時(shí),支持 meta 標(biāo)簽的 content 屬性中的 icon-uri 值組件

Boolean

當(dāng)設(shè)置為 true 時(shí),則啟用所有默認(rèn)元素和屬性的處理,而 false 則禁用所有屬性的處理。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          // Disables attributes processing
          sources: false,
        },
      },
    ],
  },
};

Object

你可以配置要處理的標(biāo)簽和屬性,來(lái)過(guò)濾它們,過(guò)濾 URL 并處理以 / 開(kāi)頭的資源地址。

例如:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            list: [
              // All default supported tags and attributes
              "...",
              {
                tag: "img",
                attribute: "data-src",
                type: "src",
              },
              {
                tag: "img",
                attribute: "data-srcset",
                type: "srcset",
              },
            ],
            urlFilter: (attribute, value, resourcePath) => {
              // `attribute` 參數(shù)包含一個(gè) HTML 屬性的名稱(chēng)。
              // `value` 參數(shù)包含一個(gè) HTML 屬性的值。
              // `resourcePath` 參數(shù)包含一個(gè)已加載 HTML 文件的路徑。

              if (/example\.pdf$/.test(value)) {
                return false;
              }

              return true;
            },
          },
        },
      },
    ],
  },
};

list

類(lèi)型:?Array? 默認(rèn)值:支持的標(biāo)簽和屬性列表

允許設(shè)置要處理的標(biāo)簽和屬性以及處理方式,以及過(guò)濾其中一些標(biāo)簽和屬性的能力。

使用 ... 語(yǔ)法可以使用所有默認(rèn)支持的標(biāo)簽和屬性。

例如:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            list: [
              // All default supported tags and attributes
              "...",
              {
                tag: "img",
                attribute: "data-src",
                type: "src",
              },
              {
                tag: "img",
                attribute: "data-srcset",
                type: "srcset",
              },
              {
                // Tag name
                tag: "link",
                // Attribute name
                attribute: "href",
                // Type of processing, can be `src` or `scrset`
                type: "src",
                // Allow to filter some attributes
                filter: (tag, attribute, attributes, resourcePath) => {
                  // The `tag` argument contains a name of the HTML tag.
                  // The `attribute` argument contains a name of the HTML attribute.
                  // The `attributes` argument contains all attributes of the tag.
                  // The `resourcePath` argument contains a path to the loaded HTML file.

                  if (/my-html\.html$/.test(resourcePath)) {
                    return false;
                  }

                  if (!/stylesheet/i.test(attributes.rel)) {
                    return false;
                  }

                  if (
                    attributes.type &&
                    attributes.type.trim().toLowerCase() !== "text/css"
                  ) {
                    return false;
                  }

                  return true;
                },
              },
            ],
          },
        },
      },
    ],
  },
};

如果未指定標(biāo)簽名稱(chēng),它將處理所有標(biāo)簽。

你可以使用自定義過(guò)濾器指定要處理的 html 元素。

例如:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            list: [
              {
                // Attribute name
                attribute: "src",
                // Type of processing, can be `src` or `scrset`
                type: "src",
                // Allow to filter some attributes (optional)
                filter: (tag, attribute, attributes, resourcePath) => {
                  // The `tag` argument contains a name of the HTML tag.
                  // The `attribute` argument contains a name of the HTML attribute.
                  // The `attributes` argument contains all attributes of the tag.
                  // The `resourcePath` argument contains a path to the loaded HTML file.

                  // choose all HTML tags except img tag
                  return tag.toLowerCase() !== "img";
                },
              },
            ],
          },
        },
      },
    ],
  },
};

filter 也可以用來(lái)擴(kuò)展支持的元素和屬性。

例如,filter 可以幫助處理引用資源的 meta 標(biāo)簽:

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            list: [
              {
                tag: "meta",
                attribute: "content",
                type: "src",
                filter: (tag, attribute, attributes, resourcePath) => {
                  if (
                    attributes.value === "og:image" ||
                    attributes.name === "twitter:image"
                  ) {
                    return true;
                  }

                  return false;
                },
              },
            ],
          },
        },
      },
    ],
  },
};

請(qǐng)注意: 帶有 tag 配置項(xiàng)的 source 優(yōu)先級(jí)要比沒(méi)有 tag 配置項(xiàng)的高。

filter 可以用于禁用默認(rèn) source。

示例:

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            list: [
              "...",
              {
                tag: "img",
                attribute: "src",
                type: "src",
                filter: () => false,
              },
            ],
          },
        },
      },
    ],
  },
};

urlFilter

類(lèi)型:?Function? 默認(rèn)值: undefined

允許配置要過(guò)濾的 url。所有過(guò)濾的 url 都參與解析(會(huì)保持原樣)。 默認(rèn)情況下,所有非請(qǐng)求資源類(lèi)型的值(例如 ?<img src="javascript:void (0)" />? )都不處理。

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          sources: {
            urlFilter: (attribute, value, resourcePath) => {
              // The `attribute` argument contains a name of the HTML attribute.
              // The `value` argument contains a value of the HTML attribute.
              // The `resourcePath` argument contains a path to the loaded HTML file.

              if (/example\.pdf$/.test(value)) {
                return false;
              }

              return true;
            },
          },
        },
      },
    ],
  },
};

preprocessor

類(lèi)型:?Function? 默認(rèn)值:undefined

允許在處理之前對(duì)內(nèi)容進(jìn)行預(yù)處理。

?你應(yīng)該始終返回有效的 HTML

file.hbs

<div>
  <p>{{firstname}} {{lastname}}</p>
  <img src="image.png" alt="alt" />
<div>

Function

你可以將 preprocessor 選項(xiàng)設(shè)置為 Function 實(shí)例。

webpack.config.js

const Handlebars = require("handlebars");

module.exports = {
  module: {
    rules: [
      {
        test: /\.hbs$/i,
        loader: "html-loader",
        options: {
          preprocessor: (content, loaderContext) => {
            let result;

            try {
              result = Handlebars.compile(content)({
                firstname: "Value",
                lastname: "OtherValue",
              });
            } catch (error) {
              loaderContext.emitError(error);

              return content;
            }

            return result;
          },
        },
      },
    ],
  },
};

你還可以將 preprocessor 選項(xiàng)設(shè)置為異步函數(shù)實(shí)例。

例如:

webpack.config.js

const Handlebars = require("handlebars");

module.exports = {
  module: {
    rules: [
      {
        test: /\.hbs$/i,
        loader: "html-loader",
        options: {
          preprocessor: async (content, loaderContext) => {
            let result;

            try {
              result = await Handlebars.compile(content)({
                firstname: "Value",
                lastname: "OtherValue",
              });
            } catch (error) {
              await loaderContext.emitError(error);

              return content;
            }

            return result;
          },
        },
      },
    ],
  },
};

minimize

類(lèi)型:?Boolean|Object? 默認(rèn)值:在生產(chǎn)模式下為 true ,否則為 false

告訴 ?html-loader? 編譯時(shí)需要壓縮 HTML 字符串。

Boolean

默認(rèn)情況下,啟用壓縮的規(guī)則如下:

({
  caseSensitive: true,
  collapseWhitespace: true,
  conservativeCollapse: true,
  keepClosingSlash: true,
  minifyCSS: true,
  minifyJS: true,
  removeComments: true,
  removeRedundantAttributes: true,
  removeScriptTypeAttributes: true,
  removeStyleLinkTypeAttributes: true,
});

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          minimize: true,
        },
      },
    ],
  },
};

Object

webpack.config.js

關(guān)于可用選項(xiàng)的更多信息,請(qǐng)參閱 html-minifier-terser 文檔。

可以在 webpack.conf.js 中使用以下選項(xiàng)來(lái)禁用規(guī)則

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          minimize: {
            removeComments: false,
            collapseWhitespace: false,
          },
        },
      },
    ],
  },
};

esModule

類(lèi)型:?Boolean? 默認(rèn)值:false

默認(rèn)情況下, html-loader 生成使用 ES modules 語(yǔ)法的 JS 模塊。 在某些情況下,使用 ES modules 會(huì)更好,例如在進(jìn)行模塊合并和 tree shaking 時(shí)。

你可以使用以下方法啟用 CommonJS 模塊語(yǔ)法:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          esModule: false,
        },
      },
    ],
  },
};

示例

使用 <!-- webpackIgnore: true --> 注釋禁用 url 解析

通過(guò) ?<!-- webpackIgnore: true -->? 注釋?zhuān)梢越固幚硐乱粋€(gè)標(biāo)簽的源。

<!-- 禁止對(duì) src 屬性進(jìn)行 url 處理 -->
<!-- webpackIgnore: true -->
<img src="image.png" />

<!-- 禁止對(duì) src 與 srcset 屬性進(jìn)行 url 處理 -->
<!-- webpackIgnore: true -->
<img
  srcset="image.png 480w, image.png 768w"
  src="image.png"
  alt="Elva dressed as a fairy"
/>

<!-- 禁止對(duì) content 屬性進(jìn)行 url 處理 -->
<!-- webpackIgnore: true -->
<meta itemprop="image" content="./image.png" />

<!-- 禁止對(duì) href 屬性進(jìn)行 url 處理 -->
<!-- webpackIgnore: true -->
<link rel="icon" type="image/png" sizes="192x192" href="./image.png" />

roots

使用 resolve.roots 可以指定解析相對(duì)服務(wù)端的 URL(以 '/' 開(kāi)頭)請(qǐng)求的目錄列表。

webpack.config.js

module.exports = {
  context: __dirname,
  module: {
    rules: [
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {},
      },
      {
        test: /\.jpg$/,
        type: "asset/resource",
      },
    ],
  },
  resolve: {
    roots: [path.resolve(__dirname, "fixtures")],
  },
};

file.html

<img src="/image.jpg" />
// => image.jpg in __dirname/fixtures will be resolved

CDN

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.jpg$/,
        type: "asset/resource",
      },
      {
        test: /\.png$/,
        type: "asset/inline",
      },
    ],
  },
  output: {
    publicPath: "http://cdn.example.com/[fullhash]/",
  },
};

file.html

<img src="image.jpg" data-src="image2x.png" />

index.js

require("html-loader!./file.html");

// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg" rel="external nofollow"  rel="external nofollow"  data-src="image2x.png"/>'
require('html-loader?{"sources":{"list":[{"tag":"img","attribute":"data-src","type":"src"}]}}!./file.html');

// => '<img src="image.jpg" data-src="data:image/png;base64,..." />'
require('html-loader?{"sources":{"list":[{"tag":"img","attribute":"src","type":"src"},{"tag":"img","attribute":"data-src","type":"src"}]}}!./file.html');

// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg" rel="external nofollow"  rel="external nofollow"  data-src="data:image/png;base64,..." />'

處理 script 和 link 標(biāo)簽

script.file.js

console.log(document);

style.file.css

a {
  color: red;
}

file.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Title of the document</title>
    <link rel="stylesheet" type="text/css" href="./style.file.css" />
  </head>
  <body>
    Content of the document......
    <script src="./script.file.js"></script>
  </body>
</html>

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        type: "asset/resource",
        generator: {
          filename: "[name][ext]",
        },
      },
      {
        test: /\.html$/i,
        use: ["extract-loader", "html-loader"],
      },
      {
        test: /\.js$/i,
        exclude: /\.file.js$/i,
        loader: "babel-loader",
      },
      {
        test: /\.file.js$/i,
        type: "asset/resource",
      },
      {
        test: /\.css$/i,
        exclude: /\.file.css$/i,
        loader: "css-loader",
      },
      {
        test: /\.file.css$/i,
        type: "asset/resource",
      },
    ],
  },
};

模板

你可以使用任何模板系統(tǒng)。以下是 handlebars 的示例。

file.hbs

<div>
  <p>{{firstname}} {{lastname}}</p>
  <img src="image.png" alt="alt" />
<div>

webpack.config.js

const Handlebars = require("handlebars");

module.exports = {
  module: {
    rules: [
      {
        test: /\.hbs$/i,
        loader: "html-loader",
        options: {
          preprocessor: (content, loaderContext) => {
            let result;

            try {
              result = Handlebars.compile(content)({
                firstname: "Value",
                lastname: "OtherValue",
              });
            } catch (error) {
              loaderContext.emitError(error);

              return content;
            }

            return result;
          },
        },
      },
    ],
  },
};

PostHTML

你可以使用 PostHTML 而無(wú)需任何其他加載程序。

file.html

<img src="image.jpg" />

webpack.config.js

const posthtml = require("posthtml");
const posthtmlWebp = require("posthtml-webp");

module.exports = {
  module: {
    rules: [
      {
        test: /\.hbs$/i,
        loader: "html-loader",
        options: {
          preprocessor: (content, loaderContext) => {
            let result;

            try {
              result = posthtml().use(plugin).process(content, { sync: true });
            } catch (error) {
              loaderContext.emitError(error);

              return content;
            }

            return result.html;
          },
        },
      },
    ],
  },
};

導(dǎo)出為 HTML 文件

一種非常常見(jiàn)的情況是將 HTML 導(dǎo)出到自己的 .html 文件中,以直接使用, 而非注入到 javascript。 可以使用以下 2 種 loader 的組合來(lái)實(shí)現(xiàn):

  • extract-loader
  • html-loader

還有 asset modules

html-loader 將解析 URL,同時(shí)引入圖片以及你需要的所有內(nèi)容。 extract loader 會(huì)將 javascript 解析為正確的 html 文件, 然后確保圖片被引入且路徑正確, asset modules 會(huì)為你生成 .html 文件。例如:

webpack.config.js

module.exports = {
  output: {
    assetModuleFilename: "[name][ext]",
  },
  module: {
    rules: [
      {
        test: /\.html$/,
        type: "asset/resource",
        generator: {
          filename: "[name][ext]",
        },
      },
      {
        test: /\.html$/i,
        use: ["extract-loader", "html-loader"],
      },
    ],
  },
};

貢獻(xiàn)

如果你還沒(méi)有閱讀,請(qǐng)花一點(diǎn)時(shí)間閱讀我們的貢獻(xiàn)指南。

許可證

MIT


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)