细说webpack源码之compile流程-rules参数处理技巧(2(2)
这里用js的rules做案例,看这个方法的返回:
class RuleSet {
constructor(rules) { /**/ };
/*
Example:
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
}
*/
/*
condition:
{
test: /\.js$/,
include: ['d:\\workspace\\src', 'd:\\workspace\\test'],
exclude: undefined
}
*/
static normalizeCondition(condition) {
// include返回类似于 [(str) => str.indexOf('d:\\workspace\\src') === 0,...] 的函数
if (typeof condition === "string") { return str => str.indexOf(condition) === 0; }
// test参数返回了 /\.js$/.test 函数
if (condition instanceof RegExp) { return condition.test.bind(condition); }
// include为数组
if (Array.isArray(condition)) {
const items = condition.map(c => RuleSet.normalizeCondition(c));
return orMatcher(items);
}
const matchers = [];
// 解析出['test','include','exclude']
Object.keys(condition).forEach(key => {
const value = condition[key];
switch (key) {
// 此value为一个数组
case "include":
case "test":
if (value)
matchers.push(RuleSet.normalizeCondition(value));
break;
// undefined跳过
case "exclude":
if (value) { /**/ }
break;
default:
throw new Error("Unexcepted property " + key + " in condition");
}
});
return andMatcher(matchers);
}
}
这里继续看orMatcher、andMatcher函数的处理:
function orMatcher(items) {
// 当一个函数被满足条件时返回true
return function(str) {
for (let i = 0; i < items.length; i++) {
if (items[i](str))
return true;
}
return false;
};
}
function andMatcher(items) {
// 当一个条件不满足时返回false
return function(str) {
for (let i = 0; i < items.length; i++) {
if (!items[i](str))
return false;
}
return true;
};
}
从字面意思也可以理解函数作用,比如说这里的include被包装成一个orMatcher函数,传入的字符串无论是以数组中任何一个元素开头都会返回true,andMatcher以及未出现的notMatcher同理。
resource
下面是对resource参数的处理,源码如下:
if (rule.resource) {
// 如果前面检测到了test || include || exclude参数 这里会报错
checkResourceSource("resource");
try {
newRule.resource = RuleSet.normalizeCondition(rule.resource);
} catch (error) {
throw new Error(RuleSet.buildErrorMessage(rule.resource, error));
}
}
可以看出这个参数与前面那个是互斥的,应该是老版API,下面两种方式实现是一样的:
/*
方式1:
rules:[
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
}
]
*/
/*
方式2:
rules:[
{
resource:{
test: /\.js$/,
include: [resolve('src'), resolve('test')]
exclude: undefined
}
}
]
*/
内容版权声明:除非注明,否则皆为本站原创文章。
