Skip to content

Commit

Permalink
feat: preprocessor option (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Mar 18, 2020
1 parent f2ce5b1 commit 8c73761
Show file tree
Hide file tree
Showing 18 changed files with 441 additions and 45 deletions.
159 changes: 153 additions & 6 deletions README.md
Expand Up @@ -50,12 +50,66 @@ module.exports = {

## Options

| Name | Type | Default | Description |
| :-----------------------------: | :------------------------: | :------------------------------------------: | :--------------------------------------- |
| **[`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 |
| 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;
},
},
},
],
},
};
```

### `attributes`

Expand Down Expand Up @@ -501,6 +555,99 @@ require('html-loader?root=.!./file.html');
// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg">'
```

### Templating

You can use any template system. Below is an example for [handlebars](https://handlebarsjs.com/).

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

### PostHTML

You can use [PostHTML](https://github.com/posthtml/posthtml) without any additional loaders.

**file.html**

```html
<img src="image.jpg" />
```

**webpack.config.js**

```js
const posthtml = require('posthtml');
const posthtmlWebp = require('posthtml-webp');

module.exports = {
module: {
rules: [
{
test: /\.hbs$/i,
loader: 'html-loader',
options: {
preprocessor: () => {
let result;

try {
result = posthtml()
.use(plugin)
.process(content, { sync: true });
} catch (error) {
loaderContext.emitError(error);

return content;
}

return result.html;
},
},
},
],
},
};
```

### Export into HTML files

A very common scenario is exporting the HTML into their own _.html_ file, to
Expand Down
92 changes: 92 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -67,12 +67,15 @@
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.20.1",
"file-loader": "^6.0.0",
"handlebars": "^4.7.3",
"husky": "^4.2.3",
"jest": "^25.1.0",
"jest-junit": "^10.0.0",
"lint-staged": "^10.0.8",
"memfs": "^3.1.2",
"npm-run-all": "^4.1.5",
"posthtml": "^0.12.0",
"posthtml-webp": "^1.5.0",
"prettier": "^1.19.1",
"standard-version": "^7.1.0",
"webpack": "^4.42.0"
Expand Down
14 changes: 13 additions & 1 deletion src/index.js
Expand Up @@ -21,6 +21,11 @@ export default function htmlLoader(content) {
baseDataPath: 'options',
});

if (options.preprocessor) {
// eslint-disable-next-line no-param-reassign
content = options.preprocessor(content, this);
}

const plugins = [];

const attributes =
Expand Down Expand Up @@ -70,5 +75,12 @@ export default function htmlLoader(content) {
const moduleCode = getModuleCode(html, replaceableMessages, codeOptions);
const exportCode = getExportCode(html, exportedMessages, codeOptions);

return `${importCode}${moduleCode}${exportCode}`;
let code = `${importCode}${moduleCode}${exportCode}`;

if (options.process && options.process.post) {
// eslint-disable-next-line no-param-reassign
code = options.process.post(code, this);
}

return code;
}
3 changes: 3 additions & 0 deletions src/options.json
@@ -1,6 +1,9 @@
{
"type": "object",
"properties": {
"preprocessor": {
"instanceof": "Function"
},
"attributes": {
"anyOf": [
{ "type": "boolean" },
Expand Down
2 changes: 1 addition & 1 deletion src/utils.js
Expand Up @@ -94,5 +94,5 @@ export function getExportCode(html, exportedMessages, codeOptions) {
return `// Exports\nexport default code;`;
}

return `// Exports\nmodule.exports = code`;
return `// Exports\nmodule.exports = code;`;
}
22 changes: 11 additions & 11 deletions test/__snapshots__/attributes-option.test.js.snap

Large diffs are not rendered by default.

0 comments on commit 8c73761

Please sign in to comment.