Skip to content

Commit 2152535

Browse files
feat: issue 1256
1 parent 28fb950 commit 2152535

15 files changed

+3016
-31
lines changed

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,38 @@ module.exports = {
11321132

11331133
## Examples
11341134

1135+
### Disabling sources resolving using the `/* webpackIgnore: true */` comment
1136+
1137+
With the help of the `/* webpackIgnore: true */`comment, it is possible to disable sources handling for rules and for individual declarations.
1138+
1139+
```css
1140+
/* webpackIgnore: true*/
1141+
@import url(./basic.css);
1142+
@import /* webpackIgnore: true */ url(./imported.css);
1143+
1144+
/** webpackIgnore: true */
1145+
.class {
1146+
color: red;
1147+
background: url("./url/img.png");
1148+
}
1149+
1150+
.class {
1151+
color: red;
1152+
background: /** webpackIgnore: true */ url("./url/img.png");
1153+
}
1154+
1155+
.class {
1156+
background-image: image-set(
1157+
url(./url/img.png) 2x,
1158+
url(./url/img.png) 3x,
1159+
/*webpackIgnore: true*/ url(./url/img.png) 4x,
1160+
url(./url/img.png) 5x,
1161+
url(./url/img.png) 6x,
1162+
/*webpackIgnore: true*/ url(./url/img.png) 7x
1163+
);
1164+
}
1165+
```
1166+
11351167
### Assets
11361168

11371169
The following `webpack.config.js` can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory.

package-lock.json

+1-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/postcss-import-parser.js

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
resolveRequests,
66
isUrlRequestable,
77
requestify,
8+
isWebpackIgnoreSource,
89
} from "../utils";
910

