今天聊一聊webpack的loader
webpack 的 loader 是基于的 node module, 所以你完全可以这么写
module.exports = function (source) {
//todo
}
为了保证兼容性请尽量使用 ES5 以及 CommonJS
source 则是这个 loader 处理的脚本文件的字符串方式输入
如果需要依赖别的模块来完成处理, 同样可以使用 CommonJS 的模块规范
var other = require('other');
module.exports = function () {
//todo
}
当数据处理完毕后,可以通过 return 返回出处理完毕的数据,可以返回字符串生成一个 js 文件
module.exports = function () {
return 'module.exports=function () { return 1}';
}
来尝试一个例子,编译一个 .temp 文件,它是一个模板文件,我们将它编译成一个 js 可执行的函数
首先 webpack 配置 loader 处理 .temp
{
test: /\.temp$/, //temp 模板加载器
loader: 'temp-loader'
}
temp 文件内容:
<div>请编译我吧!</div>
开始写 temp-loader
module.exports = function (source) {
return 'module.exports=function () { return ' + source + ';}';
}
当执行 webpack 任务的时候 .temp 文件内容会被输出并重新生成为 js 模块
module.exports=function () {
return '<div>请编译我吧!</div>';
}
把上面的模板修改下,改成动态模板
<div>{{content}}</div>
开始改写 temp-loader
module.exports = function (source) {
return 'module.exports = function (content) { return '" + source.replace(/\{\{(.*)\}\}/, "'+$1+'") + "';}';
}
此时执行 webpack 任务的时候 .temp 文件内容会被输出成:
module.exports=function (content) {
return '<div>' + content + '</div>';
}
这样就可以通过传递不同的参数,return 出 不同的模板
需要注意的是逆向思维, 因为在写 loader 里,所有的输出都要抽象成是真实的 js 语句,但是在 loader 里,它又是字符串,所以特别是引号的使用,要用逆向思维拼接这个 '字符串'
webpack 还提供了一些 API 来使用
loaderIndex: 获取当前资源正在经过第 x 个 loader 处理
resourcePath: 当前资源的路径,有时候需要访问和当前资源相同路径下的别的文件时会用到
async(): 声明当前 loader 为异步 loader 如果不需要依赖其它模块的 loader 可以这样处理,提升编译性能,具体看个例子:
module.exports = function(source) {
var callback = this.async();
// 这个模块异步执行
doSomeAsyncOperation(content, function(err, result) {
callback(null, result);
});
};
cacheable(): 让当前 loader 缓存
具体 API 文档请查看 webpack 官网: http://webpack.github.io
通过各种 API 的调用和词法分析手段可以做出形形色色的各种功能的 loader
愿大家都能贡献出强大好用的 loader !!!