chushihua
This commit is contained in:
+264
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
var formatCodeFrame = require("babel-code-frame");
|
||||
var Tokenizer = require("css-selector-tokenizer");
|
||||
var postcss = require("postcss");
|
||||
var loaderUtils = require("loader-utils");
|
||||
var assign = require("object-assign");
|
||||
var getLocalIdent = require("./getLocalIdent");
|
||||
|
||||
var icssUtils = require('icss-utils');
|
||||
var localByDefault = require("postcss-modules-local-by-default");
|
||||
var extractImports = require("postcss-modules-extract-imports");
|
||||
var modulesScope = require("postcss-modules-scope");
|
||||
var modulesValues = require("postcss-modules-values");
|
||||
var valueParser = require('postcss-value-parser');
|
||||
|
||||
var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
|
||||
return function(css) {
|
||||
var imports = {};
|
||||
var exports = {};
|
||||
var importItems = [];
|
||||
var urlItems = [];
|
||||
|
||||
function replaceImportsInString(str) {
|
||||
if(options.import) {
|
||||
var tokens = valueParser(str);
|
||||
tokens.walk(function (node) {
|
||||
if (node.type !== 'word') {
|
||||
return;
|
||||
}
|
||||
var token = node.value;
|
||||
var importIndex = imports["$" + token];
|
||||
if(typeof importIndex === "number") {
|
||||
node.value = "___CSS_LOADER_IMPORT___" + importIndex + "___";
|
||||
}
|
||||
})
|
||||
return tokens.toString();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
if(options.import) {
|
||||
css.walkAtRules(/^import$/i, function(rule) {
|
||||
var values = Tokenizer.parseValues(rule.params);
|
||||
var url = values.nodes[0].nodes[0];
|
||||
if(url && url.type === "url") {
|
||||
url = url.url;
|
||||
} else if(url && url.type === "string") {
|
||||
url = url.value;
|
||||
} else throw rule.error("Unexpected format " + rule.params);
|
||||
if (!url.replace(/\s/g, '').length) {
|
||||
return;
|
||||
}
|
||||
values.nodes[0].nodes.shift();
|
||||
var mediaQuery = Tokenizer.stringifyValues(values);
|
||||
|
||||
if(loaderUtils.isUrlRequest(url, options.root)) {
|
||||
url = loaderUtils.urlToRequest(url, options.root);
|
||||
}
|
||||
|
||||
importItems.push({
|
||||
url: url,
|
||||
mediaQuery: mediaQuery
|
||||
});
|
||||
rule.remove();
|
||||
});
|
||||
}
|
||||
|
||||
var icss = icssUtils.extractICSS(css);
|
||||
exports = icss.icssExports;
|
||||
Object.keys(icss.icssImports).forEach(function(key) {
|
||||
var url = loaderUtils.parseString(key);
|
||||
Object.keys(icss.icssImports[key]).forEach(function(prop) {
|
||||
imports["$" + prop] = importItems.length;
|
||||
importItems.push({
|
||||
url: url,
|
||||
export: icss.icssImports[key][prop]
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
Object.keys(exports).forEach(function(exportName) {
|
||||
exports[exportName] = replaceImportsInString(exports[exportName]);
|
||||
});
|
||||
|
||||
function isAlias(url) {
|
||||
// Handle alias starting by / and root disabled
|
||||
return url !== options.resolve(url)
|
||||
}
|
||||
|
||||
function processNode(item) {
|
||||
switch (item.type) {
|
||||
case "value":
|
||||
item.nodes.forEach(processNode);
|
||||
break;
|
||||
case "nested-item":
|
||||
item.nodes.forEach(processNode);
|
||||
break;
|
||||
case "item":
|
||||
var importIndex = imports["$" + item.name];
|
||||
if (typeof importIndex === "number") {
|
||||
item.name = "___CSS_LOADER_IMPORT___" + importIndex + "___";
|
||||
}
|
||||
break;
|
||||
case "url":
|
||||
if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && (isAlias(item.url) || loaderUtils.isUrlRequest(item.url, options.root))) {
|
||||
// Strip quotes, they will be re-added if the module needs them
|
||||
item.stringType = "";
|
||||
delete item.innerSpacingBefore;
|
||||
delete item.innerSpacingAfter;
|
||||
var url = item.url;
|
||||
item.url = "___CSS_LOADER_URL___" + urlItems.length + "___";
|
||||
urlItems.push({
|
||||
url: url
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
css.walkDecls(function(decl) {
|
||||
var values = Tokenizer.parseValues(decl.value);
|
||||
values.nodes.forEach(function(value) {
|
||||
value.nodes.forEach(processNode);
|
||||
});
|
||||
decl.value = Tokenizer.stringifyValues(values);
|
||||
});
|
||||
css.walkAtRules(function(atrule) {
|
||||
if(typeof atrule.params === "string") {
|
||||
atrule.params = replaceImportsInString(atrule.params);
|
||||
}
|
||||
});
|
||||
|
||||
options.importItems = importItems;
|
||||
options.urlItems = urlItems;
|
||||
options.exports = exports;
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = function processCss(inputSource, inputMap, options, callback) {
|
||||
var query = options.query;
|
||||
var root = query.root && query.root.length > 0 ? query.root.replace(/\/$/, "") : query.root;
|
||||
var context = query.context;
|
||||
var localIdentName = query.localIdentName || "[hash:base64]";
|
||||
var localIdentRegExp = query.localIdentRegExp;
|
||||
var forceMinimize = query.minimize;
|
||||
var minimize = typeof forceMinimize !== "undefined" ? !!forceMinimize : options.minimize;
|
||||
|
||||
var customGetLocalIdent = query.getLocalIdent || getLocalIdent;
|
||||
|
||||
var parserOptions = {
|
||||
root: root,
|
||||
mode: options.mode,
|
||||
url: query.url !== false,
|
||||
import: query.import !== false,
|
||||
resolve: options.resolve
|
||||
};
|
||||
|
||||
var pipeline = postcss([
|
||||
modulesValues,
|
||||
localByDefault({
|
||||
mode: options.mode,
|
||||
rewriteUrl: function(global, url) {
|
||||
if(parserOptions.url){
|
||||
url = url.trim();
|
||||
|
||||
if(!url.replace(/\s/g, '').length || !loaderUtils.isUrlRequest(url, root)) {
|
||||
return url;
|
||||
}
|
||||
if(global) {
|
||||
return loaderUtils.urlToRequest(url, root);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}),
|
||||
extractImports(),
|
||||
modulesScope({
|
||||
generateScopedName: function generateScopedName (exportName) {
|
||||
return customGetLocalIdent(options.loaderContext, localIdentName, exportName, {
|
||||
regExp: localIdentRegExp,
|
||||
hashPrefix: query.hashPrefix || "",
|
||||
context: context
|
||||
});
|
||||
}
|
||||
}),
|
||||
parserPlugin(parserOptions)
|
||||
]);
|
||||
|
||||
if(minimize) {
|
||||
var cssnano = require("cssnano");
|
||||
var minimizeOptions = assign({}, query.minimize);
|
||||
["zindex", "normalizeUrl", "discardUnused", "mergeIdents", "reduceIdents", "autoprefixer"].forEach(function(name) {
|
||||
if(typeof minimizeOptions[name] === "undefined")
|
||||
minimizeOptions[name] = false;
|
||||
});
|
||||
pipeline.use(cssnano(minimizeOptions));
|
||||
}
|
||||
|
||||
pipeline.process(inputSource, {
|
||||
// we need a prefix to avoid path rewriting of PostCSS
|
||||
from: "/css-loader!" + options.from,
|
||||
to: options.to,
|
||||
map: options.sourceMap ? {
|
||||
prev: inputMap,
|
||||
sourcesContent: true,
|
||||
inline: false,
|
||||
annotation: false
|
||||
} : null
|
||||
}).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) {
|
||||
if (err.name === 'CssSyntaxError') {
|
||||
var wrappedError = new CSSLoaderError(
|
||||
'Syntax Error',
|
||||
err.reason,
|
||||
err.line != null && err.column != null
|
||||
? {line: err.line, column: err.column}
|
||||
: null,
|
||||
err.input.source
|
||||
);
|
||||
callback(wrappedError);
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function formatMessage(message, loc, source) {
|
||||
var formatted = message;
|
||||
if (loc) {
|
||||
formatted = formatted
|
||||
+ ' (' + loc.line + ':' + loc.column + ')';
|
||||
}
|
||||
if (loc && source) {
|
||||
formatted = formatted
|
||||
+ '\n\n' + formatCodeFrame(source, loc.line, loc.column) + '\n';
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
function CSSLoaderError(name, message, loc, source, error) {
|
||||
Error.call(this);
|
||||
Error.captureStackTrace(this, CSSLoaderError);
|
||||
this.name = name;
|
||||
this.error = error;
|
||||
this.message = formatMessage(message, loc, source);
|
||||
this.hideStack = true;
|
||||
}
|
||||
|
||||
CSSLoaderError.prototype = Object.create(Error.prototype);
|
||||
CSSLoaderError.prototype.constructor = CSSLoaderError;
|
||||
Reference in New Issue
Block a user