Skip to content

Commit 3c9a1d8

Browse files
refactor: attributes option (#265)
1 parent 8c73761 commit 3c9a1d8

12 files changed

+605
-1247
lines changed

README.md

+173-96
Original file line numberDiff line numberDiff line change
@@ -50,70 +50,16 @@ module.exports = {
5050

5151
## Options
5252

53-
| Name | Type | Default | Description |
54-
| :---------------------------------: | :------------------------: | :------------------------------------------: | :----------------------------------------------- |
55-
| **[`preprocessor`](#preprocessor)** | `{Function}` | `undefined` | Allows pre-processing of content before handling |
56-
| **[`attributes`](#attributes)** | `{Boolean\/Array\/Object}` | `true` | Enables/Disables attributes handling |
57-
| **[`root`](#root)** | `{String}` | `undefiend` | Allow to handle root-relative attributes |
58-
| **[`minimize`](#minimize)** | `{Boolean\|Object}` | `true` in production mode, otherwise `false` | Tell `html-loader` to minimize HTML |
59-
| **[`esModule`](#esmodule)** | `{Boolean}` | `false` | Use ES modules syntax |
60-
61-
### `preprocessor`
62-
63-
Type: `Function`
64-
Default: `undefined`
65-
66-
Allows pre-processing of content before handling.
67-
68-
> ⚠ You should always return valid HTML
69-
70-
**file.hbs**
71-
72-
```hbs
73-
<div>
74-
<p>{{firstname}} {{lastname}}</p>
75-
<img src="image.png" alt="alt" />
76-
<div>
77-
```
78-
79-
**webpack.config.js**
80-
81-
```js
82-
const Handlebars = require('handlebars');
83-
84-
module.exports = {
85-
module: {
86-
rules: [
87-
{
88-
test: /\.hbs$/i,
89-
loader: 'html-loader',
90-
options: {
91-
preprocessor: (content, loaderContext) => {
92-
let result;
93-
94-
try {
95-
result = Handlebars.compile(content)({
96-
firstname: 'Value',
97-
lastname: 'OtherValue',
98-
});
99-
} catch (error) {
100-
loaderContext.emitError(error);
101-
102-
return content;
103-
}
104-
105-
return result;
106-
},
107-
},
108-
},
109-
],
110-
},
111-
};
112-
```
53+
| Name | Type | Default | Description |
54+
| :---------------------------------: | :-----------------: | :------------------------------------------: | :----------------------------------------------- |
55+
| **[`attributes`](#attributes)** | `{Boolean\|Object}` | `true` | Enables/Disables attributes 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}` | `false` | Use ES modules syntax |
11359

11460
### `attributes`
11561

116-
Type: `Boolean|Array|Object`
62+
Type: `Boolean|Object`
11763
Default: `true`
11864

11965
By default every loadable attributes (for example - `<img src="image.png">`) is imported (`const img = require('./image.png')` or `import img from "./image.png""`).
@@ -149,7 +95,7 @@ module.exports = {
14995
test: /\.html$/i,
15096
loader: 'html-loader',
15197
options: {
152-
// Disables tags and attributes processing
98+
// Disables attributes processing
15399
attributes: false,
154100
},
155101
},
@@ -158,33 +104,9 @@ module.exports = {
158104
};
159105
```
160106

161-
#### `Array`
162-
163-
Allows you to specify which tags and attributes to process.
164-
Pass an array of `<tag>:<attribute>` or `:<attribute>` combinations.
165-
You can specify which tag-attribute combination should be processed by this loader via the query parameter `attributes`, for example:
166-
167-
**webpack.config.js**
168-
169-
```js
170-
module.exports = {
171-
module: {
172-
rules: [
173-
{
174-
test: /\.html$/i,
175-
loader: 'html-loader',
176-
options: {
177-
attributes: [':data-src', 'custom-elements:data-src'],
178-
},
179-
},
180-
],
181-
},
182-
};
183-
```
184-
185107
#### `Object`
186108

187-
Allows you to specify which tags and attributes to process, filter them and process sources starts with `/`.
109+
Allows you to specify which tags and attributes to process, filter them, filter urls and process sources starts with `/`.
188110
For example:
189111

190112
**webpack.config.js**
@@ -198,13 +120,54 @@ module.exports = {
198120
loader: 'html-loader',
199121
options: {
200122
attributes: {
201-
list: [':data-src', 'custom-elements:data-src'],
202-
filter: (attribute, value, resourcePath) => {
123+
list: [
124+
{
125+
tag: 'img',
126+
attribute: 'src',
127+
type: 'src',
128+
},
129+
{
130+
tag: 'img',
131+
attribute: 'srcset',
132+
type: 'srcset',
133+
},
134+
{
135+
tag: 'img',
136+
attribute: 'data-src',
137+
type: 'src',
138+
},
139+
{
140+
tag: 'img',
141+
attribute: 'data-srcset',
142+
type: 'srcset',
143+
},
144+
{
145+
tag: 'link',
146+
attribute: 'href',
147+
type: 'src',
148+
filter: (tag, attribute, attributes) => {
149+
if (!/stylesheet/i.test(attributes.rel)) {
150+
return false;
151+
}
152+
153+
if (
154+
attributes.type &&
155+
attributes.type.trim().toLowerCase() !== 'text/css'
156+
) {
157+
return false;
158+
}
159+
160+
return true;
161+
},
162+
},
163+
// More attributes
164+
],
165+
urlFilter: (attribute, value, resourcePath) => {
203166
// The `attribute` argument contains a name of the HTML attribute.
204167
// The `value` argument contains a value of the HTML attribute.
205168
// The `resourcePath` argument contains a path to the loaded HTML file.
206169

207-
if (value.includes('example')) {
170+
if (/example\.pdf$/.test(value)) {
208171
return false;
209172
}
210173

@@ -221,9 +184,11 @@ module.exports = {
221184

222185
#### `list`
223186

224-
Type: `String`
187+
Type: `Array`
225188
Default: https://github.com/webpack-contrib/html-loader#attributes
226189

190+
Allows to setup which tags and attributes to process and how, and the ability to filter some of them.
191+
227192
For example:
228193

229194
**webpack.config.js**
@@ -237,7 +202,66 @@ module.exports = {
237202
loader: 'html-loader',
238203
options: {
239204
attributes: {
240-
list: [':data-src', 'custom-elements:data-src'],
205+
list: [
206+
{
207+
// Tag name
208+
tag: 'img',
209+
// Attribute name
210+
attribute: 'src',
211+
// Type of processing, can be `src` or `scrset`
212+
type: 'src',
213+
},
214+
{
215+
// Tag name
216+
tag: 'img',
217+
// Attribute name
218+
attribute: 'srcset',
219+
// Type of processing, can be `src` or `scrset`
220+
type: 'srcset',
221+
},
222+
{
223+
tag: 'img',
224+
attribute: 'data-src',
225+
type: 'src',
226+
},
227+
{
228+
tag: 'img',
229+
attribute: 'data-srcset',
230+
type: 'srcset',
231+
},
232+
{
233+
// Tag name
234+
tag: 'link',
235+
// Attribute name
236+
attribute: 'href',
237+
// Type of processing, can be `src` or `scrset`
238+
type: 'src',
239+
// Allow to filter some attributes
240+
filter: (tag, attribute, attributes, resourcePath) => {
241+
// The `tag` argument contains a name of the HTML tag.
242+
// The `attribute` argument contains a name of the HTML attribute.
243+
// The `attributes` argument contains all attributes of the tag.
244+
// The `resourcePath` argument contains a path to the loaded HTML file.
245+
246+
if (/my-html\.html$/.test(resourcePath)) {
247+
return false;
248+
}
249+
250+
if (!/stylesheet/i.test(attributes.rel)) {
251+
return false;
252+
}
253+
254+
if (
255+
attributes.type &&
256+
attributes.type.trim().toLowerCase() !== 'text/css'
257+
) {
258+
return false;
259+
}
260+
261+
return true;
262+
},
263+
},
264+
],
241265
},
242266
},
243267
},
@@ -246,12 +270,12 @@ module.exports = {
246270
};
247271
```
248272

249-
#### `filter`
273+
#### `urlFilter`
250274

251275
Type: `Function`
252276
Default: `undefined`
253277

254-
Allow to filter sources. All filtered sources will not be resolved (left in the code as they were written).
278+
Allow to filter urls. All filtered urls will not be resolved (left in the code as they were written).
255279
All non requestable sources (for example `<img src="javascript:void(0)">`) do not handle by default.
256280

257281
```js
@@ -263,12 +287,12 @@ module.exports = {
263287
loader: 'html-loader',
264288
options: {
265289
attributes: {
266-
filter: (attribute, value, resourcePath) => {
290+
urlFilter: (attribute, value, resourcePath) => {
267291
// The `attribute` argument contains a name of the HTML attribute.
268292
// The `value` argument contains a value of the HTML attribute.
269293
// The `resourcePath` argument contains a path to the loaded HTML file.
270294

271-
if (value.includes('example')) {
295+
if (/example\.pdf$/.test(value)) {
272296
return false;
273297
}
274298

@@ -310,6 +334,59 @@ module.exports = {
310334
};
311335
```
312336

337+
### `preprocessor`
338+
339+
Type: `Function`
340+
Default: `undefined`
341+
342+
Allows pre-processing of content before handling.
343+
344+
> ⚠ You should always return valid HTML
345+
346+
**file.hbs**
347+
348+
```hbs
349+
<div>
350+
<p>{{firstname}} {{lastname}}</p>
351+
<img src="image.png" alt="alt" />
352+
<div>
353+
```
354+
355+
**webpack.config.js**
356+
357+
```js
358+
const Handlebars = require('handlebars');
359+
360+
module.exports = {
361+
module: {
362+
rules: [
363+
{
364+
test: /\.hbs$/i,
365+
loader: 'html-loader',
366+
options: {
367+
preprocessor: (content, loaderContext) => {
368+
let result;
369+
370+
try {
371+
result = Handlebars.compile(content)({
372+
firstname: 'Value',
373+
lastname: 'OtherValue',
374+
});
375+
} catch (error) {
376+
loaderContext.emitError(error);
377+
378+
return content;
379+
}
380+
381+
return result;
382+
},
383+
},
384+
},
385+
],
386+
},
387+
};
388+
```
389+
313390
### `minimize`
314391

315392
Type: `Boolean|Object`

0 commit comments

Comments
 (0)