Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reduce count of require #1014

Merged
merged 1 commit into from Dec 10, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 31 additions & 6 deletions src/plugins/postcss-icss-parser.js
@@ -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
@@ -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
@@ -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
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
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
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