Skip to content

Commit

Permalink
async api
Browse files Browse the repository at this point in the history
postcss 5

fixes #95
  • Loading branch information
sokra committed Sep 10, 2015
1 parent 5c5bc39 commit 724717e
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 210 deletions.
165 changes: 84 additions & 81 deletions lib/loader.js
Expand Up @@ -10,6 +10,7 @@ var getImportPrefix = require("./getImportPrefix");

module.exports = function(content, map) {
if(this.cacheable) this.cacheable();
var callback = this.async();
var query = loaderUtils.parseQuery(this.query);
var root = query.root;
var moduleMode = query.modules || query.module;
Expand All @@ -18,102 +19,104 @@ module.exports = function(content, map) {
map = JSON.stringify(map);
}

var result = processCss(content, map, {
processCss(content, map, {
mode: moduleMode ? "local" : "global",
from: loaderUtils.getRemainingRequest(this),
to: loaderUtils.getCurrentRequest(this),
query: query,
minimize: this.minimize,
loaderContext: this
});
}, function(err, result) {
if(err) return callback(err);

var cssAsString = JSON.stringify(result.source);
var cssAsString = JSON.stringify(result.source);

// for importing CSS
var importUrlPrefix = getImportPrefix(this, query);
// for importing CSS
var importUrlPrefix = getImportPrefix(this, query);

var alreadyImported = {};
var importJs = result.importItems.filter(function(imp) {
if(!imp.mediaQuery) {
if(alreadyImported[imp.url])
return false;
alreadyImported[imp.url] = true;
}
return true;
}).map(function(imp) {
if(!loaderUtils.isUrlRequest(imp.url, root)) {
return "exports.push([module.id, " +
JSON.stringify("@import url(" + imp.url + ");") + ", " +
JSON.stringify(imp.mediaQuery) + "]);";
} else {
var importUrl = importUrlPrefix + imp.url;
return "exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), " + JSON.stringify(imp.mediaQuery) + ");";
var alreadyImported = {};
var importJs = result.importItems.filter(function(imp) {
if(!imp.mediaQuery) {
if(alreadyImported[imp.url])
return false;
alreadyImported[imp.url] = true;
}
return true;
}).map(function(imp) {
if(!loaderUtils.isUrlRequest(imp.url, root)) {
return "exports.push([module.id, " +
JSON.stringify("@import url(" + imp.url + ");") + ", " +
JSON.stringify(imp.mediaQuery) + "]);";
} else {
var importUrl = importUrlPrefix + imp.url;
return "exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), " + JSON.stringify(imp.mediaQuery) + ");";
}
}, this).join("\n");

function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ").locals" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}
}, this).join("\n");

function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ").locals" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}
cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this)).replace(result.urlItemRegExpG, function(item) {
var match = result.urlItemRegExp.exec(item);
var idx = +match[1];
var urlItem = result.urlItems[idx];
var url = urlItem.url;
idx = url.indexOf("?#");
if(idx < 0) idx = url.indexOf("#");
var urlRequest;
if(idx > 0) { // idx === 0 is catched by isUrlRequest
// in cases like url('webfont.eot?#iefix')
urlRequest = url.substr(0, idx);
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"" +
url.substr(idx);
}
urlRequest = url;
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"";
}.bind(this));

cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this)).replace(result.urlItemRegExpG, function(item) {
var match = result.urlItemRegExp.exec(item);
var idx = +match[1];
var urlItem = result.urlItems[idx];
var url = urlItem.url;
idx = url.indexOf("?#");
if(idx < 0) idx = url.indexOf("#");
var urlRequest;
if(idx > 0) { // idx === 0 is catched by isUrlRequest
// in cases like url('webfont.eot?#iefix')
urlRequest = url.substr(0, idx);
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"" +
url.substr(idx);
var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "exports.locals = {\n" + exportJs + "\n};";
}
urlRequest = url;
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"";
}.bind(this));

var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "exports.locals = {\n" + exportJs + "\n};";
}


var moduleJs;
if(query.sourceMap && result.map) {
// add a SourceMap
map = result.map;
if(map.sources) {
map.sources = map.sources.map(function(source) {
var p = path.relative(query.context || this.options.context, source).replace(/\\/g, "/");
if(p.indexOf("../") !== 0)
p = "./" + p;
return "/" + p;
}, this);
map.sourceRoot = "webpack://";
var moduleJs;
if(query.sourceMap && result.map) {
// add a SourceMap
map = result.map;
if(map.sources) {
map.sources = map.sources.map(function(source) {
var p = path.relative(query.context || this.options.context, source).replace(/\\/g, "/");
if(p.indexOf("../") !== 0)
p = "./" + p;
return "/" + p;
}, this);
map.sourceRoot = "webpack://";
}
map = JSON.stringify(map);
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\", " + map + "]);";
} else {
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\"]);";
}
map = JSON.stringify(map);
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\", " + map + "]);";
} else {
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\"]);";
}

// embed runtime
return "exports = module.exports = require(" + loaderUtils.stringifyRequest(this, require.resolve("./css-base.js")) + ")();\n" +
"// imports\n" +
importJs + "\n\n" +
"// module\n" +
moduleJs + "\n\n" +
"// exports\n" +
exportJs;
// embed runtime
callback(null, "exports = module.exports = require(" + loaderUtils.stringifyRequest(this, require.resolve("./css-base.js")) + ")();\n" +
"// imports\n" +
importJs + "\n\n" +
"// module\n" +
moduleJs + "\n\n" +
"// exports\n" +
exportJs);
}.bind(this));
};
47 changes: 25 additions & 22 deletions lib/localsLoader.js
Expand Up @@ -9,37 +9,40 @@ var getImportPrefix = require("./getImportPrefix");

