细说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]; });
内容版权声明:除非注明,否则皆为本站原创文章。