kuyin-webpack-plugins
Version:
custom webpack, enhanced-resolve plugins
109 lines (108 loc) • 4.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const path_1 = tslib_1.__importDefault(require("path"));
const utils_1 = require("../utils");
function getAlias() {
const { compilerOptions } = global;
if (!compilerOptions || !compilerOptions.resolve || !compilerOptions.resolve.alias) {
utils_1.debug('FallbackResolvePlugin插件需要和DefineGlobalsWebpackPlugin插件配合使用');
return {};
}
return compilerOptions.resolve.alias;
}
// 参数标准化
function normalizeOptions({ pattern, fallbackPath }) {
if (!Array.isArray(fallbackPath)) {
fallbackPath = [fallbackPath];
}
fallbackPath = fallbackPath.map(item => {
if (typeof item === 'string') {
return {
path: item,
useWhenPatternNotFound: (_request) => true,
};
}
if (item.useWhenPatternNotFound === undefined) {
item.useWhenPatternNotFound = true;
}
return {
path: item.path,
useWhenPatternNotFound: typeof item.useWhenPatternNotFound === 'function'
? item.useWhenPatternNotFound
: (_request) => !!item.useWhenPatternNotFound,
};
});
return {
pattern,
fallbackPath,
};
}
class FallbackResolvePlugin {
constructor(options) {
this.options = options;
}
apply(resolver) {
const { pattern, fallbackPath } = normalizeOptions(this.options);
// enhanced-resolve源码在执行AliasPlugin前会触发described-resolve钩子
// 执行之后会触发resolve钩子
resolver.getHook('described-resolve').tapAsync('FallbackResolvePlugin', (request, resolveContext, callback) => {
const innerRequest = request.request || request.path;
const alias = getAlias();
// 不需要处理的文件提前终止本插件
if (!pattern.test(innerRequest)) {
return callback();
}
const keys = Object.keys(alias);
let i = keys.length;
while (i--) {
const key = keys[i];
if (utils_1.startsWith(innerRequest, key)) {
const realPath = alias[key];
const oldRequestStr = path_1.default.resolve(realPath, innerRequest.substr(key.length + 1));
const excludedFallbackPath = fallbackPath
.filter(item => {
return utils_1.existsSync(path_1.default.resolve(item.path, innerRequest.substr(key.length + 1)));
})
.map(item => {
return {
...item,
path: path_1.default.resolve(item.path, innerRequest.substr(key.length + 1)),
};
});
let item;
if (excludedFallbackPath.length > 0) {
// eslint-disable-next-line
item = excludedFallbackPath[0];
}
else {
item = {
path: oldRequestStr,
useWhenPatternNotFound: (_request) => true,
};
}
if (!item.useWhenPatternNotFound(request) ||
(item.useWhenPatternNotFound(request) && !utils_1.existsSync(oldRequestStr))) {
const newRequestStr = item.path;
if (!utils_1.existsSync(oldRequestStr)) {
utils_1.info(`${oldRequestStr}不存在,将使用${newRequestStr}`);
}
const obj = Object.assign({}, request, {
request: newRequestStr,
});
return resolver.doResolve('resolve', obj, `FallbackResolvePlugin 使用默认路径${newRequestStr}`, resolveContext, (err, result) => {
if (err)
return callback(err);
// Don't allow other aliasing or raw request
if (result === undefined)
return callback(null, null);
return callback(null, result);
});
}
}
}
return callback();
});
}
}
exports.FallbackResolvePlugin = FallbackResolvePlugin;