Skip to content

Commit

Permalink
feat: added support webpackIgnore comment (#1264)
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-Bernardito committed Feb 25, 2021
1 parent e18c5a9 commit 53d40a9
Show file tree
Hide file tree
Showing 14 changed files with 3,406 additions and 24 deletions.
54 changes: 54 additions & 0 deletions README.md
Expand Up @@ -1132,6 +1132,60 @@ module.exports = {

## Examples

### Disable url resolving using the `/* webpackIgnore: true */` comment

With the help of the `/* webpackIgnore: true */`comment, it is possible to disable sources handling for rules and for individual declarations.

```css
/* webpackIgnore: true */
@import url(./basic.css);
@import /* webpackIgnore: true */ url(./imported.css);

.class {
/* Disabled url handling for the all urls in the 'background' declaration */
color: red;
/* webpackIgnore: true */
background: url("./url/img.png"), url("./url/img.png");
}

.class {
/* Disabled url handling for the first url in the 'background' declaration */
color: red;
background:
/* webpackIgnore: true */ url("./url/img.png"), url("./url/img.png");
}

.class {
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background: url("./url/img.png"),
/* webpackIgnore: true */ url("./url/img.png");
}

/* prettier-ignore */
.class {
/* Disabled url handling for the second url in the 'background' declaration */
color: red;
background: url("./url/img.png"),
/* webpackIgnore: true */
url("./url/img.png");
}

/* prettier-ignore */
.class {
/* Disabled url handling for third and sixth urls in the 'background-image' declaration */
background-image: image-set(
url(./url/img.png) 2x,
url(./url/img.png) 3x,
/* webpackIgnore: true */ url(./url/img.png) 4x,
url(./url/img.png) 5x,
url(./url/img.png) 6x,
/* webpackIgnore: true */
url(./url/img.png) 7x
);
}
```

### Assets

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.
Expand Down
22 changes: 22 additions & 0 deletions src/plugins/postcss-import-parser.js
Expand Up @@ -5,6 +5,7 @@ import {
resolveRequests,
isUrlRequestable,
requestify,
webpackIgnoreCommentRegexp,
} from "../utils";

function visitor(result, parsedResults, node, key) {
Expand All @@ -13,6 +14,27 @@ function visitor(result, parsedResults, node, key) {
return;
}

if (node.raws.afterName && node.raws.afterName.trim().length > 0) {
const lastCommentIndex = node.raws.afterName.lastIndexOf("/*");
const matched = node.raws.afterName
.slice(lastCommentIndex)
.match(webpackIgnoreCommentRegexp);

if (matched && matched[2] === "true") {
return;
}
}

const prevNode = node.prev();

if (prevNode && prevNode.type === "comment") {
const matched = prevNode.text.match(webpackIgnoreCommentRegexp);

if (matched && matched[2] === "true") {
return;
}
}

// Nodes do not exists - `@import url('http://') :root {}`
if (node.nodes) {
result.warn(
Expand Down
119 changes: 115 additions & 4 deletions src/plugins/postcss-url-parser.js
Expand Up @@ -5,6 +5,7 @@ import {
requestify,
resolveRequests,
isUrlRequestable,
webpackIgnoreCommentRegexp,
} from "../utils";

const isUrlFunc = /url/i;
Expand All @@ -30,19 +31,94 @@ function shouldHandleRule(rule, node, result) {
return true;
}

function getWebpackIgnoreCommentValue(index, nodes, inBetween) {
if (index === 0 && typeof inBetween !== "undefined") {
return inBetween;
}

let prevValueNode = nodes[index - 1];

if (!prevValueNode) {
// eslint-disable-next-line consistent-return
return;
}

if (prevValueNode.type === "space") {
if (!nodes[index - 2]) {
// eslint-disable-next-line consistent-return
return;
}

prevValueNode = nodes[index - 2];
}

if (prevValueNode.type !== "comment") {
// eslint-disable-next-line consistent-return
return;
}

const matched = prevValueNode.value.match(webpackIgnoreCommentRegexp);

return matched && matched[2] === "true";
}

function visitor(result, parsedResults, node, key) {
if (!needParseDeclaration.test(node[key])) {
return;
}

const parsed = valueParser(node[key]);
const parsed = valueParser(
typeof node.raws.value === "undefined" ? node[key] : node.raws.value.raw
);

let inBetween;

if (typeof node.raws.between !== "undefined") {
const lastCommentIndex = node.raws.between.lastIndexOf("/*");

const matched = node.raws.between
.slice(lastCommentIndex)
.match(webpackIgnoreCommentRegexp);

if (matched) {
inBetween = matched[2] === "true";
}
}

let isIgnoreOnDeclaration = false;

parsed.walk((valueNode) => {
const prevNode = node.prev();

if (prevNode && prevNode.type === "comment") {
const matched = prevNode.text.match(webpackIgnoreCommentRegexp);

if (matched) {
isIgnoreOnDeclaration = matched[2] === "true";
}
}

let needIgnore;

parsed.walk((valueNode, index, valueNodes) => {
if (valueNode.type !== "function") {
return;
}

if (isUrlFunc.test(valueNode.value)) {
needIgnore = getWebpackIgnoreCommentValue(index, valueNodes, inBetween);

if (
(isIgnoreOnDeclaration && typeof needIgnore === "undefined") ||
needIgnore
) {
if (needIgnore) {
// eslint-disable-next-line no-undefined
needIgnore = undefined;
}

return;
}

const { nodes } = valueNode;
const isStringValue = nodes.length !== 0 && nodes[0].type === "string";
const url = isStringValue ? nodes[0].value : valueParser.stringify(nodes);
Expand All @@ -62,10 +138,28 @@ function visitor(result, parsedResults, node, key) {
// eslint-disable-next-line consistent-return
return false;
} else if (isImageSetFunc.test(valueNode.value)) {
for (const nNode of valueNode.nodes) {
for (const [innerIndex, nNode] of valueNode.nodes.entries()) {
const { type, value } = nNode;

if (type === "function" && isUrlFunc.test(value)) {
needIgnore = getWebpackIgnoreCommentValue(
innerIndex,
valueNode.nodes
);

if (
(isIgnoreOnDeclaration && typeof needIgnore === "undefined") ||
needIgnore
) {
if (needIgnore) {
// eslint-disable-next-line no-undefined
needIgnore = undefined;
}

// eslint-disable-next-line no-continue
continue;
}

const { nodes } = nNode;
const isStringValue =
nodes.length !== 0 && nodes[0].type === "string";
Expand All @@ -88,6 +182,24 @@ function visitor(result, parsedResults, node, key) {
});
}
} else if (type === "string") {
needIgnore = getWebpackIgnoreCommentValue(
innerIndex,
valueNode.nodes
);

if (
(isIgnoreOnDeclaration && typeof needIgnore === "undefined") ||
needIgnore
) {
if (needIgnore) {
// eslint-disable-next-line no-undefined
needIgnore = undefined;
}

// eslint-disable-next-line no-continue
continue;
}

const rule = {
node: nNode,
url: value,
Expand All @@ -104,7 +216,6 @@ function visitor(result, parsedResults, node, key) {
}
}
}

// Do not traverse inside `image-set`
// eslint-disable-next-line consistent-return
return false;
Expand Down
2 changes: 2 additions & 0 deletions src/utils.js
Expand Up @@ -19,6 +19,7 @@ const unescapeRegExp = new RegExp(
"ig"
);
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
const webpackIgnoreCommentRegexp = /webpackIgnore:(\s+)?(true|false)/;

function unescape(str) {
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
Expand Down Expand Up @@ -721,4 +722,5 @@ export {
resolveRequests,
isUrlRequestable,
sort,
webpackIgnoreCommentRegexp,
};

0 comments on commit 53d40a9

Please sign in to comment.