index.js
console.log('hello webpack')
replaceLoader.js
// 不能写成箭头函数,只能写显示的 function 声明函数,不然会有 this 指向问题
module.exports = function(source) {
return source.replace('loader', 'compiler loader')
}
replaceLoaderAsync.js
// 在 webpack.config.js 配置的 options 中传入的参数可能不一定是对象形式,
// 可能会直接是字符串,借助 loader-utils 可以帮助分析传入的参数
const loaderUtils = require('loader-utils');
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
// 编写异步 loader 时
// 返回使用的 callback 应使用 this.async() 生成
const callback = this.async()
setTimeout(() => {
const result = source.replace('webpack', options.name)
// callback 的作用相当于 return
// 不同的是,callback 可以返回错误信息,结果代码,sourceMap,或者其他数据
callback(null, result)
}, 1000);
}
this.callback ()
可以同步或者异步调用的并返回多个结果的函数。预期的参数是:
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
-
第一个参数必须是
Error
或者null
-
第二个参数是一个
string
或者 Buffer。 -
可选的:第三个参数必须是一个可以被 this module 解析的 source map。
-
可选的:第四个参数,会被 webpack 忽略,可以是任何东西(例如一些元数据)。
如果这个函数被调用的话,你应该返回 undefined 从而避免含糊的 loader 结果。
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js'
},
// 配置后就可以不必每次都写路径
// loader: path.resolve(__dirname, './loaders/replaceLoaderAsync.js'),
resolveLoader: {
modules: ['node_modules', './loaders']
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'replaceLoader'
},
{
loader: 'replaceLoaderAsync',
options: {
name: 'loader'
}
}
]
}
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
}