0%

如何编写一个loader

什么是loader

loader其实是一种打包方案,loader可以将所有类型的文件转换为webpack能够处理的有效模块,然后你就可以利用webpack的打包能力,对它们进行处理。

自己编写的loader的使用

同普通loader一样,在webpack.config.js的module中写新的rule,还要在webpack.config.js新写一个配置项resolveLoader(代码如下所示),意思是按名称先在node_modules中找loader,找不到再去 ./loader 文件夹中找(自己写的loader放在该文件夹中,为replaceLoader.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
resolveLoader: {
modules: ['node_modules', './loaders']
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'replaceLoader',
options: {
name: 'zj'
}
}
}]
}

对loader传递数据

如上面的代码中,option即可用来传递参数,把想传递的参数写成option对象的属性。然后replaceLoader.js中用this.query.属性即可得到这个参数;也可以使用loader-util中的getOption方法来得到这个option对象。

loader的编写

在这里,我们假设入口文件index.js中的代码内容仅为console.log('hello world');,我们想编写一个loader对这个文件进行处理,实现把world改成zj
loader其实是一个函数。在编写的时候,我们可以把loader放在一个单独的文件中,然后导出即可使用。注意在这里module.exports = function() {}的function不能写成箭头函数,因为在loader的编写中我们会常用到this,这里用箭头函数可能会造成this的使用出现麻烦。最终代码如下:

1
2
3
4
5
6
const loaderUtils = require('loader-utils')

module.exports = function (source) {
const options = loaderUtils.getOptions(this)
return source.replace('world', options.name)
}

异步loader编写

this.async

Tells the loader-runner that the loader intends to call back asynchronously. Returns this.callback

this.callback

A function that can be called synchronously or asynchronously in order to return multiple results. The expected arguments are:

1
2
3
4
5
6
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
1
2
3
4
5
6
7
8
9
10
const loaderUtils = require('loader-utils');

module.exports = function (source) {
const options = loaderUtils.getOptions(this);
const callback = this.async();
setTimeout(() => {
const result = source.replace('world', options.name);
callback(null, result);
}, 5000);
};
-------------本文结束感谢您的阅读-------------