Skip to content

Commit e091d27

Browse files
fix: reduce count of require (#1014)
1 parent 60c65e0 commit e091d27

11 files changed

+158
-40
lines changed

src/plugins/postcss-icss-parser.js

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import postcss from 'postcss';
22
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils';
3+
import { urlToRequest } from 'loader-utils';
34

45
const pluginName = 'postcss-icss-parser';
56

@@ -10,13 +11,34 @@ export default postcss.plugin(
1011
const importReplacements = Object.create(null);
1112
const { icssImports, icssExports } = extractICSS(css);
1213

13-
Object.keys(icssImports).forEach((url, importIndex) => {
14-
const tokens = Object.keys(icssImports[url]);
14+
const normalizedIcssImports = Object.keys(icssImports).reduce(
15+
(accumulator, url) => {
16+
const tokensMap = icssImports[url];
17+
const tokens = Object.keys(tokensMap);
1518

16-
if (tokens.length === 0) {
17-
return;
18-
}
19+
if (tokens.length === 0) {
20+
return accumulator;
21+
}
1922

23+
const normalizedUrl = urlToRequest(url);
24+
25+
if (!accumulator[normalizedUrl]) {
26+
// eslint-disable-next-line no-param-reassign
27+
accumulator[normalizedUrl] = tokensMap;
28+
} else {
29+
// eslint-disable-next-line no-param-reassign
30+
accumulator[normalizedUrl] = {
31+
...accumulator[normalizedUrl],
32+
...tokensMap,
33+
};
34+
}
35+
36+
return accumulator;
37+
},
38+
{}
39+
);
40+
41+
Object.keys(normalizedIcssImports).forEach((url, importIndex) => {
2042
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;
2143

2244
result.messages.push({
@@ -25,9 +47,12 @@ export default postcss.plugin(
2547
value: { type: 'icss-import', name: importName, url },
2648
});
2749

50+
const tokenMap = normalizedIcssImports[url];
51+
const tokens = Object.keys(tokenMap);
52+
2853
tokens.forEach((token, replacementIndex) => {
2954
const name = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
30-
const localName = icssImports[url][token];
55+
const localName = tokenMap[token];
3156

3257
importReplacements[token] = name;
3358

src/plugins/postcss-import-parser.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import postcss from 'postcss';
22
import valueParser from 'postcss-value-parser';
3+
import { isUrlRequest, urlToRequest } from 'loader-utils';
34

45
const pluginName = 'postcss-import-parser';
56

@@ -28,12 +29,16 @@ function parseImport(params) {
2829
return null;
2930
}
3031

31-
const url = getUrl(nodes[0]);
32+
let url = getUrl(nodes[0]);
3233

3334
if (!url || url.trim().length === 0) {
3435
return null;
3536
}
3637

38+
if (isUrlRequest(url)) {
39+
url = urlToRequest(url);
40+
}
41+
3742
return {
3843
url,
3944
media: valueParser

src/plugins/postcss-url-parser.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import postcss from 'postcss';
22
import valueParser from 'postcss-value-parser';
3+
import { urlToRequest } from 'loader-utils';
34

45
const pluginName = 'postcss-url-parser';
56

@@ -77,7 +78,7 @@ function getUrlsFromValue(value, result, filter, decl) {
7778
}
7879

7980
const splittedUrl = url.split(/(\?)?#/);
80-
let normalizedUrl = decodeURIComponent(splittedUrl[0]);
81+
let normalizedUrl = urlToRequest(decodeURIComponent(splittedUrl[0]));
8182
const [, singleQuery, hashValue] = splittedUrl;
8283
const hash =
8384
singleQuery || hashValue

src/utils.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
*/
55
import path from 'path';
66

7-
import loaderUtils, {
8-
isUrlRequest,
9-
stringifyRequest,
10-
urlToRequest,
11-
} from 'loader-utils';
7+
import loaderUtils, { isUrlRequest, stringifyRequest } from 'loader-utils';
128
import normalizePath from 'normalize-path';
139
import cssesc from 'cssesc';
1410
import modulesValues from 'postcss-modules-values';
@@ -230,10 +226,7 @@ function getImportCode(
230226
importPrefix = getImportPrefix(loaderContext, importLoaders);
231227
}
232228

233-
const url = stringifyRequest(
234-
loaderContext,
235-
importPrefix + urlToRequest(item.url)
236-
);
229+
const url = stringifyRequest(loaderContext, importPrefix + item.url);
237230

238231
importItems.push(`var ${item.name} = require(${url});`);
239232

@@ -259,7 +252,7 @@ function getImportCode(
259252
let importName = urlImportNames.get(url);
260253

261254
if (!importName) {
262-
const preparedUrl = stringifyRequest(loaderContext, urlToRequest(url));
255+
const preparedUrl = stringifyRequest(loaderContext, url);
263256

264257
importName = `___CSS_LOADER_URL_PURE_IMPORT_${index}___`;
265258
importItems.push(`var ${importName} = require(${preparedUrl});`);

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ Array [
168168
.background {
169169
background: url(/webpack/public/path/img.png);
170170
}
171+
172+
@import url(./test.css);
171173
",
172174
"",
173175
],
@@ -211,7 +213,7 @@ exports.i(___CSS_LOADER_AT_RULE_IMPORT_17___);
211213
exports.i(___CSS_LOADER_AT_RULE_IMPORT_18___);
212214
var ___CSS_LOADER_URL_IMPORT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_PURE_IMPORT_0___);
213215
// Module
214-
exports.push([module.id, \\"@import url(test.css);\\\\n@import url('test.css');\\\\n@import url(\\\\\\"test.css\\\\\\");\\\\n@IMPORT url(test.css);\\\\n@import URL(test.css);\\\\n@import url(test.css );\\\\n@import url( test.css);\\\\n@import url( test.css );\\\\n@import url(\\\\n test.css\\\\n);\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import \\\\\\"test.css\\\\\\";\\\\n@import 'test.css';\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import url(test.css) screen and print;\\\\n@import url(test.css) SCREEN AND PRINT;\\\\n@import url(test.css)screen and print;\\\\n@import url(test.css) screen and print;\\\\n@import url(~package/test.css);\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\\\n.background {\\\\n background: url(\\" + ___CSS_LOADER_URL_IMPORT_0___ + \\");\\\\n}\\\\n\\", \\"\\"]);
216+
exports.push([module.id, \\"@import url(test.css);\\\\n@import url('test.css');\\\\n@import url(\\\\\\"test.css\\\\\\");\\\\n@IMPORT url(test.css);\\\\n@import URL(test.css);\\\\n@import url(test.css );\\\\n@import url( test.css);\\\\n@import url( test.css );\\\\n@import url(\\\\n test.css\\\\n);\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import \\\\\\"test.css\\\\\\";\\\\n@import 'test.css';\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import url(test.css) screen and print;\\\\n@import url(test.css) SCREEN AND PRINT;\\\\n@import url(test.css)screen and print;\\\\n@import url(test.css) screen and print;\\\\n@import url(~package/test.css);\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\\\n.background {\\\\n background: url(\\" + ___CSS_LOADER_URL_IMPORT_0___ + \\");\\\\n}\\\\n\\\\n@import url(./test.css);\\\\n\\", \\"\\"]);
215217
"
216218
`;
217219

@@ -346,6 +348,8 @@ Array [
346348
.background {
347349
background: url(/webpack/public/path/img.png);
348350
}
351+
352+
@import url(./test.css);
349353
",
350354
"",
351355
],
@@ -360,7 +364,7 @@ var ___CSS_LOADER_URL_PURE_IMPORT_0___ = require(\\"./img.png\\");
360364
exports = module.exports = ___CSS_LOADER_API_IMPORT___(false);
361365
var ___CSS_LOADER_URL_IMPORT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_PURE_IMPORT_0___);
362366
// Module
363-
exports.push([module.id, \\"@import url(test.css);\\\\n@import url('test.css');\\\\n@import url(\\\\\\"test.css\\\\\\");\\\\n@IMPORT url(test.css);\\\\n@import URL(test.css);\\\\n@import url(test.css );\\\\n@import url( test.css);\\\\n@import url( test.css );\\\\n@import url(\\\\n test.css\\\\n);\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import \\\\\\"test.css\\\\\\";\\\\n@import 'test.css';\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import url(test.css) screen and print;\\\\n@import url(test.css) SCREEN AND PRINT;\\\\n@import url(test.css)screen and print;\\\\n@import url(test.css) screen and print;\\\\n@import url(test-media.css) screen and print;\\\\n@import url(test-other.css) (min-width: 100px);\\\\n@import url(http://example.com/style.css);\\\\n@import url(http://example.com/style.css);\\\\n@import url(http://example.com/style.css#hash);\\\\n@import url(http://example.com/style.css?#hash);\\\\n@import url(http://example.com/style.css?foo=bar#hash);\\\\n@import url(http://example.com/other-style.css) screen and print;\\\\n@import url(http://example.com/other-style.css) screen and print;\\\\n@import url(\\\\\\"//example.com/style.css\\\\\\");\\\\n@import url(~package/test.css);\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n@import url('query.css?foo=1&bar=1');\\\\n@import url('other-query.css?foo=1&bar=1#hash');\\\\n@import url('other-query.css?foo=1&bar=1#hash') screen and print;\\\\n@import url('https://fonts.googleapis.com/css?family=Roboto');\\\\n@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC');\\\\n@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto');\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\\\n@import url('./relative.css');\\\\n@import url('../import/top-relative.css');\\\\n@import url(~package/tilde.css);\\\\n@import url(~aliasesImport/alias.css);\\\\n@import url('./url.css');\\\\n\\\\n.background {\\\\n background: url(\\" + ___CSS_LOADER_URL_IMPORT_0___ + \\");\\\\n}\\\\n\\", \\"\\"]);
367+
exports.push([module.id, \\"@import url(test.css);\\\\n@import url('test.css');\\\\n@import url(\\\\\\"test.css\\\\\\");\\\\n@IMPORT url(test.css);\\\\n@import URL(test.css);\\\\n@import url(test.css );\\\\n@import url( test.css);\\\\n@import url( test.css );\\\\n@import url(\\\\n test.css\\\\n);\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import \\\\\\"test.css\\\\\\";\\\\n@import 'test.css';\\\\n@import '';\\\\n@import \\\\\\"\\\\\\";\\\\n@import \\\\\\" \\\\\\";\\\\n@import \\\\\\"\\\\n\\\\\\";\\\\n@import url();\\\\n@import url('');\\\\n@import url(\\\\\\"\\\\\\");\\\\n@import url(test.css) screen and print;\\\\n@import url(test.css) SCREEN AND PRINT;\\\\n@import url(test.css)screen and print;\\\\n@import url(test.css) screen and print;\\\\n@import url(test-media.css) screen and print;\\\\n@import url(test-other.css) (min-width: 100px);\\\\n@import url(http://example.com/style.css);\\\\n@import url(http://example.com/style.css);\\\\n@import url(http://example.com/style.css#hash);\\\\n@import url(http://example.com/style.css?#hash);\\\\n@import url(http://example.com/style.css?foo=bar#hash);\\\\n@import url(http://example.com/other-style.css) screen and print;\\\\n@import url(http://example.com/other-style.css) screen and print;\\\\n@import url(\\\\\\"//example.com/style.css\\\\\\");\\\\n@import url(~package/test.css);\\\\n@import ;\\\\n@import foo-bar;\\\\n@import-normalize;\\\\n@import url('http://') :root {}\\\\n@import url('query.css?foo=1&bar=1');\\\\n@import url('other-query.css?foo=1&bar=1#hash');\\\\n@import url('other-query.css?foo=1&bar=1#hash') screen and print;\\\\n@import url('https://fonts.googleapis.com/css?family=Roboto');\\\\n@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC');\\\\n@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto');\\\\n\\\\n.class {\\\\n a: b c d;\\\\n}\\\\n\\\\n.foo {\\\\n @import 'path.css';\\\\n}\\\\n\\\\n@import url('./relative.css');\\\\n@import url('../import/top-relative.css');\\\\n@import url(~package/tilde.css);\\\\n@import url(~aliasesImport/alias.css);\\\\n@import url('./url.css');\\\\n\\\\n.background {\\\\n background: url(\\" + ___CSS_LOADER_URL_IMPORT_0___ + \\");\\\\n}\\\\n\\\\n@import url(./test.css);\\\\n\\", \\"\\"]);
364368
"
365369
`;
366370

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

+44
Original file line numberDiff line numberDiff line change
@@ -6627,6 +6627,50 @@ Array [
66276627
66286628
exports[`modules should accepts all arguments for getLocalIdent option: warnings 1`] = `Array []`;
66296629
6630+
exports[`modules should avoid unnecessary "require": errors 1`] = `Array []`;
6631+
6632+
exports[`modules should avoid unnecessary "require": module (evaluated) 1`] = `
6633+
Array [
6634+
Array [
6635+
2,
6636+
"._22ETk3ZhhvjVe-4dAULcsF {
6637+
display: block;
6638+
}
6639+
",
6640+
"",
6641+
],
6642+
Array [
6643+
1,
6644+
"._1UrsXQ2x66vvn0IAbZqRYi {
6645+
color: red;
6646+
}
6647+
6648+
._3xlGH7JLMDZsCqOwH83KaV {
6649+
color: red;
6650+
}
6651+
",
6652+
"",
6653+
],
6654+
]
6655+
`;
6656+
6657+
exports[`modules should avoid unnecessary "require": module 1`] = `
6658+
"// Imports
6659+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../src/runtime/api.js\\");
6660+
var ___CSS_LOADER_ICSS_IMPORT_0___ = require(\\"-!../../../src/index.js??ref--4-0!./imported-simple.css\\");
6661+
exports = module.exports = ___CSS_LOADER_API_IMPORT___(false);
6662+
exports.i(___CSS_LOADER_ICSS_IMPORT_0___);
6663+
// Module
6664+
exports.push([module.id, \\"._1UrsXQ2x66vvn0IAbZqRYi {\\\\n color: red;\\\\n}\\\\n\\\\n._3xlGH7JLMDZsCqOwH83KaV {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
6665+
// Exports
6666+
exports.locals = {
6667+
\\"simple-foo\\": \\"_1UrsXQ2x66vvn0IAbZqRYi \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\",
6668+
\\"simple-bar\\": \\"_3xlGH7JLMDZsCqOwH83KaV \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\"
6669+
};"
6670+
`;
6671+
6672+
exports[`modules should avoid unnecessary "require": warnings 1`] = `Array []`;
6673+
66306674
exports[`modules should correctly replace escaped symbols in selector with localIdentName option: errors 1`] = `Array []`;
66316675
66326676
exports[`modules should correctly replace escaped symbols in selector with localIdentName option: locals 1`] = `

0 commit comments

Comments
 (0)