Skip to content

Commit d17f912

Browse files
refactor: remove the require value for the interpolate option (#235)
BREAKING CHANGE: the `require` value for the `interpolation` option was removed with replacement, please use `raw-loader`, the special loader for syntax (for example - `ejs-loader`) or template literal for that. Non standard HTML syntax potential can be broken by minimizer, parser can throw an error in some cases.
1 parent 60c6f1d commit d17f912

File tree

7 files changed

+10
-112
lines changed

7 files changed

+10
-112
lines changed

README.md

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module.exports = {
4848
};
4949
```
5050

51-
By default every local `<img src="image.png">` is required (`require('./image.png')`).
51+
By default every loadable attributes (for example - `<img src="image.png">`) is imported (`const img = require('./image.png')` or `import img from "./image.png""`).
5252
You may need to specify loaders for images in your configuration (recommended `file-loader` or `url-loader`).
5353

5454
## Options
@@ -57,7 +57,7 @@ You may need to specify loaders for images in your configuration (recommended `f
5757
| :-------------------------------: | :-----------------: | :-------------------------------------------------------------------------------------------------------------------: | :--------------------------------------- |
5858
| **[`attributes`](#attributes)** | `{Boolean\/Array}` | `[':srcset', 'img:src', 'audio:src', 'video:src', 'track:src', 'embed:src', 'source:src','input:src', 'object:data']` | Enables/Disables attributes handling |
5959
| **[`root`](#root)** | `{String}` | `undefiend` | Allow to handle root-relative attributes |
60-
| **[`interpolate`](#interpolate)** | `{Boolean\|String}` | `false` | Allow to use expressions in HTML syntax |
60+
| **[`interpolate`](#interpolate)** | `{Boolean}` | `false` | Allow to use expressions in HTML syntax |
6161
| **[`minimize`](#minimize)** | `{Boolean\|Object}` | `true` in production mode, otherwise `false` | Tell `html-loader` to minimize HTML |
6262
| **[`esModule`](#esmodule)** | `{Boolean}` | `false` | Use ES modules syntax |
6363

@@ -147,22 +147,20 @@ Type: `Boolean|String`
147147
Default: `false`
148148

149149
Allow to use expressions in HTML syntax.
150-
151-
#### `Boolean`
152-
153150
You can use `interpolate` flag to enable interpolation syntax for ES6 template strings, like so:
154151

155152
```js
156153
require('html-loader?interpolate!./file.html');
157154
```
158155

159156
```html
160-
<img src="${require(`./images/gallery.png`)}" />
157+
<img src="${require(`./images/gallery.png`).default}" />
161158

162-
<div>${require('./components/gallery.html')}</div>
159+
<div>${require('./components/gallery.html').default}</div>
163160
```
164161

165-
#### `Boolean`
162+
> ⚠ By default `file-loader` or `url-loader` use ES module syntax so you need use the `default` property.
163+
> You should not use the `default` property if you setup the `esModule` option to `false` value for `file-loader` or `url-loader`.
166164
167165
**webpack.config.js**
168166

@@ -182,40 +180,6 @@ module.exports = {
182180
};
183181
```
184182

185-
#### `String`
186-
187-
If you only want to use `require` in template and any other `${}` are not to be translated, you can set `interpolate` flag to `require`, like so:
188-
189-
**webpack.config.js**
190-
191-
```js
192-
module.exports = {
193-
module: {
194-
rules: [
195-
{
196-
test: /\.html$/i,
197-
loader: 'html-loader',
198-
options: {
199-
interpolate: 'require',
200-
},
201-
},
202-
],
203-
},
204-
};
205-
```
206-
207-
This may be useful for template syntaxes. For example:
208-
209-
```html
210-
<#list list as list>
211-
<a href="${list.href!}" />${list.name}</a>
212-
</#list>
213-
214-
<img src="${require(`./images/gallery.png`)}">
215-
216-
<div>${require('./components/gallery.html')}</div>
217-
```
218-
219183
### `minimize`
220184

221185
Type: `Boolean|Object`

src/index.js

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import {
1616

1717
import schema from './options.json';
1818

19-
const REQUIRE_REGEX = /\${require\([^)]*\)}/g;
20-
2119
export const raw = true;
2220

2321
export default function htmlLoader(source) {
@@ -55,31 +53,6 @@ export default function htmlLoader(source) {
5553
}
5654
}
5755

58-
if (options.interpolate === 'require') {
59-
const reqList = [];
60-
61-
let result = REQUIRE_REGEX.exec(content);
62-
while (result) {
63-
reqList.push({
64-
length: result[0].length,
65-
start: result.index,
66-
value: result[0],
67-
});
68-
69-
result = REQUIRE_REGEX.exec(content);
70-
}
71-
72-
reqList.reverse();
73-
74-
for (const link of reqList) {
75-
const ident = getUniqueIdent(replacers);
76-
77-
replacers.set(ident, link.value.substring(11, link.length - 3));
78-
79-
content = replaceLinkWithIdent(content, link, ident);
80-
}
81-
}
82-
8356
const minimize =
8457
typeof options.minimize === 'undefined'
8558
? isProductionMode(this)
@@ -109,7 +82,7 @@ export default function htmlLoader(source) {
10982
}
11083
}
11184

112-
if (options.interpolate && options.interpolate !== 'require') {
85+
if (options.interpolate) {
11386
try {
11487
// Double escape quotes so that they are not unescaped completely in the template string
11588
content = compile(

src/options.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"type": "string"
1717
},
1818
"interpolate": {
19-
"anyOf": [{ "type": "boolean" }, { "type": "string" }]
19+
"anyOf": [{ "type": "boolean" }]
2020
},
2121
"minimize": {
2222
"anyOf": [{ "type": "boolean" }, { "type": "object" }]

test/__snapshots__/interpolate-option.test.js.snap

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,3 @@ exports[`'interpolate' option should work with boolean notation: result 1`] = `
5858
`;
5959

6060
exports[`'interpolate' option should work with boolean notation: warnings 1`] = `Array []`;
61-
62-
exports[`'interpolate' option should work with the "require": errors 1`] = `Array []`;
63-
64-
exports[`'interpolate' option should work with the "require": module 1`] = `
65-
"// Imports
66-
var ___HTML_LOADER_GET_URL_IMPORT___ = require(\\"../../src/runtime/getUrl.js\\");
67-
var ___HTML_LOADER_IDENT_0___ = require(\\"./image.png\\");
68-
// Exports
69-
module.exports = \\"<img src=\\\\\\"\${\\\\\\"Hello \\\\\\" + (1+1)}\\\\\\">\\\\n<img src=\\\\\\"\${\`Hello \` + (1+1)}\\\\\\">\\\\n<p>Something about the \\\\\\\\\` character</p>\\\\n<script>{\\\\\\"json\\\\\\": \\\\\\"with \\\\\\\\\\\\\\"quotes\\\\\\\\\\\\\\" in value\\\\\\"}</script>\\\\n<h3>#{number} {customer}</h3>\\\\n<p> {title} </p>\\\\n<img src=\\\\\\"\\" + ___HTML_LOADER_GET_URL_IMPORT___(___HTML_LOADER_IDENT_0___) + \\"\\\\\\" /></a>\\\\n\\";"
70-
`;
71-
72-
exports[`'interpolate' option should work with the "require": result 1`] = `
73-
"<img src=\\"\${\\"Hello \\" + (1+1)}\\">
74-
<img src=\\"\${\`Hello \` + (1+1)}\\">
75-
<p>Something about the \\\\\` character</p>
76-
<script>{\\"json\\": \\"with \\\\\\"quotes\\\\\\" in value\\"}</script>
77-
<h3>#{number} {customer}</h3>
78-
<p> {title} </p>
79-
<img src=\\"/webpack/public/path/image.png\\" /></a>
80-
"
81-
`;
82-
83-
exports[`'interpolate' option should work with the "require": warnings 1`] = `Array []`;

test/__snapshots__/validate-options.test.js.snap

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ exports[`validate options should throw an error on the "esModule" option with "t
1717

1818
exports[`validate options should throw an error on the "interpolate" option with "1" value 1`] = `
1919
"Invalid options object. HTML Loader has been initialized using an options object that does not match the API schema.
20-
- options.interpolate should be one of these:
21-
boolean | string
22-
Details:
23-
* options.interpolate should be a boolean.
24-
* options.interpolate should be a string."
20+
- options.interpolate should be a boolean."
2521
`;
2622

2723
exports[`validate options should throw an error on the "root" option with "true" value 1`] = `

test/interpolate-option.test.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,6 @@ describe("'interpolate' option", () => {
3333
expect(getErrors(stats)).toMatchSnapshot('errors');
3434
});
3535

36-
it('should work with the "require"', async () => {
37-
const compiler = getCompiler('template.js', { interpolate: 'require' });
38-
const stats = await compile(compiler);
39-
40-
expect(getModuleSource('./template.html', stats)).toMatchSnapshot('module');
41-
expect(
42-
execute(readAsset('main.bundle.js', compiler, stats))
43-
).toMatchSnapshot('result');
44-
expect(getWarnings(stats)).toMatchSnapshot('warnings');
45-
expect(getErrors(stats)).toMatchSnapshot('errors');
46-
});
47-
4836
it('should emit an error on broken interpolation syntax', async () => {
4937
const compiler = getCompiler('broken-interpolation-syntax.js', {
5038
interpolate: true,

test/validate-options.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('validate options', () => {
1313
failure: [true],
1414
},
1515
interpolate: {
16-
success: [false /* true */, 'require'],
16+
success: [false /* true */],
1717
failure: [1],
1818
},
1919
esModule: {

0 commit comments

Comments
 (0)