diff --git a/README.md b/README.md index c950da29..63924576 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,40 @@ If your application includes many HTML Components or certain HTML Components are ### `url` +#### `{Boolean}` + +**webpack.config.js** +```js +{ + loader: 'html-loader', + options: { + url: false + } +} +``` + +#### `{RegExp}` + **webpack.config.js** ```js { loader: 'html-loader', options: { - url: // TODO add URL filter method (#158 && #159) + url: /filter/ + } +} +``` + +#### `{Function}` + +**webpack.config.js** +```js +{ + loader: 'html-loader', + options: { + url (url) { + return /filter/.test(url) + } } } ``` diff --git a/src/index.js b/src/index.js index de47b2bd..dfa5c61a 100644 --- a/src/index.js +++ b/src/index.js @@ -39,7 +39,7 @@ export default function loader(html, map, meta) { // HTML URL Plugin if (options.url) { - plugins.push(urls()); + plugins.push(urls(options)); } // HTML IMPORT Plugin @@ -49,7 +49,9 @@ export default function loader(html, map, meta) { // TODO(michael-ciniawsky) // aren't minified (options.template) (#160) - if (options.minimize) plugins.push(minifier()); + if (options.minimize) { + plugins.push(minifier()); + } // Reuse HTML AST (PostHTML AST) // (e.g posthtml-loader) to avoid HTML reparsing diff --git a/src/options.json b/src/options.json index 496efb4b..70ae501c 100644 --- a/src/options.json +++ b/src/options.json @@ -2,7 +2,12 @@ "type": "object", "properties": { "url": { - "type": "boolean" + "anyOf": [ + { "type": "string" }, + { "type": "boolean" }, + { "instanceof": "RegExp" }, + { "instanceof": "Function" } + ] }, "import": { "anyOf": [ diff --git a/src/plugins/url.js b/src/plugins/url.js index 7b981377..084d0d57 100644 --- a/src/plugins/url.js +++ b/src/plugins/url.js @@ -1,20 +1,31 @@ /* eslint-disable */ // External URL (Protocol URL) const URL = /^\w+:\/\//; -// TODO(michael-ciniawsky) -// extend with custom matchers -// e.g -// (`options.url.filter`) (#159) +// Attributes Matcher const ATTRS = [ { attrs: { src: true } }, { attrs: { href: true } }, { attrs: { srcset: true } }, ]; -// TODO(michael-ciniawsky) -// add filter method for urls (e.g `options.url.filter`) (#158) -const filter = (url) => { - return URL.test(url) || url.startsWith('//'); +const filter = (url, options) => { + if (URL.test(url)) { + return true; + } + + if (url.startsWith('//')) { + return true; + } + + if (options.url instanceof RegExp) { + return options.url.test(url); + } + + if (typeof options.url === 'function') { + return options.url(url); + } + + return false; }; export default function (options = {}) { @@ -30,7 +41,7 @@ export default function (options = {}) { } // Ignore external && filtered urls - if (filter(node.attrs.src)) { + if (filter(node.attrs.src, options)) { return node; } @@ -48,10 +59,11 @@ export default function (options = {}) { return node; } + // if (node.attrs.href) { // Ignore external && filtered urls - if (filter(node.attrs.href)) { + if (filter(node.attrs.href, options)) { return node; } @@ -72,7 +84,7 @@ export default function (options = {}) { // if (node.attrs.srcset) { // Ignore external && filtered urls - if (filter(node.attrs.srcset)) { + if (filter(node.attrs.srcset, options)) { return node; } diff --git a/test/fixtures/options/url/filter/fixture.html b/test/fixtures/options/url/filter/fixture.html new file mode 100644 index 00000000..fcaed8f8 --- /dev/null +++ b/test/fixtures/options/url/filter/fixture.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/options/url/filter/fixture.js b/test/fixtures/options/url/filter/fixture.js new file mode 100644 index 00000000..1e87a0d2 --- /dev/null +++ b/test/fixtures/options/url/filter/fixture.js @@ -0,0 +1,3 @@ +import html from './fixture.html'; + +export default html; diff --git a/test/options/__snapshots__/url.test.js.snap b/test/options/__snapshots__/url.test.js.snap index a95fa860..bf979700 100644 --- a/test/options/__snapshots__/url.test.js.snap +++ b/test/options/__snapshots__/url.test.js.snap @@ -1,6 +1,65 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Options url {Boolean} 1`] = ` +exports[`Options url {Boolean} - false 1`] = ` +"// HTML Imports + + +// HTML Exports + + +// HTML +export default \` + + + + HTML Loader + + + + + + + + + + + + + + + + + + + + ​ + + \\"Image\\" + + + + + + + + + + + +\`" +`; + +exports[`Options url {Boolean} - true - (default) 1`] = ` "// HTML Imports import HTML__URL__0 from './file.css'; import HTML__URL__1 from '/file.css'; @@ -71,3 +130,49 @@ export default \` \`" `; + +exports[`Options url {Function} 1`] = ` +"// HTML Imports +import HTML__URL__0 from './file.png'; +import HTML__URL__1 from '/file.png'; + + +// HTML Exports + + +// HTML +export default \` + + + + + + + + + +\`" +`; + +exports[`Options url {RegExp} 1`] = ` +"// HTML Imports +import HTML__URL__0 from './file.png'; +import HTML__URL__1 from '/file.png'; + + +// HTML Exports + + +// HTML +export default \` + + + + + + + + + +\`" +`; diff --git a/test/options/url.test.js b/test/options/url.test.js index f096ed44..513a23b1 100644 --- a/test/options/url.test.js +++ b/test/options/url.test.js @@ -5,7 +5,7 @@ import webpack from '../helpers/compiler'; describe('Options', () => { describe('url', () => { - test('{Boolean}', async () => { + test('{Boolean} - true - (default)', async () => { const config = { loader: { test: /\.html$/, @@ -18,5 +18,55 @@ describe('Options', () => { expect(source).toMatchSnapshot(); }); + + test('{Boolean} - false', async () => { + const config = { + loader: { + test: /\.html$/, + options: { + url: false, + }, + }, + }; + + const stats = await webpack('options/url/fixture.js', config); + const { source } = stats.toJson().modules[1]; + + expect(source).toMatchSnapshot(); + }); + + test('{RegExp}', async () => { + const config = { + loader: { + test: /\.html$/, + options: { + url: /filter/, + }, + }, + }; + + const stats = await webpack('options/url/filter/fixture.js', config); + const { source } = stats.toJson().modules[1]; + + expect(source).toMatchSnapshot(); + }); + + test('{Function}', async () => { + const config = { + loader: { + test: /\.html$/, + options: { + url(url) { + return /filter/.test(url); + }, + }, + }, + }; + + const stats = await webpack('options/url/filter/fixture.js', config); + const { source } = stats.toJson().modules[1]; + + expect(source).toMatchSnapshot(); + }); }); });