Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,32 @@ module.exports = {

## Examples

### Disable url resolving using the `<!-- webpackIgnore: true -->` comment

With `<!-- webpackIgnore: true -->` comment, can to disable sources handling for next tag.

```html
<!-- Disabled url handling for the src attribute -->
<!-- webpackIgnore: true -->
<img src="image.png" />

<!-- Disabled url handling for the src and srcset attributes -->
<!-- webpackIgnore: true -->
<img
srcset="image.png 480w, image.png 768w"
src="image.png"
alt="Elva dressed as a fairy"
/>

<!-- Disabled url handling for the content attribute -->
<!-- webpackIgnore: true -->
<meta itemprop="image" content="./image.png" />

<!-- Disabled url handling for the href attribute -->
<!-- webpackIgnore: true -->
<link rel="icon" type="image/png" sizes="192x192" href="./image.png" />
```

### roots

With [`resolve.roots`](https://webpack.js.org/configuration/resolve/#resolveroots) can specify a list of directories where requests of server-relative URLs (starting with '/') are resolved.
Expand Down
13 changes: 13 additions & 0 deletions src/plugins/sources-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,33 @@ import {
normalizeUrl,
requestify,
stringifyRequest,
isWebpackIgnoreComment,
} from '../utils';

export default (options) =>
function process(html) {
const sources = [];
const document = parse5.parse(html, { sourceCodeLocationInfo: true });

let webpackIgnore = false;

traverse(document, (node) => {
const { tagName, attrs: attributes, sourceCodeLocation } = node;

if (isWebpackIgnoreComment(node)) {
webpackIgnore = true;
return;
}

if (!tagName) {
return;
}

if (webpackIgnore) {
webpackIgnore = false;
return;
}

attributes.forEach((attribute) => {
let { name } = attribute;

Expand Down
10 changes: 10 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,13 @@ export function c0ControlCodesExclude(source) {

return { value, startOffset };
}

const webpackIgnoreCommentRegexp = /webpackIgnore:(\s+)?true/;

export function isWebpackIgnoreComment(node) {
if (node.nodeName !== '#comment') {
return false;
}

return webpackIgnoreCommentRegexp.test(node.data);
}
87 changes: 87 additions & 0 deletions test/__snapshots__/loader.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,93 @@ exports[`loader should work with server-relative url: result 1`] = `

exports[`loader should work with server-relative url: warnings 1`] = `Array []`;

exports[`loader should work with webpackIgnore comment: errors 1`] = `Array []`;

exports[`loader should work with webpackIgnore comment: module 1`] = `
"// Module
var code = \\"<!doctype html>\\\\n<html lang=\\\\\\"en\\\\\\">\\\\n<head>\\\\n <meta charset=\\\\\\"UTF-8\\\\\\">\\\\n <meta name=\\\\\\"viewport\\\\\\"\\\\n content=\\\\\\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\\\\\\">\\\\n <meta http-equiv=\\\\\\"X-UA-Compatible\\\\\\" content=\\\\\\"ie=edge\\\\\\">\\\\n <title>Document</title>\\\\n</head>\\\\n<body>\\\\n\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<img src=\\\\\\"image.png\\\\\\" />\\\\n<!-- webpackIgnore: true --> <img src=\\\\\\"image.png\\\\\\" />\\\\n<!-- webpackIgnore: true -->\\\\n<img srcset=\\\\\\"image.png 480w, image.png 768w\\\\\\" src=\\\\\\"image.png\\\\\\" alt=\\\\\\"Elva dressed as a fairy\\\\\\">\\\\n<!-- webpackIgnore: true -->\\\\n<img data-srcset=\\\\\\"image.png 480w, image.png 800w\\\\\\" sizes=\\\\\\"(max-width: 600px) 480px, 800px\\\\\\" data-src=\\\\\\"image.png\\\\\\" alt=\\\\\\"Elva dressed as a fairy\\\\\\">\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<meta itemprop=\\\\\\"image\\\\\\" content=\\\\\\"./image.png\\\\\\" />\\\\n<!-- webpackIgnore: true -->\\\\n<meta itemprop=\\\\\\"logo\\\\\\" content=\\\\\\"./image.png\\\\\\" />\\\\n<!-- webpackIgnore: true -->\\\\n<meta itemprop=\\\\\\"screenshot\\\\\\" content=\\\\\\"./image.png\\\\\\" />\\\\n<!-- webpackIgnore: true -->\\\\n<meta property=\\\\\\"og:audio\\\\\\" content=\\\\\\"./sound.mp3\\\\\\" />\\\\n<!-- webpackIgnore: true -->\\\\n<meta property=\\\\\\"og:audio:secure_url\\\\\\" content=\\\\\\"./sound.mp3\\\\\\" />\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<link itemprop=\\\\\\"downloadUrl\\\\\\" href=\\\\\\"image.png\\\\\\">\\\\n<!-- webpackIgnore: true -->\\\\n<link itemprop=\\\\\\"contentUrl\\\\\\" href=\\\\\\"image.png\\\\\\">\\\\n<!-- webpackIgnore: true -->\\\\n<link itemprop=\\\\\\"installUrl\\\\\\" href=\\\\\\"image.png\\\\\\">\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<link rel=\\\\\\"icon\\\\\\" type=\\\\\\"image/png\\\\\\" sizes=\\\\\\"192x192\\\\\\" href=\\\\\\"./image.png\\\\\\">\\\\n<!-- webpackIgnore: true -->\\\\n<link rel=\\\\\\"apple-touch-icon\\\\\\" href=\\\\\\"./image.png\\\\\\">\\\\n<!-- webpackIgnore: true -->\\\\n<link rel=\\\\\\"manifest\\\\\\" href=\\\\\\"./site.webmanifest\\\\\\">\\\\n\\\\n<svg width=\\\\\\"200\\\\\\" height=\\\\\\"200\\\\\\">\\\\n <!-- webpackIgnore: true -->\\\\n <image xlink:href=\\\\\\"./webpack.svg\\\\\\" height=\\\\\\"200\\\\\\" width=\\\\\\"200\\\\\\"/>\\\\n</svg>\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<div data-videomp4=\\\\\\"video.mp4\\\\\\"></div>\\\\n\\\\n<!-- webpackIgnore: true -->\\\\n<video controls poster=\\\\\\"./image.png\\\\\\">\\\\n <!-- webpackIgnore: true -->\\\\n <source src=\\\\\\"example.ogg\\\\\\" type=\\\\\\"video/ogg\\\\\\">\\\\n <!-- webpackIgnore: true -->\\\\n <track src=\\\\\\"example.vtt\\\\\\" kind=\\\\\\"subtitles\\\\\\" srclang=\\\\\\"en\\\\\\" label=\\\\\\"English\\\\\\">\\\\n</video>\\\\n\\\\n<picture>\\\\n <!-- webpackIgnore: true -->\\\\n <source media=\\\\\\"(min-width: 650px)\\\\\\" srcset=\\\\\\"image.png\\\\\\">\\\\n <!-- webpackIgnore: true -->\\\\n <source media=\\\\\\"(min-width: 465px)\\\\\\" srcset=\\\\\\"image.png\\\\\\">\\\\n <!-- webpackIgnore: true -->\\\\n <img src=\\\\\\"image.png\\\\\\" alt=\\\\\\"Flowers\\\\\\" style=\\\\\\"width:auto;\\\\\\">\\\\n</picture>\\\\n\\\\n\\\\n</body>\\\\n</html>\\";
// Exports
export default code;"
`;

exports[`loader should work with webpackIgnore comment: result 1`] = `
"<!doctype html>
<html lang=\\"en\\">
<head>
<meta charset=\\"UTF-8\\">
<meta name=\\"viewport\\"
content=\\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\\">
<meta http-equiv=\\"X-UA-Compatible\\" content=\\"ie=edge\\">
<title>Document</title>
</head>
<body>


<!-- webpackIgnore: true -->
<img src=\\"image.png\\" />
<!-- webpackIgnore: true --> <img src=\\"image.png\\" />
<!-- webpackIgnore: true -->
<img srcset=\\"image.png 480w, image.png 768w\\" src=\\"image.png\\" alt=\\"Elva dressed as a fairy\\">
<!-- webpackIgnore: true -->
<img data-srcset=\\"image.png 480w, image.png 800w\\" sizes=\\"(max-width: 600px) 480px, 800px\\" data-src=\\"image.png\\" alt=\\"Elva dressed as a fairy\\">

<!-- webpackIgnore: true -->
<meta itemprop=\\"image\\" content=\\"./image.png\\" />
<!-- webpackIgnore: true -->
<meta itemprop=\\"logo\\" content=\\"./image.png\\" />
<!-- webpackIgnore: true -->
<meta itemprop=\\"screenshot\\" content=\\"./image.png\\" />
<!-- webpackIgnore: true -->
<meta property=\\"og:audio\\" content=\\"./sound.mp3\\" />
<!-- webpackIgnore: true -->
<meta property=\\"og:audio:secure_url\\" content=\\"./sound.mp3\\" />

<!-- webpackIgnore: true -->
<link itemprop=\\"downloadUrl\\" href=\\"image.png\\">
<!-- webpackIgnore: true -->
<link itemprop=\\"contentUrl\\" href=\\"image.png\\">
<!-- webpackIgnore: true -->
<link itemprop=\\"installUrl\\" href=\\"image.png\\">

<!-- webpackIgnore: true -->
<link rel=\\"icon\\" type=\\"image/png\\" sizes=\\"192x192\\" href=\\"./image.png\\">
<!-- webpackIgnore: true -->
<link rel=\\"apple-touch-icon\\" href=\\"./image.png\\">
<!-- webpackIgnore: true -->
<link rel=\\"manifest\\" href=\\"./site.webmanifest\\">

<svg width=\\"200\\" height=\\"200\\">
<!-- webpackIgnore: true -->
<image xlink:href=\\"./webpack.svg\\" height=\\"200\\" width=\\"200\\"/>
</svg>

<!-- webpackIgnore: true -->
<div data-videomp4=\\"video.mp4\\"></div>

<!-- webpackIgnore: true -->
<video controls poster=\\"./image.png\\">
<!-- webpackIgnore: true -->
<source src=\\"example.ogg\\" type=\\"video/ogg\\">
<!-- webpackIgnore: true -->
<track src=\\"example.vtt\\" kind=\\"subtitles\\" srclang=\\"en\\" label=\\"English\\">
</video>

<picture>
<!-- webpackIgnore: true -->
<source media=\\"(min-width: 650px)\\" srcset=\\"image.png\\">
<!-- webpackIgnore: true -->
<source media=\\"(min-width: 465px)\\" srcset=\\"image.png\\">
<!-- webpackIgnore: true -->
<img src=\\"image.png\\" alt=\\"Flowers\\" style=\\"width:auto;\\">
</picture>


</body>
</html>"
`;

exports[`loader should work with webpackIgnore comment: warnings 1`] = `Array []`;

exports[`loader should work: errors 1`] = `Array []`;

exports[`loader should work: module 1`] = `
Expand Down
73 changes: 73 additions & 0 deletions test/fixtures/webpackIgnore.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>


<!-- webpackIgnore: true -->
<img src="image.png" />
<!-- webpackIgnore: true --> <img src="image.png" />
<!-- webpackIgnore: true -->
<img srcset="image.png 480w, image.png 768w" src="image.png" alt="Elva dressed as a fairy">
<!-- webpackIgnore: true -->
<img data-srcset="image.png 480w, image.png 800w" sizes="(max-width: 600px) 480px, 800px" data-src="image.png" alt="Elva dressed as a fairy">

<!-- webpackIgnore: true -->
<meta itemprop="image" content="./image.png" />
<!-- webpackIgnore: true -->
<meta itemprop="logo" content="./image.png" />
<!-- webpackIgnore: true -->
<meta itemprop="screenshot" content="./image.png" />
<!-- webpackIgnore: true -->
<meta property="og:audio" content="./sound.mp3" />
<!-- webpackIgnore: true -->
<meta property="og:audio:secure_url" content="./sound.mp3" />

<!-- webpackIgnore: true -->
<link itemprop="downloadUrl" href="image.png">
<!-- webpackIgnore: true -->
<link itemprop="contentUrl" href="image.png">
<!-- webpackIgnore: true -->
<link itemprop="installUrl" href="image.png">

<!-- webpackIgnore: true -->
<link rel="icon" type="image/png" sizes="192x192" href="./image.png">
<!-- webpackIgnore: true -->
<link rel="apple-touch-icon" href="./image.png">
<!-- webpackIgnore: true -->
<link rel="manifest" href="./site.webmanifest">

<svg width="200" height="200">
<!-- webpackIgnore: true -->
<image xlink:href="./webpack.svg" height="200" width="200"/>
</svg>

<!-- webpackIgnore: true -->
<div data-videomp4="video.mp4"></div>

<!-- webpackIgnore: true -->
<video controls poster="./image.png">
<!-- webpackIgnore: true -->
<source src="example.ogg" type="video/ogg">
<!-- webpackIgnore: true -->
<track src="example.vtt" kind="subtitles" srclang="en" label="English">
</video>

<picture>
<!-- webpackIgnore: true -->
<source media="(min-width: 650px)" srcset="image.png">
<!-- webpackIgnore: true -->
<source media="(min-width: 465px)" srcset="image.png">
<!-- webpackIgnore: true -->
<img src="image.png" alt="Flowers" style="width:auto;">
</picture>


</body>
</html>
3 changes: 3 additions & 0 deletions test/fixtures/webpackIgnore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import html from './webpackIgnore.html';

export default html;
14 changes: 14 additions & 0 deletions test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,18 @@ describe('loader', () => {
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with webpackIgnore comment', async () => {
const compiler = getCompiler('webpackIgnore.js');
const stats = await compile(compiler);

expect(getModuleSource('./webpackIgnore.html', stats)).toMatchSnapshot(
'module'
);
expect(
execute(readAsset('main.bundle.js', compiler, stats))
).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});