Skip to content

perf: use modules only if explicitly set #497

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ module.exports = function(content, map) {
var callback = this.async();
var query = loaderUtils.getOptions(this) || {};
var root = query.root;
var moduleMode = query.modules || query.module;
var camelCaseKeys = query.camelCase || query.camelcase;
var resolve = createResolver(query.alias);

Expand All @@ -23,7 +22,6 @@ module.exports = function(content, map) {
}

processCss(content, map, {
mode: moduleMode ? "local" : "global",
from: loaderUtils.getRemainingRequest(this),
to: loaderUtils.getCurrentRequest(this),
query: query,
Expand Down
2 changes: 0 additions & 2 deletions lib/localsLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ module.exports = function(content) {
if(this.cacheable) this.cacheable();
var callback = this.async();
var query = loaderUtils.getOptions(this) || {};
var moduleMode = query.modules || query.module;
var camelCaseKeys = query.camelCase || query.camelcase;

processCss(content, null, {
mode: moduleMode ? "local" : "global",
query: query,
minimize: this.minimize,
loaderContext: this
Expand Down
131 changes: 76 additions & 55 deletions lib/processCss.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
} else throw rule.error("Unexpected format" + rule.params);
values.nodes[0].nodes.shift();
var mediaQuery = Tokenizer.stringifyValues(values);
if(loaderUtils.isUrlRequest(url, options.root) && options.mode === "global") {
if((!options.modules && loaderUtils.isUrlRequest(url, options.root))
|| (loaderUtils.isUrlRequest(url, options.root) && options.mode === "global")
) {
url = loaderUtils.urlToRequest(url, options.root);
}
importItems.push({
Expand All @@ -58,25 +60,27 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
});
}

css.walkRules(function(rule) {
if(rule.selector === ":export") {
rule.walkDecls(function(decl) {
exports[decl.prop] = decl.value;
});
rule.remove();
} else if(/^:import\(.+\)$/.test(rule.selector)) {
var match = /^:import\((.+)\)$/.exec(rule.selector);
var url = loaderUtils.parseString(match[1]);
rule.walkDecls(function(decl) {
imports["$" + decl.prop] = importItems.length;
importItems.push({
url: url,
export: decl.value
if (options.modules) {
css.walkRules(function (rule) {
if (rule.selector === ":export") {
rule.walkDecls(function (decl) {
exports[decl.prop] = decl.value;
});
});
rule.remove();
}
});
rule.remove();
} else if (/^:import\(.+\)$/.test(rule.selector)) {
var match = /^:import\((.+)\)$/.exec(rule.selector);
var url = loaderUtils.parseString(match[1]);
rule.walkDecls(function (decl) {
imports["$" + decl.prop] = importItems.length;
importItems.push({
url: url,
export: decl.value
});
});
rule.remove();
}
});
}

Object.keys(exports).forEach(function(exportName) {
exports[exportName] = replaceImportsInString(exports[exportName]);
Expand All @@ -97,15 +101,21 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
}
break;
case "url":
if (options.url && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url, options.root)) {
item.stringType = "";
delete item.innerSpacingBefore;
delete item.innerSpacingAfter;
var url = item.url;
item.url = "___CSS_LOADER_URL___" + urlItems.length + "___";
urlItems.push({
url: url
});
if (options.url && !/^#/.test(item.url)) {
if (!options.modules && loaderUtils.isUrlRequest(item.url, options.root)) {
item.url = loaderUtils.urlToRequest(item.url, options.root);
}

if (loaderUtils.isUrlRequest(item.url, options.root)) {
item.stringType = "";
delete item.innerSpacingBefore;
delete item.innerSpacingAfter;
var url = item.url;
item.url = "___CSS_LOADER_URL___" + urlItems.length + "___";
urlItems.push({
url: url
});
}
}
break;
}
Expand Down Expand Up @@ -134,6 +144,9 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
var query = options.query;
var root = query.root;
var context = query.context;
var modules = query.modules || query.module;
var moduleMode = query.moduleMode || query.moduleMode;
var defaultModuleMode = modules ? "local" : "global";
var localIdentName = query.localIdentName || "[hash:base64]";
var localIdentRegExp = query.localIdentRegExp;
var forceMinimize = query.minimize;
Expand All @@ -143,39 +156,47 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {

var parserOptions = {
root: root,
mode: options.mode,
mode: moduleMode,
modules: modules,
url: query.url !== false,
import: query.import !== false
};

var pipeline = postcss([
localByDefault({
mode: options.mode,
rewriteUrl: function(global, url) {
if(parserOptions.url){
if(!loaderUtils.isUrlRequest(url, root)) {
return url;
}
if(global) {
return loaderUtils.urlToRequest(url, root);
var plugins = [];

if (modules) {
plugins.push(
localByDefault({
mode: moduleMode ? moduleMode : defaultModuleMode,
rewriteUrl: function(global, url) {
if(parserOptions.url){
if(!loaderUtils.isUrlRequest(url, root)) {
return url;
}
if(global) {
return loaderUtils.urlToRequest(url, root);
}
}
return url;
}
return url;
}
}),
extractImports(),
modulesValues,
modulesScope({
generateScopedName: function generateScopedName (exportName) {
return customGetLocalIdent(options.loaderContext, localIdentName, exportName, {
regExp: localIdentRegExp,
hashPrefix: query.hashPrefix || "",
context: context
});
}
}),
parserPlugin(parserOptions)
]);
}),
extractImports(),
modulesValues,
modulesScope({
generateScopedName: function generateScopedName (exportName) {
return customGetLocalIdent(options.loaderContext, localIdentName, exportName, {
regExp: localIdentRegExp,
hashPrefix: query.hashPrefix || "",
context: context
});
}
})
);
}

plugins.push(parserPlugin(parserOptions));

var pipeline = postcss(plugins);

if(minimize) {
var cssnano = require("cssnano");
Expand Down
2 changes: 2 additions & 0 deletions test/customGetLocalIdentTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ describe("customGetLocalIdent", function() {
jkl: "foo"
},
{
modules: true,
moduleMode: 'global',
getLocalIdent: function () {
return 'foo'
}
Expand Down
34 changes: 17 additions & 17 deletions test/localTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("local", function() {
[1, ".test-2_pBx { background: red; }", ""]
], {
test: "test-2_pBx"
}, "?localIdentName=[local]-[hash:base64:5]");
}, "?modules&localIdentName=[local]-[hash:base64:5]");
testLocal("locals", ":local(.className) { background: red; }\n:local(#someId) { background: green; }\n" +
":local(.className .subClass) { color: green; }\n:local(#someId .subClass) { color: blue; }", [
[1, "._23J0282swY7bwvI2X4fHiV { background: red; }\n#_3vpqN0v_IxlO3TzQjbpB33 { background: green; }\n" +
Expand All @@ -27,48 +27,48 @@ describe("local", function() {
className: "_23J0282swY7bwvI2X4fHiV",
someId: "_3vpqN0v_IxlO3TzQjbpB33",
subClass: "_1s1VsToXFz17cPAltMg7jz"
});
}, "?modules");
testLocalMinimize("minimized plus local", ":local(.localClass) { background: red; }\n:local .otherClass { background: red; }\n:local(.empty) { }", [
[1, "._localClass,._otherClass{background:red}", ""]
], {
localClass: "_localClass",
otherClass: "_otherClass",
empty: "_empty"
}, "?localIdentName=_[local]");
}, "?modules&localIdentName=_[local]");
testLocal("mode switching", ".c1 :local .c2 .c3 :global .c4 :local .c5, .c6 :local .c7 { background: red; }\n.c8 { background: red; }", [
[1, ".c1 ._c2 ._c3 .c4 ._c5, .c6 ._c7 { background: red; }\n.c8 { background: red; }", ""]
], {
c2: "_c2",
c3: "_c3",
c5: "_c5",
c7: "_c7"
}, "?localIdentName=_[local]");
}, "?modules&moduleMode=global&localIdentName=_[local]");
testLocal("comment in local", ":local(.c1/*.c2*/.c3) { background: red; }", [
[1, "._c1._c3 { background: red; }", ""]
], {
c1: "_c1",
c3: "_c3"
}, "?localIdentName=_[local]");
}, "?modules&localIdentName=_[local]");
testLocal("comment in local", ":local(.c1/*.c2*/.c3) { background: red; }", [
[1, "._c1._c3 { background: red; }", ""]
], {
c1: "_c1",
c3: "_c3"
}, "?localIdentName=_[local]");
}, "?modules&localIdentName=_[local]");
testLocal("strings in local", ":local(.c1[data-attr=\".c2)]'\"]:not(.c3):not(.c4)) { background: red; }", [
[1, "._c1[data-attr=\".c2)]'\"]:not(._c3):not(._c4) { background: red; }", ""]
], {
c1: "_c1",
c3: "_c3",
c4: "_c4"
}, "?localIdentName=_[local]");
}, "?modules&localIdentName=_[local]");

testLocal("composes class simple", ":local(.c1) { a: 1; }\n:local(.c2) { composes: c1; b: 1; }", [
[1, "._c1 { a: 1; }\n._c2 { b: 1; }", ""]
], {
c1: "_c1",
c2: "_c2 _c1"
}, "?localIdentName=_[local]");
}, "?modules&localIdentName=_[local]");
testLocal("composes class from module", [
":local(.c1) { composes: c2 from \"./module\"; b: 1; }",
":local(.c3) { composes: c1; b: 3; }",
Expand All @@ -84,7 +84,7 @@ describe("local", function() {
c1: "_c1 imported-c2",
c3: "_c3 _c1 imported-c2",
c5: "_c5 imported-c2 imported-c4"
}, "?localIdentName=_[local]", {
}, "?modules&localIdentName=_[local]", {
"./module": (function() {
var r = [
[2, ".test{c: d}", ""]
Expand All @@ -111,7 +111,7 @@ describe("local", function() {
c1: "_c1 imported-c-2",
c3: "_c3 _c1 imported-c-2",
c5: "_c5 imported-c-2 imported-c4"
}, "?localIdentName=_[local]", {
}, "?modules&localIdentName=_[local]", {
"./module": (function() {
var r = [
[2, ".test{c: d}", ""]
Expand All @@ -131,7 +131,7 @@ describe("local", function() {
[1, "._c1 { b: 1; }", ""]
], {
c1: "_c1 imported-c2 imported-c3 imported-c4"
}, "?localIdentName=_[local]", {
}, "?modules&moduleMode=global&localIdentName=_[local]", {
"./module": (function() {
var r = [
[2, ".test{c: d}", ""]
Expand All @@ -152,18 +152,18 @@ describe("local", function() {
className: "_23J0282swY7bwvI2X4fHiV",
someId: "_3vpqN0v_IxlO3TzQjbpB33",
subClass: "_1s1VsToXFz17cPAltMg7jz"
}, "?module");
}, "?modules");
testLocal("class name parsing", ".-a0-34a___f { color: red; }", [
[1, "._3ZMCqVa1XidxdqbX65hZ5D { color: red; }", ""]
], {
"-a0-34a___f": "_3ZMCqVa1XidxdqbX65hZ5D"
}, "?module");
}, "?modules");
testLocal("imported values in decl", ".className { color: IMPORTED_NAME; }\n" +
":import(\"./vars.css\") { IMPORTED_NAME: primary-color; }", [
[1, "._className { color: red; }", ""]
], {
"className": "_className"
}, "?module&localIdentName=_[local]", {
}, "?modules&localIdentName=_[local]", {
"./vars.css": {
locals: {
"primary-color": "red"
Expand Down Expand Up @@ -206,15 +206,15 @@ describe("local", function() {
[1, "._1test { background: red; }", ""]
], {
test: "_1test"
}, "?localIdentName=1[local]");
}, "?modules&localIdentName=1[local]");
testLocal("prefixes leading hyphen + digit with underscore", ":local(.test) { background: red; }", [
[1, "._-1test { background: red; }", ""]
], {
test: "_-1test"
}, "?localIdentName=-1[local]");
}, "?modules&localIdentName=-1[local]");
testLocal("prefixes two leading hyphens with underscore", ":local(.test) { background: red; }", [
[1, "._--test { background: red; }", ""]
], {
test: "_--test"
}, "?localIdentName=--[local]");
}, "?modules&localIdentName=--[local]");
});
8 changes: 4 additions & 4 deletions test/localsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ describe("locals", function() {
ghi: "_ghi",
jkl: "_jkl"
},
"?localIdentName=_[local]"
"?modules&moduleMode=global&localIdentName=_[local]"
);
testLocals("should return only locals with composing",
":local(.abc) { color: red; } :local(.def) { composes: abc; background: green; }",
{
abc: "_abc",
def: "_def _abc"
},
"?localIdentName=_[local]"
"?modules&localIdentName=_[local]"
);
testLocals("should return only locals with importing",
":local(.abc) { composes: def from \"./module.css\"; }",
{
abc: "_abc imported_def imported_ghi"
},
"?localIdentName=_[local]",
"?modules&localIdentName=_[local]",
{
"./module.css": {
def: "imported_def imported_ghi",
Expand All @@ -38,7 +38,7 @@ describe("locals", function() {
{
abc: "_abc imported_def1 imported_ghi1 imported_def2"
},
"?localIdentName=_[local]",
"?modules&localIdentName=_[local]",
{
"./module1.css": {
def: "imported_def1 imported_ghi1",
Expand Down
Loading