html-loader
Экспортирует 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).
Поддерживаемые теги и атрибуты:
- атрибут
srcтегаaudio - атрибут
srcтегаembed - атрибут
srcтегаimg - атрибут
srcsetтегаimg - атрибут
srcтегаinput - атрибут
dataтегаobject - атрибут
srcтегаscript - атрибут
hrefтегаscript - атрибут
xlink:hrefтегаscript - атрибут
srcтегаsource - атрибут
srcsetтегаsource - атрибут
srcтегаtrack - атрибут
posterтегаvideo - атрибут
srcтегаvideo - атрибут
xlink:hrefтегаimage - атрибут
hrefтегаimage - атрибут
xlink:hrefтегаuse - атрибут
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 - атрибут
imagesrcsetтегаlinkкогда атрибутrelсодержитstylesheet,icon,shortcut icon,mask-icon,apple-touch-icon,apple-touch-icon-precomposed,apple-touch-startup-image,manifest,prefetch,preload - атрибут
contentтега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 - компонент значения
icon-uriв атрибутеcontentтегаmetaкогда атрибутnameимеет значениеmsapplication-task
boolean
Значение true позволяет обработать все стандартные элементы и атрибуты, значение false отключает обработку всех атрибутов.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
// Disables attributes processing
sources: false,
},
},
],
},
};
object
Позволяет указать, какие теги и атрибуты обрабатывать, фильтровать их, фильтровать 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;
},
},
},
},
],
},
};
list
Тип:
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>
function
Можно установить опцию 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>
function
Можно установить опцию 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 в виде асинхронной функции.
Например:
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.
boolean
Правила минимизации по умолчанию:
({
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
См. документацию html-minifier-terser для получения дополнительной информации о доступных опциях.
Правила по умолчанию можно переопределить, используя следующие опции в вашей webpack.conf.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 генерирует JS модули, использующие синтаксис ES модулей. В некоторых случаях использование ES модулей полезно, например, конкатенация модулей и tree shaking.
Вы можете включить синтаксис CommonJS, используя:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
options: {
esModule: false,
},
},
],
},
}; Примеры
Отключение разрешения URL с помощью комментария <!-- webpackIgnore: true -->
С помощью комментария <!-- webpackIgnore: true -->, можно отключить обработку источников для следующего тега.
<!-- 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" />
roots
С помощью 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
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" 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",
},
],
},
}; Шаблонизация
Можно использовать любую систему шаблонов. Ниже приведён пример для 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 без дополнительных загрузчиков.
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 в отдельные файлы .html, чтобы отображать их напрямую, а не вставлять с помощью JavaScript. Это можно сделать с помощью сочетания html-loader и asset modules.
Загрузчик html-loader будет парсить URL-адреса, загружать изображения и всё, что вы ожидаете. Загрузчик extract будет парсить 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"],
},
],
},
}; Содействие
Пожалуйста, ознакомьтесь с нашими рекомендациями по участию в проекте, если вы ещё этого не сделали.
Лицензия
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/loaders/html-loader