将 HTML 导出为字符串。在编译器要求时,HTML 会被最小化。
首先,你需要安装 html-loader
npm install --save-dev html-loader
或
yarn add -D html-loader
或
pnpm add -D html-loader
然后将加载器添加到你的 webpack
配置中。例如:
file.js
import html from "./file.html";
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
},
],
},
};
sources
类型
type sources =
| boolean
| {
list?: Array<{
tag?: string;
attribute?: string;
type?: string;
filter?: (
tag: string,
attribute: string,
attributes: string,
resourcePath: string,
) => boolean;
}>;
urlFilter?: (
attribute: string,
value: string,
resourcePath: string,
) => boolean;
scriptingEnabled?: boolean;
};
默认值:true
默认情况下,每个可加载属性(例如 - <img src="image.png"/>
)都会被导入(const img = require('./image.png')
或 new URL("./image.png", import.meta.url)
)。你可能需要在配置中为图片指定加载器(推荐使用 asset modules
)。
支持的标签和属性
audio
标签的 src
属性embed
标签的 src
属性img
标签的 src
属性img
标签的 srcset
属性input
标签的 src
属性object
标签的 data
属性script
标签的 src
属性script
标签的 href
属性script
标签的 xlink:href
属性source
标签的 src
属性source
标签的 srcset
属性track
标签的 src
属性video
标签的 poster
属性video
标签的 src
属性image
标签的 xlink:href
属性image
标签的 href
属性use
标签的 xlink:href
属性use
标签的 href
属性link
标签的 rel
属性包含 stylesheet
, icon
, shortcut icon
, mask-icon
, apple-touch-icon
, apple-touch-icon-precomposed
, apple-touch-startup-image
, manifest
, prefetch
, preload
时,或当 itemprop
属性为 image
, logo
, screenshot
, thumbnailurl
, contenturl
, downloadurl
, duringmedia
, embedurl
, installurl
, layoutimage
时,link
标签的 href
属性link
标签的 rel
属性包含 stylesheet
, icon
, shortcut icon
, mask-icon
, apple-touch-icon
, apple-touch-icon-precomposed
, apple-touch-startup-image
, manifest
, prefetch
, preload
时,link
标签的 imagesrcset
属性meta
标签的 name
属性为 msapplication-tileimage
, msapplication-square70x70logo
, msapplication-square150x150logo
, msapplication-wide310x150logo
, msapplication-square310x310logo
, msapplication-config
, twitter:image
时,或当 property
属性为 og:image
, og:image:url
, og:image:secure_url
, og:audio
, og:audio:secure_url
, og:video
, og:video:secure_url
, vk:image
时,或当 itemprop
属性为 image
, logo
, screenshot
, thumbnailurl
, contenturl
, downloadurl
, duringmedia
, embedurl
, installurl
, layoutimage
时,meta
标签的 content
属性name
属性为 msapplication-task
时,meta
标签的 content
属性中的 icon-uri
值组件布尔值
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
// Disables attributes processing
sources: false,
},
},
],
},
};
对象
允许你指定要处理、过滤的标签和属性,过滤 URL 并处理以 /
开头的源。
例如
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) => {
// 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;
},
},
},
},
],
},
};
列表
类型
type list = Array<{
tag?: string;
attribute?: string;
type?: string;
filter?: (
tag: string,
attribute: string,
attributes: string,
resourcePath: string,
) => boolean;
}>;
默认值:支持的标签和属性。
允许设置要处理的标签和属性及其处理方式,以及过滤其中一部分的功能。
使用 ...
语法可以扩展默认支持的标签和属性。
例如
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;
},
},
],
},
},
},
],
},
};
如果未指定标签名称,它将处理所有标签。
你可以使用自定义过滤器来指定要处理的 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";
},
},
],
},
},
},
],
},
};
过滤器还可以用于扩展支持的元素和属性。
例如,过滤器可以帮助处理引用资源的 meta 标签
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;
},
},
],
},
},
},
],
},
};
[!注意]
带有
tag
选项的源优先于没有该选项的源。
过滤器可用于禁用默认源。
例如
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
sources: {
list: [
"...",
{
tag: "img",
attribute: "src",
type: "src",
filter: () => false,
},
],
},
},
},
],
},
};
urlFilter
类型
type urlFilter = (
attribute: string,
value: string,
resourcePath: string,
) => boolean;
默认值:undefined
允许过滤 URL。所有被过滤的 URL 都不会被解析(保留在代码中,原样不动)。默认情况下不处理不可请求的源(例如 <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;
},
},
},
},
],
},
};
scriptingEnabled
类型
type scriptingEnabled = boolean;
默认值:true
默认情况下,html-loader
中的解析器将 <noscript>
标签内的内容解释为纯 #text
,因此在处理过程中会忽略这些标签内内容的解析。
为了使解析器将 <noscript>
内部的内容识别为 #AST
并进行处理,请将此选项设置为:false
更多信息:scriptingEnabled
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
sources: {
// Enables processing inside the <noscript> tag
scriptingEnabled: false,
},
},
},
],
},
};
preprocessor
类型
type preprocessor = (content: string, loaderContext: LoaderContext) => string;
默认值:undefined
允许在加载器处理内容之前进行预处理。
[!警告]
你应始终返回有效的 HTML。
file.hbs
<div>
<p>{{firstname}} {{lastname}}</p>
<img src="image.png" alt="alt" />
<div>
函数
你可以将 preprocessor
选项设置为 function
实例。
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
选项设置为异步函数实例。
例如
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;
},
},
},
],
},
};
postprocessor
类型
type postprocessor = (content: string, loaderContext: LoaderContext) => string;
默认值:undefined
允许在替换所有属性(如 src
/srcset
/等)后对内容进行后处理。
file.html
<img src="image.png" />
<img src="<%= 'Hello ' + (1+1) %/>" />
<img src="<%= require('./image.png') %>" />
<img src="<%= new URL('./image.png', import.meta.url) %>" />
<div><%= require('./gallery.html').default %></div>
函数
你可以将 postprocessor
选项设置为 function
实例。
webpack.config.js
const Handlebars = require("handlebars");
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
postprocessor: (content, loaderContext) => {
// When you environment supports template literals (using browserslist or options) we will generate code using them
const isTemplateLiteralSupported = content[0] === "`";
return content
.replace(/<%=/g, isTemplateLiteralSupported ? `\${` : '" +')
.replace(/%>/g, isTemplateLiteralSupported ? "}" : '+ "');
},
},
},
],
},
};
你也可以将 postprocessor
选项设置为异步 function
实例。
例如
webpack.config.js
const Handlebars = require("handlebars");
module.exports = {
module: {
rules: [
{
test: /\.hbs$/i,
loader: "html-loader",
options: {
postprocessor: async (content, loaderContext) => {
const value = await getValue();
// When you environment supports template literals (using browserslist or options) we will generate code using them
const isTemplateLiteralSupported = content[0] === "`";
return content
.replace(/<%=/g, isTemplateLiteralSupported ? `\${` : '" +')
.replace(/%>/g, isTemplateLiteralSupported ? "}" : '+ "')
.replace("my-value", value);
},
},
},
],
},
};
minimize
类型
type minimize =
| boolean
| {
caseSensitive?: boolean;
collapseWhitespace?: boolean;
conservativeCollapse?: boolean;
keepClosingSlash?: boolean;
minifyCSS?: boolean;
minifyJS?: boolean;
removeComments?: boolean;
removeRedundantAttributes?: boolean;
removeScriptTypeAttributes?: boolean;
removeStyleLinkTypeAttributes?: boolean;
};
默认值:生产模式下为 true
,否则为 false
使用此选项可以启用或自定义 html-loader
的 HTML 最小化功能。
布尔值
默认启用的最小化规则如下:
({
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,
},
},
],
},
};
对象
webpack.config.js
有关可用选项的更多信息,请参阅 html-minifier-terser 的文档。
可以在你的 webpack.config.js
中使用以下选项覆盖默认规则
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
minimize: {
removeComments: false,
collapseWhitespace: false,
},
},
},
],
},
};
默认规则可以扩展
webpack.config.js
const { defaultMinimizerOptions } = require("html-loader");
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
minimize: {
...defaultMinimizerOptions,
removeComments: false,
collapseWhitespace: false,
},
},
},
],
},
};
esModule
类型
type esModule = boolean;
默认值:true
默认情况下,html-loader
生成使用 ES 模块语法的 JS 模块。在某些情况下,使用 ES 模块是有益的,例如模块串联和摇树优化。
如果你想生成 CommonJS 模块(例如 module.exports =
),请设置
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
esModule: false,
},
},
],
},
};
<!-- webpackIgnore: true -->
注释禁用 URL 解析使用 <!-- webpackIgnore: true -->
注释可防止 html-loader 处理下一个 HTML 标签的 URL。当你不希望 Webpack 自动处理资产导入时,这非常有用。
<!-- Disabled url handling for the src attribute -->
<!-- webpackIgnore: true -->
<img src="image.png" />
<!-- Disabled url handling for the src and srcset attributes -->
<!-- webpackIgnore: true -->
<img
srcset="image.png 480w, image.png 768w"
src="image.png"
alt="Elva dressed as a fairy"
/>
<!-- Disabled url handling for the content attribute -->
<!-- webpackIgnore: true -->
<meta itemprop="image" content="./image.png" />
<!-- Disabled url handling for the href attribute -->
<!-- webpackIgnore: true -->
<link rel="icon" type="image/png" sizes="192x192" href="./image.png" />
使用 resolve.roots
可以指定一个目录列表,用于解析服务器相对 URL(以 '/' 开头)的请求。
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
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" 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" data-src="data:image/png;base64,..." />'
script
和 link
标签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: ["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",
},
],
},
};
你可以通过利用 html-loader 中的 preprocessor 选项来使用任何模板引擎。preprocessor 函数接收文件内容和加载器上下文,允许你在 HTML 被 webpack 处理之前对其进行转换。
下面是 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;
},
},
},
],
},
};
此设置将使用 Handlebars 转换 file.hbs
模板,然后将结果传递给 html-loader
。
你可以使用 PostHTML 在 HTML 处理之前对其进行转换,而无需额外的加载器。这对于转换图像格式、添加属性或重构标记等任务非常有用。
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;
},
},
},
],
},
};
一个非常常见的场景是将 HTML 导出到它们自己的 .html 文件中,以便直接提供服务而不是通过 JavaScript 注入。这可以通过 html-loader 和 asset modules
的组合来实现。
html-loader 将解析 URL,导入图片和你期望的一切。提取加载器会将 JavaScript 解析回一个正确的 HTML 文件,确保图片被导入并指向正确的路径,而 asset modules
将为你写入 .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: ["html-loader"],
},
],
},
};
我们欢迎所有贡献!如果您是新用户,请在提交问题或拉取请求之前花一些时间阅读我们的贡献指南。