官方实现
2024年04月06日
一、实现
二、测试
2.1 test/webpack/bolawen01/loader-runner/loaders
test/webpack/bolawen01/loader-runner/loaders
用于存放 inline-loader
、normal-loader
、post-loader
、pre-loader
function loader(source) {
console.log('inline1', source);
return source + '//inline1';
}
loader.pitch = function () {
console.log('inline1 pitch');
};
module.exports = loader;
function loader(source) {
console.log('normal1', source);
return source + '//normal1';
}
loader.pitch = function () {
console.log('normal1');
};
module.exports = loader;
function loader(source) {
console.log('post1', source);
return source + '//post1';
}
loader.pitch = function () {
console.log('post1 pitch');
};
module.exports = loader;
function loader(source) {
console.log('pre1', source);
return source + '//pre1';
}
loader.pitch = function () {
console.log('pre1 pitch');
};
module.exports = loader;
2.2 test/webpack/bolawen01/loader-runner/index.js
const Fs = require('fs');
const Path = require('path');
const { runLoaders } = require('loader-runner');
const filePath = Path.resolve(__dirname, './test.js');
const request = 'inline1-loader!inline2-loader!./test.js';
const rules = [
{
test: /\.js$/,
use: ['normal1-loader', 'normal2-loader']
},
{
test: /\.js$/,
use: ['pre1-loader', 'pre2-loader'],
enforce: 'pre'
},
{
test: /\.js$/,
enforce: 'post',
use: ['post1-loader', 'post2-loader']
}
];
const parts = request.replace(/^-?!+/, '').split('!');
const sourcePath = parts.pop();
const inlineLoaders = parts;
const preLoaders = [];
const normalLoaders = [];
const postLoaders = [];
rules.forEach(rule => {
if (rule.test.test(sourcePath)) {
switch (rule.enforce) {
case 'pre':
preLoaders.push(...rule.use);
break;
case 'post':
postLoaders.push(...rule.use);
break;
default:
normalLoaders.push(...rule.use);
}
}
});
/**
* @description: 根据 inlineLoader 规则过滤 loader
* !:单个 ! 开头, 排除所有 normal-loader
* !!: 两个 !! 开头, 排除所有 pre-loader、normal-loader、post-loader
* -!: 一个 -! 开头, 排除所有 pre-loader、normal-loader
*/
let loaders = [];
if (request.startsWith('!!')) {
loaders.push(...inlineLoaders);
} else if (request.startsWith('-!')) {
loaders.push(...postLoaders, ...inlineLoaders);
} else if (request.startsWith('!')) {
loaders.push(...postLoaders, ...inlineLoaders, ...preLoaders);
} else {
loaders.push(
...postLoaders,
...inlineLoaders,
...normalLoaders,
...preLoaders
);
}
const resolveLoader = loader => {
return Path.resolve(__dirname, './loaders', loader);
};
loaders = loaders.map(resolveLoader);
runLoaders(
{
resource: filePath,
loaders,
context: { name: 'bolawen' },
readResource: Fs.readFile.bind(Fs)
},
(error, result) => {
console.log('result', result);
}
);