module.exports = function(content) {
if(this.cacheable) this.cacheable();
var callback = this.async();
var query = loaderUtils.parseQuery(this.query);
var moduleMode = query.modules || query.module;

var result = processCss(content, null, {
processCss(content, null, {
mode: moduleMode ? "local" : "global",
query: query,
minimize: this.minimize,
loaderContext: this
});
}, function(err, result) {
if(err) return callback(err);

// for importing CSS
var importUrlPrefix = getImportPrefix(this, query);
// for importing CSS
var importUrlPrefix = getImportPrefix(this, query);

function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ")" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}
function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ")" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}

var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "module.exports = {\n" + exportJs + "\n};";
}
var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "module.exports = {\n" + exportJs + "\n};";
}

return exportJs;
callback(null, exportJs);
}.bind(this));
};
60 changes: 41 additions & 19 deletions lib/processCss.js
Expand Up @@ -31,7 +31,28 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
return tokens.join("");
}

css.eachAtRule("import", function(rule) {
function walkAtRules(a, b) {
if(css.walkAtRules)
css.walkAtRules(a, b);
else
css.eachAtRule(a, b);
}

function walkRules(fn) {
if(css.walkRules)
css.walkRules(fn);
else
css.eachRule(fn);
}

function walkDecls(fn) {
if(css.walkDecls)
css.walkDecls(fn);
else
css.eachDecl(fn);
}

walkAtRules("import", function(rule) {
var values = Tokenizer.parseValues(rule.params);
var url = values.nodes[0].nodes[0];
if(url.type === "url") {
Expand All @@ -51,7 +72,7 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
rule.removeSelf();
});

css.eachRule(function(rule) {
walkRules(function(rule) {
if(rule.selector === ":export") {
rule.eachDecl(function(decl) {
exports[decl.prop] = decl.value;
Expand All @@ -75,7 +96,7 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
exports[exportName] = replaceImportsInString(exports[exportName]);
});

css.eachDecl(function(decl) {
walkDecls(function(decl) {
var values = Tokenizer.parseValues(decl.value);
values.nodes.forEach(function(value) {
value.nodes.forEach(function(item) {
Expand Down Expand Up @@ -103,7 +124,7 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
});
decl.value = Tokenizer.stringifyValues(values);
});
css.eachAtRule(function(atrule) {
walkAtRules(function(atrule) {
if(typeof atrule.params === "string") {
atrule.params = replaceImportsInString(atrule.params);
}
Expand All @@ -115,7 +136,7 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
};
});

module.exports = function processCss(inputSource, inputMap, options) {
module.exports = function processCss(inputSource, inputMap, options, callback) {

var query = options.query;
var root = query.root;
Expand Down Expand Up @@ -162,7 +183,7 @@ module.exports = function processCss(inputSource, inputMap, options) {
pipeline.use(cssnano(minimizeOptions));
}

var result = pipeline.process(inputSource, {
pipeline.process(inputSource, {
from: options.from,
to: options.to,
map: {
Expand All @@ -171,18 +192,19 @@ module.exports = function processCss(inputSource, inputMap, options) {
inline: false,
annotation: false
}
}).then(function(result) {
callback(null, {
source: result.css,
map: result.map && result.map.toJSON(),
exports: parserOptions.exports,
importItems: parserOptions.importItems,
importItemRegExpG: /___CSS_LOADER_IMPORT___([0-9]+)___/g,
importItemRegExp: /___CSS_LOADER_IMPORT___([0-9]+)___/,
urlItems: parserOptions.urlItems,
urlItemRegExpG: /___CSS_LOADER_URL___([0-9]+)___/g,
urlItemRegExp: /___CSS_LOADER_URL___([0-9]+)___/
});
}).catch(function(err) {
callback(err);
});


return {
source: result.css,
map: result.map && result.map.toJSON(),
exports: parserOptions.exports,
importItems: parserOptions.importItems,
importItemRegExpG: /___CSS_LOADER_IMPORT___([0-9]+)___/g,
importItemRegExp: /___CSS_LOADER_IMPORT___([0-9]+)___/,
urlItems: parserOptions.urlItems,
urlItemRegExpG: /___CSS_LOADER_URL___([0-9]+)___/g,
urlItemRegExp: /___CSS_LOADER_URL___([0-9]+)___/
};
};
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -5,9 +5,9 @@
"description": "css loader module for webpack",
"dependencies": {
"css-selector-tokenizer": "^0.5.1",
"cssnano": "^2.6.1",
"cssnano": ">=2.6.1 <4",
"loader-utils": "~0.2.2",
"postcss": "^4.1.11",
"postcss": ">=4.1.11 <6",
"postcss-modules-extract-imports": "0.0.5",
"postcss-modules-local-by-default": "0.0.12",
"postcss-modules-scope": "0.0.8",
Expand Down

0 comments on commit 724717e

Please sign in to comment.