webpack自定义loader的核心是导出一个函数,接收源码字符串(或buffer)作为输入,返回转换后的代码字符串(或ast),通过return或this.callback向下传递结果;它在模块构建阶段被调用,按配置从右到左链式执行,必须为commonjs模块,且保持无副作用。

Webpack 自定义 Loader 的核心是导出一个函数,接收源码字符串作为输入,返回转换后的代码字符串(或 AST 对象),并在函数内通过 this.callback 或 return 向下传递结果。
Loader 基本结构与执行时机
Loader 是一个导出函数的 Node.js 模块,在模块构建阶段被 Webpack 调用。它运行在 Node 环境中,接收原始资源内容(通常是字符串或 Buffer),可同步或异步处理后输出新内容。Webpack 会按配置中的顺序(从右到左、从下到上)链式调用多个 Loader。
- 必须是 CommonJS 模块,使用
module.exports = function(source) { ... } - 函数内部
this是 Loader Context,提供this.callback、this.async()、this.resourcePath等方法和属性 - 同步 Loader 直接
return结果;异步 Loader 需调用this.async()获取回调函数再调用this.callback
编写一个简单的同步 Loader
比如把 JS 文件里的所有 console.log 替换为注释(简单字符串替换):
// remove-console-loader.js
module.exports = function(source) {
const newSource = source.replace(/console\.log\([^)]*\);?/g, '// console.log removed');
return newSource;
};
在 webpack.config.js 中使用:
module.exports = {
module: {
rules: [{
test: /\.js$/,
use: ['./remove-console-loader.js']
}]
}
};
支持异步与 SourceMap 的 Loader
当需要异步操作(如调用外部 API、读取文件)或生成 SourceMap 时,必须使用异步模式:
module.exports = function(source, sourceMap) {
const callback = this.async();
// 模拟异步处理(例如调用 Babel)
setTimeout(() => {
const result = source.replace(/debugger/g, '// debugger removed');
// 第二个参数是转换后代码,第三个是 sourceMap(可选),第四个是 AST(可选)
callback(null, result, sourceMap);
}, 100);
};
注意:this.callback 参数顺序为 (error, content, sourceMap, ast),其中 content 必须是字符串或 Buffer。
Loader 接收参数并做配置化处理
可通过 this.getOptions() 获取在 use 中传入的 options(需安装 loader-utils 并验证 schema):
const { getOptions } = require('loader-utils');
const validateOptions = require('schema-utils');
module.exports = function(source) {
const options = getOptions(this);
const schema = { type: 'object', properties: { replaceWith: { type: 'string' } } };
validateOptions(schema, options, 'My Custom Loader');
const replacement = options.replaceWith || '// removed';
const result = source.replace(/console\.log\([^)]*\);?/g, replacement);
return result;
};
配置中使用:
use: [{
loader: './my-loader.js',
options: { replaceWith: '// LOG DISABLED' }
}]
注意事项与最佳实践
Loader 应保持纯净、无副作用,避免修改传入的 source 字符串(应创建新字符串)。调试时可用 this.addDependency(filepath) 告诉 Webpack 监听额外文件变化;用 this.cacheable(false) 关闭缓存(默认开启);大型转换建议用 AST(如 acorn + estree)而非正则,更安全可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











