Skip to content

Commit

Permalink
refactor: attributes option (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Mar 19, 2020
1 parent 8c73761 commit 3c9a1d8
Show file tree
Hide file tree
Showing 12 changed files with 605 additions and 1,247 deletions.
269 changes: 173 additions & 96 deletions README.md
Expand Up @@ -50,70 +50,16 @@ module.exports = {

## Options

| Name | Type | Default | Description |
| :---------------------------------: | :------------------------: | :------------------------------------------: | :----------------------------------------------- |
| **[`preprocessor`](#preprocessor)** | `{Function}` | `undefined` | Allows pre-processing of content before handling |
| **[`attributes`](#attributes)** | `{Boolean\/Array\/Object}` | `true` | Enables/Disables attributes handling |
| **[`root`](#root)** | `{String}` | `undefiend` | Allow to handle root-relative attributes |
| **[`minimize`](#minimize)** | `{Boolean\|Object}` | `true` in production mode, otherwise `false` | Tell `html-loader` to minimize HTML |
| **[`esModule`](#esmodule)** | `{Boolean}` | `false` | Use ES modules syntax |

### `preprocessor`

Type: `Function`
Default: `undefined`

Allows pre-processing of content before handling.

> ⚠ You should always return valid HTML
**file.hbs**

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

**webpack.config.js**

```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;
},
},
},
],
},
};
```
| Name | Type | Default | Description |
| :---------------------------------: | :-----------------: | :------------------------------------------: | :----------------------------------------------- |
| **[`attributes`](#attributes)** | `{Boolean\|Object}` | `true` | Enables/Disables attributes handling |
| **[`preprocessor`](#preprocessor)** | `{Function}` | `undefined` | Allows pre-processing of content before handling |
| **[`minimize`](#minimize)** | `{Boolean\|Object}` | `true` in production mode, otherwise `false` | Tell `html-loader` to minimize HTML |
| **[`esModule`](#esmodule)** | `{Boolean}` | `false` | Use ES modules syntax |

### `attributes`

Type: `Boolean|Array|Object`
Type: `Boolean|Object`
Default: `true`

By default every loadable attributes (for example - `<img src="image.png">`) is imported (`const img = require('./image.png')` or `import img from "./image.png""`).
Expand Down Expand Up @@ -149,7 +95,7 @@ module.exports = {
test: /\.html$/i,
loader: 'html-loader',
options: {
// Disables tags and attributes processing
// Disables attributes processing
attributes: false,
},
},
Expand All @@ -158,33 +104,9 @@ module.exports = {
};
```

#### `Array`

Allows you to specify which tags and attributes to process.
Pass an array of `<tag>:<attribute>` or `:<attribute>` combinations.
You can specify which tag-attribute combination should be processed by this loader via the query parameter `attributes`, for example:

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
options: {
attributes: [':data-src', 'custom-elements:data-src'],
},
},
],
},
};
```

#### `Object`

Allows you to specify which tags and attributes to process, filter them and process sources starts with `/`.
Allows you to specify which tags and attributes to process, filter them, filter urls and process sources starts with `/`.
For example:

**webpack.config.js**
Expand All @@ -198,13 +120,54 @@ module.exports = {
loader: 'html-loader',
options: {
attributes: {
list: [':data-src', 'custom-elements:data-src'],
filter: (attribute, value, resourcePath) => {
list: [
{
tag: 'img',
attribute: 'src',
type: 'src',
},
{
tag: 'img',
attribute: 'srcset',
type: 'srcset',
},
{
tag: 'img',
attribute: 'data-src',
type: 'src',
},
{
tag: 'img',
attribute: 'data-srcset',
type: 'srcset',
},
{
tag: 'link',
attribute: 'href',
type: 'src',
filter: (tag, attribute, attributes) => {
if (!/stylesheet/i.test(attributes.rel)) {
return false;
}

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

return true;
},
},
// More attributes
],
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 (value.includes('example')) {
if (/example\.pdf$/.test(value)) {
return false;
}

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

#### `list`

Type: `String`
Type: `Array`
Default: https://github.com/webpack-contrib/html-loader#attributes

Allows to setup which tags and attributes to process and how, and the ability to filter some of them.

For example:

**webpack.config.js**
Expand All @@ -237,7 +202,66 @@ module.exports = {
loader: 'html-loader',
options: {
attributes: {
list: [':data-src', 'custom-elements:data-src'],
list: [
{
// Tag name
tag: 'img',
// Attribute name
attribute: 'src',
// Type of processing, can be `src` or `scrset`
type: 'src',
},
{
// Tag name
tag: 'img',
// Attribute name
attribute: 'srcset',
// Type of processing, can be `src` or `scrset`
type: 'srcset',
},
{
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;
},
},
],
},
},
},
Expand All @@ -246,12 +270,12 @@ module.exports = {
};
```

#### `filter`
#### `urlFilter`

Type: `Function`
Default: `undefined`

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

```js
Expand All @@ -263,12 +287,12 @@ module.exports = {
loader: 'html-loader',
options: {
attributes: {
filter: (attribute, value, resourcePath) => {
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 (value.includes('example')) {
if (/example\.pdf$/.test(value)) {
return false;
}

Expand Down Expand Up @@ -310,6 +334,59 @@ module.exports = {
};
```

### `preprocessor`

Type: `Function`
Default: `undefined`

Allows pre-processing of content before handling.

> ⚠ You should always return valid HTML
**file.hbs**

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

**webpack.config.js**

```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;
},
},
},
],
},
};
```

### `minimize`

Type: `Boolean|Object`
Expand Down

0 comments on commit 3c9a1d8

Please sign in to comment.