1011
function visitor(result, parsedResults, node, key) {
@@ -96,6 +97,10 @@ const plugin = (options = {}) => {
9697
for (const parsedResult of parsedResults) {
9798
const { node, url, isStringValue, mediaNodes } = parsedResult;
9899

100+
if (isWebpackIgnoreSource(node)) {
101+
return;
102+
}
103+
99104
let normalizedUrl = url;
100105
let prefix = "";
101106

src/plugins/postcss-url-parser.js

+39-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
requestify,
66
resolveRequests,
77
isUrlRequestable,
8+
isWebpackIgnoreSource,
9+
webpackIgnoreRegexp,
810
} from "../utils";
911

1012
const isUrlFunc = /url/i;
@@ -35,13 +37,33 @@ function visitor(result, parsedResults, node, key) {
3537
return;
3638
}
3739

38-
const parsed = valueParser(node[key]);
40+
if (isWebpackIgnoreSource(node)) {
41+
return;
42+
}
43+
44+
const parsed = valueParser(
45+
typeof node.raws.value === "undefined" ? node[key] : node.raws.value.raw
46+
);
47+
48+
let webpackIgnore = false;
3949

4050
parsed.walk((valueNode) => {
51+
if (valueNode.type === "comment") {
52+
if (webpackIgnoreRegexp.test(valueNode.value)) {
53+
webpackIgnore = true;
54+
}
55+
return;
56+
}
57+
4158
if (valueNode.type !== "function") {
4259
return;
4360
}
4461

62+
if (webpackIgnore) {
63+
webpackIgnore = false;
64+
return;
65+
}
66+
4567
if (isUrlFunc.test(valueNode.value)) {
4668
const { nodes } = valueNode;
4769
const isStringValue = nodes.length !== 0 && nodes[0].type === "string";
@@ -62,10 +84,26 @@ function visitor(result, parsedResults, node, key) {
6284
// eslint-disable-next-line consistent-return
6385
return false;
6486
} else if (isImageSetFunc.test(valueNode.value)) {
87+
let imageSetWebpackIgnore = false;
88+
6589
for (const nNode of valueNode.nodes) {
6690
const { type, value } = nNode;
6791

92+
if (type === "comment") {
93+
if (webpackIgnoreRegexp.test(value)) {
94+
imageSetWebpackIgnore = true;
95+
}
96+
// eslint-disable-next-line no-continue
97+
continue;
98+
}
99+
68100
if (type === "function" && isUrlFunc.test(value)) {
101+
if (imageSetWebpackIgnore) {
102+
imageSetWebpackIgnore = false;
103+
// eslint-disable-next-line no-continue
104+
continue;
105+
}
106+
69107
const { nodes } = nNode;
70108
const isStringValue =
71109
nodes.length !== 0 && nodes[0].type === "string";

src/utils.js

+37
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const unescapeRegExp = new RegExp(
1919
"ig"
2020
);
2121
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
22+
const webpackIgnoreRegexp = /webpackIgnore:(\s+)?true/i;
2223

2324
function unescape(str) {
2425
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
@@ -702,6 +703,40 @@ function sort(a, b) {
702703
return a.index - b.index;
703704
}
704705

706+
function isWebpackIgnoreSource(node) {
707+
if (webpackIgnoreRegexp.test(node.raws.afterName)) {
708+
return true;
709+
}
710+
711+
if (webpackIgnoreRegexp.test(node.raws.between)) {
712+
return true;
713+
}
714+
715+
let rule;
716+
717+
// eslint-disable-next-line default-case
718+
switch (node.type) {
719+
case "atrule":
720+
rule = node;
721+
break;
722+
case "decl":
723+
rule = node.parent;
724+
break;
725+
}
726+
727+
const prevNode = rule.prev();
728+
729+
if (typeof prevNode === "undefined") {
730+
return false;
731+
}
732+
733+
if (prevNode.type !== "comment") {
734+
return false;
735+
}
736+
737+
return webpackIgnoreRegexp.test(prevNode.text);
738+
}
739+
705740
export {
706741
normalizeOptions,
707742
shouldUseModulesPlugins,
@@ -721,4 +756,6 @@ export {
721756
resolveRequests,
722757
isUrlRequestable,
723758
sort,
759+
isWebpackIgnoreSource,
760+
webpackIgnoreRegexp,
724761
};

test/__snapshots__/loader.test.js.snap

+146
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,152 @@ exports[`loader should work with the "modules.auto" option and the "importLoader
723723
724724
exports[`loader should work with the "modules.auto" option and the "importLoaders" option: warnings 1`] = `Array []`;
725725
726+
exports[`loader should work with webpackIgnore comment: errors 1`] = `Array []`;
727+
728+
exports[`loader should work with webpackIgnore comment: module 1`] = `
729+
"// Imports
730+
import ___CSS_LOADER_API_IMPORT___ from \\"../../src/runtime/api.js\\";
731+
import ___CSS_LOADER_GET_URL_IMPORT___ from \\"../../src/runtime/getUrl.js\\";
732+
import ___CSS_LOADER_URL_IMPORT_0___ from \\"./url/img.png\\";
733+
import ___CSS_LOADER_URL_IMPORT_1___ from \\"./fonts/Roboto-Regular.eot\\";
734+
import ___CSS_LOADER_URL_IMPORT_2___ from \\"./fonts/Roboto-Regular.woff\\";
735+
import ___CSS_LOADER_URL_IMPORT_3___ from \\"./fonts/Roboto-Regular.svg\\";
736+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(function(i){return i[1]});
737+
var ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);
738+
var ___CSS_LOADER_URL_REPLACEMENT_1___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_1___);
739+
var ___CSS_LOADER_URL_REPLACEMENT_2___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_1___, { hash: \\"#iefix\\" });
740+
var ___CSS_LOADER_URL_REPLACEMENT_3___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_2___);
741+
var ___CSS_LOADER_URL_REPLACEMENT_4___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_3___, { hash: \\"#Roboto-Regular\\" });
742+
// Module
743+
___CSS_LOADER_EXPORT___.push([module.id, \\"/*webpackIgnore: true*/\\\\n@import url(./basic.css);\\\\n\\\\n@import /* webpackIgnore: true */ url(./imported.css);\\\\n\\\\n/** webpackIgnore: true **/\\\\n@import url(./simple.css);\\\\n\\\\n/** webpackIgnore: true */\\\\n.class {\\\\n color: red;\\\\n background: url(\\\\\\"./url/img.png\\\\\\");\\\\n}\\\\n\\\\n.class {\\\\n color: red;\\\\n background: /** webpackIgnore: true */ url(\\\\\\"./url/img.png\\\\\\");\\\\n}\\\\n\\\\n.class {\\\\n background:\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n /** webpackIgnore: true **/ url(\\\\\\"./url/img.png\\\\\\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n /** webpackIgnore: true **/ url(\\\\\\"./url/img.png\\\\\\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"),\\\\n /** webpackIgnore: true **/\\\\n url(\\\\\\"./url/img.png\\\\\\");\\\\n}\\\\n\\\\n/** webpackIgnore: true **/\\\\n@font-face {\\\\n font-family: \\\\\\"Roboto\\\\\\";\\\\n src: url(\\\\\\"./fonts/Roboto-Regular.eot\\\\\\");\\\\n src:\\\\n url(\\\\\\"./fonts/Roboto-Regular.eot#iefix\\\\\\") format(\\\\\\"embedded-opentype\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.woff2\\\\\\") format(\\\\\\"woff\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.woff\\\\\\") format(\\\\\\"woff\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.ttf\\\\\\") format(\\\\\\"truetype\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.svg#Roboto-Regular\\\\\\") format(\\\\\\"svg\\\\\\");\\\\n font-weight: 400;\\\\n font-style: normal;\\\\n}\\\\n\\\\n@font-face {\\\\n font-family: \\\\\\"Roboto\\\\\\";\\\\n src: /** webpackIgnore: true **/ url(\\\\\\"./fonts/Roboto-Regular.eot\\\\\\");\\\\n src: /** webpackIgnore: true **/\\\\n url(\\\\\\"./fonts/Roboto-Regular.eot#iefix\\\\\\") format(\\\\\\"embedded-opentype\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.woff2\\\\\\") format(\\\\\\"woff\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.woff\\\\\\") format(\\\\\\"woff\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.ttf\\\\\\") format(\\\\\\"truetype\\\\\\"),\\\\n url(\\\\\\"./fonts/Roboto-Regular.svg#Roboto-Regular\\\\\\") format(\\\\\\"svg\\\\\\");\\\\n font-weight: 400;\\\\n font-style: normal;\\\\n}\\\\n\\\\n@font-face {\\\\n font-family: \\\\\\"Roboto\\\\\\";\\\\n src: url(\\" + ___CSS_LOADER_URL_REPLACEMENT_1___ + \\");\\\\n src:\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_2___ + \\") format(\\\\\\"embedded-opentype\\\\\\"),\\\\n /** webpackIgnore: true **/\\\\n url(\\\\\\"./fonts/Roboto-Regular.woff2\\\\\\") format(\\\\\\"woff\\\\\\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_3___ + \\") format(\\\\\\"woff\\\\\\"),\\\\n /** webpackIgnore: true **/\\\\n url(\\\\\\"./fonts/Roboto-Regular.ttf\\\\\\") format(\\\\\\"truetype\\\\\\"),\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_4___ + \\") format(\\\\\\"svg\\\\\\");\\\\n font-weight: 400;\\\\n font-style: normal;\\\\n}\\\\n\\\\n/*webpackIgnore: true*/\\\\n.class {\\\\n background-image: image-set(\\\\n url(./url/img.png) 2x,\\\\n url(./url/img.png) 3x,\\\\n url(./url/img.png) 4x,\\\\n url(./url/img.png) 5x,\\\\n url(./url/img.png) 6x,\\\\n url(./url/img.png) 7x\\\\n );\\\\n}\\\\n\\\\n.class {\\\\n background-image: /*webpackIgnore: true*/ image-set(\\\\n url(./url/img.png) 2x,\\\\n url(./url/img.png) 3x,\\\\n url(./url/img.png) 4x,\\\\n url(./url/img.png) 5x,\\\\n url(./url/img.png) 6x,\\\\n url(./url/img.png) 7x\\\\n );\\\\n}\\\\n\\\\n.class {\\\\n background-image: image-set(\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\") 2x,\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\") 3x,\\\\n /*webpackIgnore: true*/\\\\n url(./url/img.png) 4x,\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\") 5x,\\\\n url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\") 6x,\\\\n /*webpackIgnore: true*/\\\\n url(./url/img.png) 7x\\\\n );\\\\n}\\\\n\\\\n\\", \\"\\"]);
744+
// Exports
745+
export default ___CSS_LOADER_EXPORT___;
746+
"
747+
`;
748+
749+
exports[`loader should work with webpackIgnore comment: result 1`] = `
750+
Array [
751+
Array [
752+
"./webpackIgnore.css",
753+
"/*webpackIgnore: true*/
754+
@import url(./basic.css);
755+
756+
@import /* webpackIgnore: true */ url(./imported.css);
757+
758+
/** webpackIgnore: true **/
759+
@import url(./simple.css);
760+
761+
/** webpackIgnore: true */
762+
.class {
763+
color: red;
764+
background: url(\\"./url/img.png\\");
765+
}
766+
767+
.class {
768+
color: red;
769+
background: /** webpackIgnore: true */ url(\\"./url/img.png\\");
770+
}
771+
772+
.class {
773+
background:
774+
url(/webpack/public/path/img.png),
775+
url(/webpack/public/path/img.png),
776+
/** webpackIgnore: true **/ url(\\"./url/img.png\\"),
777+
url(/webpack/public/path/img.png),
778+
/** webpackIgnore: true **/ url(\\"./url/img.png\\"),
779+
url(/webpack/public/path/img.png),
780+
url(/webpack/public/path/img.png),
781+
url(/webpack/public/path/img.png),
782+
/** webpackIgnore: true **/
783+
url(\\"./url/img.png\\");
784+
}
785+
786+
/** webpackIgnore: true **/
787+
@font-face {
788+
font-family: \\"Roboto\\";
789+
src: url(\\"./fonts/Roboto-Regular.eot\\");
790+
src:
791+
url(\\"./fonts/Roboto-Regular.eot#iefix\\") format(\\"embedded-opentype\\"),
792+
url(\\"./fonts/Roboto-Regular.woff2\\") format(\\"woff\\"),
793+
url(\\"./fonts/Roboto-Regular.woff\\") format(\\"woff\\"),
794+
url(\\"./fonts/Roboto-Regular.ttf\\") format(\\"truetype\\"),
795+
url(\\"./fonts/Roboto-Regular.svg#Roboto-Regular\\") format(\\"svg\\");
796+
font-weight: 400;
797+
font-style: normal;
798+
}
799+
800+
@font-face {
801+
font-family: \\"Roboto\\";
802+
src: /** webpackIgnore: true **/ url(\\"./fonts/Roboto-Regular.eot\\");
803+
src: /** webpackIgnore: true **/
804+
url(\\"./fonts/Roboto-Regular.eot#iefix\\") format(\\"embedded-opentype\\"),
805+
url(\\"./fonts/Roboto-Regular.woff2\\") format(\\"woff\\"),
806+
url(\\"./fonts/Roboto-Regular.woff\\") format(\\"woff\\"),
807+
url(\\"./fonts/Roboto-Regular.ttf\\") format(\\"truetype\\"),
808+
url(\\"./fonts/Roboto-Regular.svg#Roboto-Regular\\") format(\\"svg\\");
809+
font-weight: 400;
810+
font-style: normal;
811+
}
812+
813+
@font-face {
814+
font-family: \\"Roboto\\";
815+
src: url(/webpack/public/path/Roboto-Regular.eot);
816+
src:
817+
url(/webpack/public/path/Roboto-Regular.eot#iefix) format(\\"embedded-opentype\\"),
818+
/** webpackIgnore: true **/
819+
url(\\"./fonts/Roboto-Regular.woff2\\") format(\\"woff\\"),
820+
url(/webpack/public/path/Roboto-Regular.woff) format(\\"woff\\"),
821+
/** webpackIgnore: true **/
822+
url(\\"./fonts/Roboto-Regular.ttf\\") format(\\"truetype\\"),
823+
url(/webpack/public/path/Roboto-Regular.svg#Roboto-Regular) format(\\"svg\\");
824+
font-weight: 400;
825+
font-style: normal;
826+
}
827+
828+
/*webpackIgnore: true*/
829+
.class {
830+
background-image: image-set(
831+
url(./url/img.png) 2x,
832+
url(./url/img.png) 3x,
833+
url(./url/img.png) 4x,
834+
url(./url/img.png) 5x,
835+
url(./url/img.png) 6x,
836+
url(./url/img.png) 7x
837+
);
838+
}
839+
840+
.class {
841+
background-image: /*webpackIgnore: true*/ image-set(
842+
url(./url/img.png) 2x,
843+
url(./url/img.png) 3x,
844+
url(./url/img.png) 4x,
845+
url(./url/img.png) 5x,
846+
url(./url/img.png) 6x,
847+
url(./url/img.png) 7x
848+
);
849+
}
850+
851+
.class {
852+
background-image: image-set(
853+
url(/webpack/public/path/img.png) 2x,
854+
url(/webpack/public/path/img.png) 3x,
855+
/*webpackIgnore: true*/
856+
url(./url/img.png) 4x,
857+
url(/webpack/public/path/img.png) 5x,
858+
url(/webpack/public/path/img.png) 6x,
859+
/*webpackIgnore: true*/
860+
url(./url/img.png) 7x
861+
);
862+
}
863+
864+
",
865+
"",
866+
],
867+
]
868+
`;
869+
870+
exports[`loader should work with webpackIgnore comment: warnings 1`] = `Array []`;
871+
726872
exports[`loader should work: errors 1`] = `Array []`;
727873
728874
exports[`loader should work: module 1`] = `

0 commit comments

Comments
 (0)