Skip to content

Commit

Permalink
fix: reduce count of require (#1014)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Dec 10, 2019
1 parent 60c65e0 commit e091d27
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 40 deletions.
37 changes: 31 additions & 6 deletions src/plugins/postcss-icss-parser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import postcss from 'postcss';
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils';
import { urlToRequest } from 'loader-utils';

const pluginName = 'postcss-icss-parser';

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

Object.keys(icssImports).forEach((url, importIndex) => {
const tokens = Object.keys(icssImports[url]);
const normalizedIcssImports = Object.keys(icssImports).reduce(
(accumulator, url) => {
const tokensMap = icssImports[url];
const tokens = Object.keys(tokensMap);

if (tokens.length === 0) {
return;
}
if (tokens.length === 0) {
return accumulator;
}

const normalizedUrl = urlToRequest(url);

if (!accumulator[normalizedUrl]) {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = tokensMap;
} else {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = {
...accumulator[normalizedUrl],
...tokensMap,
};
}

return accumulator;
},
{}
);

Object.keys(normalizedIcssImports).forEach((url, importIndex) => {
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;

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

const tokenMap = normalizedIcssImports[url];
const tokens = Object.keys(tokenMap);

tokens.forEach((token, replacementIndex) => {
const name = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
const localName = icssImports[url][token];
const localName = tokenMap[token];

importReplacements[token] = name;

Expand Down
7 changes: 6 additions & 1 deletion src/plugins/postcss-import-parser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import postcss from 'postcss';
import valueParser from 'postcss-value-parser';
import { isUrlRequest, urlToRequest } from 'loader-utils';

const pluginName = 'postcss-import-parser';

Expand Down Expand Up @@ -28,12 +29,16 @@ function parseImport(params) {
return null;
}

const url = getUrl(nodes[0]);
let url = getUrl(nodes[0]);

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

if (isUrlRequest(url)) {
url = urlToRequest(url);
}

return {
url,
media: valueParser
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/postcss-url-parser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import postcss from 'postcss';
import valueParser from 'postcss-value-parser';
import { urlToRequest } from 'loader-utils';

const pluginName = 'postcss-url-parser';

Expand Down Expand Up @@ -77,7 +78,7 @@ function getUrlsFromValue(value, result, filter, decl) {
}

const splittedUrl = url.split(/(\?)?#/);
let normalizedUrl = decodeURIComponent(splittedUrl[0]);
let normalizedUrl = urlToRequest(decodeURIComponent(splittedUrl[0]));
const [, singleQuery, hashValue] = splittedUrl;
const hash =
singleQuery || hashValue
Expand Down
13 changes: 3 additions & 10 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
*/
import path from 'path';

import loaderUtils, {
isUrlRequest,
stringifyRequest,
urlToRequest,
} from 'loader-utils';
import loaderUtils, { isUrlRequest, stringifyRequest } from 'loader-utils';
import normalizePath from 'normalize-path';
import cssesc from 'cssesc';
import modulesValues from 'postcss-modules-values';
Expand Down Expand Up @@ -230,10 +226,7 @@ function getImportCode(
importPrefix = getImportPrefix(loaderContext, importLoaders);
}

const url = stringifyRequest(
loaderContext,
importPrefix + urlToRequest(item.url)
);
const url = stringifyRequest(loaderContext, importPrefix + item.url);

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

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

if (!importName) {
const preparedUrl = stringifyRequest(loaderContext, urlToRequest(url));
const preparedUrl = stringifyRequest(loaderContext, url);

importName = `___CSS_LOADER_URL_PURE_IMPORT_${index}___`;
importItems.push(`var ${importName} = require(${preparedUrl});`);
Expand Down
8 changes: 6 additions & 2 deletions test/__snapshots__/import-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ Array [
.background {
background: url(/webpack/public/path/img.png);
}
@import url(./test.css);
",
"",
],
Expand Down Expand Up @@ -211,7 +213,7 @@ exports.i(___CSS_LOADER_AT_RULE_IMPORT_17___);
exports.i(___CSS_LOADER_AT_RULE_IMPORT_18___);
var ___CSS_LOADER_URL_IMPORT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_PURE_IMPORT_0___);
// Module
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\\", \\"\\"]);
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\\", \\"\\"]);
"
`;

Expand Down Expand Up @@ -346,6 +348,8 @@ Array [
.background {
background: url(/webpack/public/path/img.png);
}
@import url(./test.css);
",
"",
],
Expand All @@ -360,7 +364,7 @@ var ___CSS_LOADER_URL_PURE_IMPORT_0___ = require(\\"./img.png\\");
exports = module.exports = ___CSS_LOADER_API_IMPORT___(false);
var ___CSS_LOADER_URL_IMPORT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_PURE_IMPORT_0___);
// Module
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\\", \\"\\"]);
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\\", \\"\\"]);
"
`;

Expand Down
44 changes: 44 additions & 0 deletions test/__snapshots__/modules-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6627,6 +6627,50 @@ Array [
exports[`modules should accepts all arguments for getLocalIdent option: warnings 1`] = `Array []`;
exports[`modules should avoid unnecessary "require": errors 1`] = `Array []`;
exports[`modules should avoid unnecessary "require": module (evaluated) 1`] = `
Array [
Array [
2,
"._22ETk3ZhhvjVe-4dAULcsF {
display: block;
}
",
"",
],
Array [
1,
"._1UrsXQ2x66vvn0IAbZqRYi {
color: red;
}
._3xlGH7JLMDZsCqOwH83KaV {
color: red;
}
",
"",
],
]
`;
exports[`modules should avoid unnecessary "require": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../src/runtime/api.js\\");
var ___CSS_LOADER_ICSS_IMPORT_0___ = require(\\"-!../../../src/index.js??ref--4-0!./imported-simple.css\\");
exports = module.exports = ___CSS_LOADER_API_IMPORT___(false);
exports.i(___CSS_LOADER_ICSS_IMPORT_0___);
// Module
exports.push([module.id, \\"._1UrsXQ2x66vvn0IAbZqRYi {\\\\n color: red;\\\\n}\\\\n\\\\n._3xlGH7JLMDZsCqOwH83KaV {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
// Exports
exports.locals = {
\\"simple-foo\\": \\"_1UrsXQ2x66vvn0IAbZqRYi \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\",
\\"simple-bar\\": \\"_3xlGH7JLMDZsCqOwH83KaV \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\"
};"
`;
exports[`modules should avoid unnecessary "require": warnings 1`] = `Array []`;
exports[`modules should correctly replace escaped symbols in selector with localIdentName option: errors 1`] = `Array []`;
exports[`modules should correctly replace escaped symbols in selector with localIdentName option: locals 1`] = `
Expand Down
Loading

0 comments on commit e091d27

Please sign in to comment.