UNPKG

23.3 kBMarkdownView Raw
1<div align="center">
2 <img width="200" height="200" src="https://worldvectorlogo.com/logos/html5.svg" alt="html-loader">
3 <a href="https://github.com/webpack/webpack">
4 <img width="200" height="200" vspace="" hspace="25" src="https://webpack.js.org/assets/icon-square-big.svg" alt="webpack">
5 </a>
6</div>
7
8[![npm][npm]][npm-url]
9[![node][node]][node-url]
10[![deps][deps]][deps-url]
11[![tests][tests]][tests-url]
12[![coverage][cover]][cover-url]
13[![chat][chat]][chat-url]
14[![size][size]][size-url]
15
16# html-loader
17
18Exports HTML as string. HTML is minimized when the compiler demands.
19
20## Getting Started
21
22To begin, you'll need to install `html-loader`:
23
24```console
25npm install --save-dev html-loader
26```
27
28Then add the plugin to your `webpack` config. For example:
29
30**file.js**
31
32```js
33import html from "./file.html";
34```
35
36**webpack.config.js**
37
38```js
39module.exports = {
40 module: {
41 rules: [
42 {
43 test: /\.html$/i,
44 loader: "html-loader",
45 },
46 ],
47 },
48};
49```
50
51## Options
52
53| Name | Type | Default | Description |
54| :---------------------------------: | :-----------------: | :------------------------------------------: | :----------------------------------------------- |
55| **[`sources`](#sources)** | `{Boolean\|Object}` | `true` | Enables/Disables sources handling |
56| **[`preprocessor`](#preprocessor)** | `{Function}` | `undefined` | Allows pre-processing of content before handling |
57| **[`minimize`](#minimize)** | `{Boolean\|Object}` | `true` in production mode, otherwise `false` | Tell `html-loader` to minimize HTML |
58| **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Enable/disable ES modules syntax |
59
60### `sources`
61
62Type: `Boolean|Object`
63Default: `true`
64
65By default every loadable attributes (for example - `<img src="image.png">`) is imported (`const img = require('./image.png')` or `import img from "./image.png""`).
66You may need to specify loaders for images in your configuration (recommended [`asset modules`](https://webpack.js.org/guides/asset-modules/)).
67
68Supported tags and attributes:
69
70- the `src` attribute of the `audio` tag
71- the `src` attribute of the `embed` tag
72- the `src` attribute of the `img` tag
73- the `srcset` attribute of the `img` tag
74- the `src` attribute of the `input` tag
75- the `data` attribute of the `object` tag
76- the `src` attribute of the `script` tag
77- the `href` attribute of the `script` tag
78- the `xlink:href` attribute of the `script` tag
79- the `src` attribute of the `source` tag
80- the `srcset` attribute of the `source` tag
81- the `src` attribute of the `track` tag
82- the `poster` attribute of the `video` tag
83- the `src` attribute of the `video` tag
84- the `xlink:href` attribute of the `image` tag
85- the `href` attribute of the `image` tag
86- the `xlink:href` attribute of the `use` tag
87- the `href` attribute of the `use` tag
88- the `href` attribute of the `link` tag when the `rel` attribute contains `stylesheet`, `icon`, `shortcut icon`, `mask-icon`, `apple-touch-icon`, `apple-touch-icon-precomposed`, `apple-touch-startup-image`, `manifest`, `prefetch`, `preload` or when the `itemprop` attribute is `image`, `logo`, `screenshot`, `thumbnailurl`, `contenturl`, `downloadurl`, `duringmedia`, `embedurl`, `installurl`, `layoutimage`
89- the `imagesrcset` attribute of the `link` tag when the `rel` attribute contains `stylesheet`, `icon`, `shortcut icon`, `mask-icon`, `apple-touch-icon`, `apple-touch-icon-precomposed`, `apple-touch-startup-image`, `manifest`, `prefetch`, `preload`
90- the `content` attribute of the `meta` tag when the `name` attribute is `msapplication-tileimage`, `msapplication-square70x70logo`, `msapplication-square150x150logo`, `msapplication-wide310x150logo`, `msapplication-square310x310logo`, `msapplication-config`, `twitter:image` or when the `property` attribute is `og:image`, `og:image:url`, `og:image:secure_url`, `og:audio`, `og:audio:secure_url`, `og:video`, `og:video:secure_url`, `vk:image` or when the `itemprop` attribute is `image`, `logo`, `screenshot`, `thumbnailurl`, `contenturl`, `downloadurl`, `duringmedia`, `embedurl`, `installurl`, `layoutimage`
91- the `icon-uri` value component in `content` attribute of the `meta` tag when the `name` attribute is `msapplication-task`
92
93#### `Boolean`
94
95The `true` value enables processing of all default elements and attributes, the `false` disable processing of all attributes.
96
97**webpack.config.js**
98
99```js
100module.exports = {
101 module: {
102 rules: [
103 {
104 test: /\.html$/i,
105 loader: "html-loader",
106 options: {
107 // Disables attributes processing
108 sources: false,
109 },
110 },
111 ],
112 },
113};
114```
115
116#### `Object`
117
118Allows you to specify which tags and attributes to process, filter them, filter urls and process sources starts with `/`.
119
120For example:
121
122**webpack.config.js**
123
124```js
125module.exports = {
126 module: {
127 rules: [
128 {
129 test: /\.html$/i,
130 loader: "html-loader",
131 options: {
132 sources: {
133 list: [
134 // All default supported tags and attributes
135 "...",
136 {
137 tag: "img",
138 attribute: "data-src",
139 type: "src",
140 },
141 {
142 tag: "img",
143 attribute: "data-srcset",
144 type: "srcset",
145 },
146 ],
147 urlFilter: (attribute, value, resourcePath) => {
148 // The `attribute` argument contains a name of the HTML attribute.
149 // The `value` argument contains a value of the HTML attribute.
150 // The `resourcePath` argument contains a path to the loaded HTML file.
151
152 if (/example\.pdf$/.test(value)) {
153 return false;
154 }
155
156 return true;
157 },
158 },
159 },
160 },
161 ],
162 },
163};
164```
165
166#### `list`
167
168Type: `Array`
169Default: [supported tags and attributes](#sources).
170
171Allows to setup which tags and attributes to process and how, and the ability to filter some of them.
172
173Using `...` syntax allows you to extend [default supported tags and attributes](#sources).
174
175For example:
176
177**webpack.config.js**
178
179```js
180module.exports = {
181 module: {
182 rules: [
183 {
184 test: /\.html$/i,
185 loader: "html-loader",
186 options: {
187 sources: {
188 list: [
189 // All default supported tags and attributes
190 "...",
191 {
192 tag: "img",
193 attribute: "data-src",
194 type: "src",
195 },
196 {
197 tag: "img",
198 attribute: "data-srcset",
199 type: "srcset",
200 },
201 {
202 // Tag name
203 tag: "link",
204 // Attribute name
205 attribute: "href",
206 // Type of processing, can be `src` or `scrset`
207 type: "src",
208 // Allow to filter some attributes
209 filter: (tag, attribute, attributes, resourcePath) => {
210 // The `tag` argument contains a name of the HTML tag.
211 // The `attribute` argument contains a name of the HTML attribute.
212 // The `attributes` argument contains all attributes of the tag.
213 // The `resourcePath` argument contains a path to the loaded HTML file.
214
215 if (/my-html\.html$/.test(resourcePath)) {
216 return false;
217 }
218
219 if (!/stylesheet/i.test(attributes.rel)) {
220 return false;
221 }
222
223 if (
224 attributes.type &&
225 attributes.type.trim().toLowerCase() !== "text/css"
226 ) {
227 return false;
228 }
229
230 return true;
231 },
232 },
233 ],
234 },
235 },
236 },
237 ],
238 },
239};
240```
241
242If the tag name is not specified it will process all the tags.
243
244> You can use your custom filter to specify html elements to be processed.
245
246For example:
247
248**webpack.config.js**
249
250```js
251module.exports = {
252 module: {
253 rules: [
254 {
255 test: /\.html$/i,
256 loader: "html-loader",
257 options: {
258 sources: {
259 list: [
260 {
261 // Attribute name
262 attribute: "src",
263 // Type of processing, can be `src` or `scrset`
264 type: "src",
265 // Allow to filter some attributes (optional)
266 filter: (tag, attribute, attributes, resourcePath) => {
267 // The `tag` argument contains a name of the HTML tag.
268 // The `attribute` argument contains a name of the HTML attribute.
269 // The `attributes` argument contains all attributes of the tag.
270 // The `resourcePath` argument contains a path to the loaded HTML file.
271
272 // choose all HTML tags except img tag
273 return tag.toLowerCase() !== "img";
274 },
275 },
276 ],
277 },
278 },
279 },
280 ],
281 },
282};
283```
284
285Filter can also be used to extend the supported elements and attributes.
286
287For example, filter can help process meta tags that reference assets:
288
289```js
290module.exports = {
291 module: {
292 rules: [
293 {
294 test: /\.html$/i,
295 loader: "html-loader",
296 options: {
297 sources: {
298 list: [
299 {
300 tag: "meta",
301 attribute: "content",
302 type: "src",
303 filter: (tag, attribute, attributes, resourcePath) => {
304 if (
305 attributes.value === "og:image" ||
306 attributes.name === "twitter:image"
307 ) {
308 return true;
309 }
310
311 return false;
312 },
313 },
314 ],
315 },
316 },
317 },
318 ],
319 },
320};
321```
322
323**Note:** source with a `tag` option takes precedence over source without.
324
325Filter can be used to disable default sources.
326
327For example:
328
329```js
330module.exports = {
331 module: {
332 rules: [
333 {
334 test: /\.html$/i,
335 loader: "html-loader",
336 options: {
337 sources: {
338 list: [
339 "...",
340 {
341 tag: "img",
342 attribute: "src",
343 type: "src",
344 filter: () => false,
345 },
346 ],
347 },
348 },
349 },
350 ],
351 },
352};
353```
354
355#### `urlFilter`
356
357Type: `Function`
358Default: `undefined`
359
360Allow to filter urls. All filtered urls will not be resolved (left in the code as they were written).
361All non requestable sources (for example `<img src="javascript:void(0)">`) do not handle by default.
362
363```js
364module.exports = {
365 module: {
366 rules: [
367 {
368 test: /\.html$/i,
369 loader: "html-loader",
370 options: {
371 sources: {
372 urlFilter: (attribute, value, resourcePath) => {
373 // The `attribute` argument contains a name of the HTML attribute.
374 // The `value` argument contains a value of the HTML attribute.
375 // The `resourcePath` argument contains a path to the loaded HTML file.
376
377 if (/example\.pdf$/.test(value)) {
378 return false;
379 }
380
381 return true;
382 },
383 },
384 },
385 },
386 ],
387 },
388};
389```
390
391### `preprocessor`
392
393Type: `Function`
394Default: `undefined`
395
396Allows pre-processing of content before handling.
397
398> ⚠ You should always return valid HTML
399
400**file.hbs**
401
402```hbs
403<div>
404 <p>{{firstname}} {{lastname}}</p>
405 <img src="image.png" alt="alt" />
406<div>
407```
408
409#### `Function`
410
411You can set the `preprocessor` option as a `Function` instance.
412
413**webpack.config.js**
414
415```js
416const Handlebars = require("handlebars");
417
418module.exports = {
419 module: {
420 rules: [
421 {
422 test: /\.hbs$/i,
423 loader: "html-loader",
424 options: {
425 preprocessor: (content, loaderContext) => {
426 let result;
427
428 try {
429 result = Handlebars.compile(content)({
430 firstname: "Value",
431 lastname: "OtherValue",
432 });
433 } catch (error) {
434 loaderContext.emitError(error);
435
436 return content;
437 }
438
439 return result;
440 },
441 },
442 },
443 ],
444 },
445};
446```
447
448You can also set the `preprocessor` option as an asynchronous function instance.
449
450For example:
451
452**webpack.config.js**
453
454```js
455const Handlebars = require("handlebars");
456
457module.exports = {
458 module: {
459 rules: [
460 {
461 test: /\.hbs$/i,
462 loader: "html-loader",
463 options: {
464 preprocessor: async (content, loaderContext) => {
465 let result;
466
467 try {
468 result = await Handlebars.compile(content)({
469 firstname: "Value",
470 lastname: "OtherValue",
471 });
472 } catch (error) {
473 await loaderContext.emitError(error);
474
475 return content;
476 }
477
478 return result;
479 },
480 },
481 },
482 ],
483 },
484};
485```
486
487### `minimize`
488
489Type: `Boolean|Object`
490Default: `true` in production mode, otherwise `false`
491
492Tell `html-loader` to minimize HTML.
493
494#### `Boolean`
495
496The enabled rules for minimizing by default are the following ones:
497
498```js
499({
500 caseSensitive: true,
501 collapseWhitespace: true,
502 conservativeCollapse: true,
503 keepClosingSlash: true,
504 minifyCSS: true,
505 minifyJS: true,
506 removeComments: true,
507 removeRedundantAttributes: true,
508 removeScriptTypeAttributes: true,
509 removeStyleLinkTypeAttributes: true,
510});
511```
512
513**webpack.config.js**
514
515```js
516module.exports = {
517 module: {
518 rules: [
519 {
520 test: /\.html$/i,
521 loader: "html-loader",
522 options: {
523 minimize: true,
524 },
525 },
526 ],
527 },
528};
529```
530
531#### `Object`
532
533**webpack.config.js**
534
535See [html-minifier-terser](https://github.com/DanielRuf/html-minifier-terser)'s documentation for more information on the available options.
536
537The default rules can be overridden using the following options in your `webpack.conf.js`
538
539**webpack.config.js**
540
541```js
542module.exports = {
543 module: {
544 rules: [
545 {
546 test: /\.html$/i,
547 loader: "html-loader",
548 options: {
549 minimize: {
550 removeComments: false,
551 collapseWhitespace: false,
552 },
553 },
554 },
555 ],
556 },
557};
558```
559
560The default rules can be extended:
561
562**webpack.config.js**
563
564```js
565const { defaultMinimizerOptions } = require("html-loader");
566
567module.exports = {
568 module: {
569 rules: [
570 {
571 test: /\.html$/i,
572 loader: "html-loader",
573 options: {
574 minimize: {
575 ...defaultMinimizerOptions,
576 removeComments: false,
577 collapseWhitespace: false,
578 },
579 },
580 },
581 ],
582 },
583};
584```
585
586### `esModule`
587
588Type: `Boolean`
589Default: `true`
590
591By default, `html-loader` generates JS modules that use the ES modules syntax.
592There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).
593
594You can enable a CommonJS modules syntax using:
595
596**webpack.config.js**
597
598```js
599module.exports = {
600 module: {
601 rules: [
602 {
603 test: /\.html$/i,
604 loader: "html-loader",
605 options: {
606 esModule: false,
607 },
608 },
609 ],
610 },
611};
612```
613
614## Examples
615
616### Disable url resolving using the `<!-- webpackIgnore: true -->` comment
617
618With `<!-- webpackIgnore: true -->` comment, can to disable sources handling for next tag.
619
620```html
621<!-- Disabled url handling for the src attribute -->
622<!-- webpackIgnore: true -->
623<img src="image.png" />
624
625<!-- Disabled url handling for the src and srcset attributes -->
626<!-- webpackIgnore: true -->
627<img
628 srcset="image.png 480w, image.png 768w"
629 src="image.png"
630 alt="Elva dressed as a fairy"
631/>
632
633<!-- Disabled url handling for the content attribute -->
634<!-- webpackIgnore: true -->
635<meta itemprop="image" content="./image.png" />
636
637<!-- Disabled url handling for the href attribute -->
638<!-- webpackIgnore: true -->
639<link rel="icon" type="image/png" sizes="192x192" href="./image.png" />
640```
641
642### roots
643
644With [`resolve.roots`](https://webpack.js.org/configuration/resolve/#resolveroots) can specify a list of directories where requests of server-relative URLs (starting with '/') are resolved.
645
646**webpack.config.js**
647
648```js
649module.exports = {
650 context: __dirname,
651 module: {
652 rules: [
653 {
654 test: /\.html$/i,
655 loader: "html-loader",
656 options: {},
657 },
658 {
659 test: /\.jpg$/,
660 type: "asset/resource",
661 },
662 ],
663 },
664 resolve: {
665 roots: [path.resolve(__dirname, "fixtures")],
666 },
667};
668```
669
670**file.html**
671
672```html
673<img src="/image.jpg" />
674```
675
676```js
677// => image.jpg in __dirname/fixtures will be resolved
678```
679
680### CDN
681
682**webpack.config.js**
683
684```js
685module.exports = {
686 module: {
687 rules: [
688 {
689 test: /\.jpg$/,
690 type: "asset/resource",
691 },
692 {
693 test: /\.png$/,
694 type: "asset/inline",
695 },
696 ],
697 },
698 output: {
699 publicPath: "http://cdn.example.com/[fullhash]/",
700 },
701};
702```
703
704**file.html**
705
706```html
707<img src="image.jpg" data-src="image2x.png" />
708```
709
710**index.js**
711
712```js
713require("html-loader!./file.html");
714
715// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg" data-src="image2x.png">'
716```
717
718```js
719require('html-loader?{"sources":{"list":[{"tag":"img","attribute":"data-src","type":"src"}]}}!./file.html');
720
721// => '<img src="image.jpg" data-src="data:image/png;base64,..." >'
722```
723
724```js
725require('html-loader?{"sources":{"list":[{"tag":"img","attribute":"src","type":"src"},{"tag":"img","attribute":"data-src","type":"src"}]}}!./file.html');
726
727// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg" data-src="data:image/png;base64,..." >'
728```
729
730### Process `script` and `link` tags
731
732**script.file.js**
733
734```js
735console.log(document);
736```
737
738**style.file.css**
739
740```css
741a {
742 color: red;
743}
744```
745
746**file.html**
747
748```html
749<!DOCTYPE html>
750<html>
751 <head>
752 <meta charset="UTF-8" />
753 <title>Title of the document</title>
754 <link rel="stylesheet" type="text/css" href="./style.file.css" />
755 </head>
756 <body>
757 Content of the document......
758 <script src="./script.file.js"></script>
759 </body>
760</html>
761```
762
763**webpack.config.js**
764
765```js
766module.exports = {
767 module: {
768 rules: [
769 {
770 test: /\.html$/,
771 type: "asset/resource",
772 generator: {
773 filename: "[name][ext]",
774 },
775 },
776 {
777 test: /\.html$/i,
778 use: ["extract-loader", "html-loader"],
779 },
780 {
781 test: /\.js$/i,
782 exclude: /\.file.js$/i,
783 loader: "babel-loader",
784 },
785 {
786 test: /\.file.js$/i,
787 type: "asset/resource",
788 },
789 {
790 test: /\.css$/i,
791 exclude: /\.file.css$/i,
792 loader: "css-loader",
793 },
794 {
795 test: /\.file.css$/i,
796 type: "asset/resource",
797 },
798 ],
799 },
800};
801```
802
803### Templating
804
805You can use any template system. Below is an example for [handlebars](https://handlebarsjs.com/).
806
807**file.hbs**
808
809```hbs
810<div>
811 <p>{{firstname}} {{lastname}}</p>
812 <img src="image.png" alt="alt" />
813<div>
814```
815
816**webpack.config.js**
817
818```js
819const Handlebars = require("handlebars");
820
821module.exports = {
822 module: {
823 rules: [
824 {
825 test: /\.hbs$/i,
826 loader: "html-loader",
827 options: {
828 preprocessor: (content, loaderContext) => {
829 let result;
830
831 try {
832 result = Handlebars.compile(content)({
833 firstname: "Value",
834 lastname: "OtherValue",
835 });
836 } catch (error) {
837 loaderContext.emitError(error);
838
839 return content;
840 }
841
842 return result;
843 },
844 },
845 },
846 ],
847 },
848};
849```
850
851### PostHTML
852
853You can use [PostHTML](https://github.com/posthtml/posthtml) without any additional loaders.
854
855**file.html**
856
857```html
858<img src="image.jpg" />
859```
860
861**webpack.config.js**
862
863```js
864const posthtml = require("posthtml");
865const posthtmlWebp = require("posthtml-webp");
866
867module.exports = {
868 module: {
869 rules: [
870 {
871 test: /\.hbs$/i,
872 loader: "html-loader",
873 options: {
874 preprocessor: (content, loaderContext) => {
875 let result;
876
877 try {
878 result = posthtml().use(plugin).process(content, { sync: true });
879 } catch (error) {
880 loaderContext.emitError(error);
881
882 return content;
883 }
884
885 return result.html;
886 },
887 },
888 },
889 ],
890 },
891};
892```
893
894### Export into HTML files
895
896A very common scenario is exporting the HTML into their own _.html_ file, to
897serve them directly instead of injecting with javascript. This can be achieved
898with a combination of 2 loaders:
899
900- [extract-loader](https://github.com/peerigon/extract-loader)
901- html-loader
902
903and [`asset modules`](https://webpack.js.org/guides/asset-modules/)
904
905The html-loader will parse the URLs, require the images and everything you
906expect. The extract loader will parse the javascript back into a proper html
907file, ensuring images are required and point to proper path, and the [`asset modules`](https://webpack.js.org/guides/asset-modules/)
908will write the _.html_ file for you. Example:
909
910**webpack.config.js**
911
912```js
913module.exports = {
914 output: {
915 assetModuleFilename: "[name][ext]",
916 },
917 module: {
918 rules: [
919 {
920 test: /\.html$/,
921 type: "asset/resource",
922 generator: {
923 filename: "[name][ext]",
924 },
925 },
926 {
927 test: /\.html$/i,
928 use: ["extract-loader", "html-loader"],
929 },
930 ],
931 },
932};
933```
934
935## Contributing
936
937Please take a moment to read our contributing guidelines if you haven't yet done so.
938
939[CONTRIBUTING](./.github/CONTRIBUTING.md)
940
941## License
942
943[MIT](./LICENSE)
944
945[npm]: https://img.shields.io/npm/v/html-loader.svg
946[npm-url]: https://npmjs.com/package/html-loader
947[node]: https://img.shields.io/node/v/html-loader.svg
948[node-url]: https://nodejs.org
949[deps]: https://david-dm.org/webpack-contrib/html-loader.svg
950[deps-url]: https://david-dm.org/webpack-contrib/html-loader
951[tests]: https://github.com/webpack-contrib/html-loader/workflows/html-loader/badge.svg
952[tests-url]: https://github.com/webpack-contrib/html-loader/actions
953[cover]: https://codecov.io/gh/webpack-contrib/html-loader/branch/master/graph/badge.svg
954[cover-url]: https://codecov.io/gh/webpack-contrib/html-loader
955[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
956[chat-url]: https://gitter.im/webpack/webpack
957[size]: https://packagephobia.now.sh/badge?p=html-loader
958[size-url]: https://packagephobia.now.sh/result?p=html-loader