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