细说webpack源码之compile流程-rules参数处理技巧(2(4)
比起对test的处理,这里就简单的多,简述如下:
1、尝试取出options(query)中的ident参数,赋值给newItem的ident,没有就赋值为默认的ref-
2、取出对象中不是options、query的键,赋值给newItem,这里传进来的键只有三个,剩下的就是loader,这个filter是逗我???
3、返回newItem对象
总之,不知道为什么防止什么意外情况而写出来的垃圾代码,这段代码其实十分简单。
单loader
第二种情况是单字符串,会对'!'进行切割调用map方法处理,再调用reduce方法扁平化为一个数组,直接看normalizeUseItemString方法:
/*
Example:
{
test: /\.css$/,
loader: 'css-loader?{opt:1}!style-loader'
}
返回:
[{loader:'css-loader',options:{opt:1}},
{loader:'style-loader'}]
*/
static normalizeUseItemString(useItemString) {
// 根据'?'切割获取loader的参数
const idx = useItemString.indexOf("?");
if (idx >= 0) {
return {
loader: useItemString.substr(0, idx),
// 后面的作为options返回
options: useItemString.substr(idx + 1)
};
}
return {
loader: useItemString
};
}
这种就是串行调用loader的处理方式,代码很简单。
Tips
这里有一点要注意,一旦loader使用了串行调用方式,不要传options或者query参数,不然loader不会被切割解析!!!
这两种方式只是不同的使用方法,最后的结果都是一样的。
use
下面是use参数的解析,估计因为这是老版的API,所以格式要求严格,处理比较随便:
if (rule.use) {
checkUseSource("use");
newRule.use = RuleSet.normalizeUse(rule.use, ident);
}
如果不用loader(s),可以用use替代,但是需要按照格式写,比如说上述串行简写的loader,在use中就需要这样写:
/*
{
test:/\.css$/,
user:['css-loader','style-loader]
}
*/
而对应options或query,需要这样写:
/*
{
test:/\.css$/,
user:{
loader:'css-loader',
options:'1'
}
}
*/
因为基本上不用了,所以这里简单看一下。
rules、oneOf
if (rule.rules)
newRule.rules = RuleSet.normalizeRules(rule.rules, refs, `${ident}-rules`);
if (rule.oneOf)
newRule.oneOf = RuleSet.normalizeRules(rule.oneOf, refs, `${ident}-oneOf`);
这两个用得少,也没啥难理解的。
下一步是过滤出没有处理的参数,添加到newRuls上:
const keys = Object.keys(rule).filter((key) => {
return ["resource", "resourceQuery", "compiler", "test", "include", "exclude", "issuer", "loader", "options", "query", "loaders", "use", "rules", "oneOf"].indexOf(key) < 0;
});
keys.forEach((key) => {
newRule[key] = rule[key];
});
内容版权声明:除非注明,否则皆为本站原创文章。
