loader的本质
loader 本质上是导出为函数的 JavaScript 模块。当webpack解析资源时,会调用相应的 loader 去处理,然后将上一个 loader 产生的结果或者资源文件传入进去。loader 有三个入参:资源文件的内容(content)、可以被 Source Map 使用的 SourceMap 数据(map)、数据,可以是任何内容(meta)。
loader 有同步 Loaders、异步 Loaders 、Raw Loader 、Pitching Loader ,更详细的可以参考 Loader Interface。
具体步骤
下面写一个去除 console.log 的 loader
- 创建一个新的文件作为你的 Loader,例如 clean-log-loader.js 。
- 在文件中,导出一个函数,该函数以源代码作为输入。
- 在函数内部,根据需要操纵源代码进行转换。
- 返回转换后的源代码。
同步 Loaders
例如,假设你想创建一个 Loader,去除每个 JavaScript 文件的中的 console.log ,Loader 所示如下:
同步 loader 有两种写法,如果有多个处理结果,则必须调用 this.callback()
,当调用 callback() 函数时,总是返回 undefined,代码如下:
module.exports = function (content, map, meta) {this.callback(null, someSyncOperation(content), map, meta);return;
};
function someSyncOperation(content) {return content.replace(/console\.log\(.*\);?/g, "");
}
如果只有一个处理结果,可以调用 this.callback()
,也可以不用,代码如下:
module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};
在 webpack.prod.js 中使用
{test: /\.jsx?$/,include: [path.resolve(__dirname, "../src")],use: [{loader: "./loaders/clean-log-loader",},],
},
异步 Loaders
对于异步 loader,使用 this.async 来获取 callback 函数。
module.exports = function(source) {const callback = this.async();// 在 `setTimeout` 等异步方法中完成处理,然后通过回调函数将结果返回给 WebpacksetTimeout(() => {callback(null, someSyncOperation(content), map, meta);}, 1000);
};
function someSyncOperation(content) {return content.replace(/console\.log\(.*\);?/g, "");
}
在 webpack.prod.js 中使用与同步一样。
Raw Loader
默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw 为 true ,loader 可以接收原始的 Buffer 。大多数情况下都是图片或字体使用 Raw Loader,毕竟js还是想看具体内容的, 添加 module.exports.raw = true 就可以了。
module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};
module.exports.raw = true;
Pitching Loader
在文件中导出一个函数并添加 pitch 属性,该函数在模块被处理之前执行。 pitch 函数的输入是请求的数据,包括请求的路径、请求的上下文以及使用的其它 Loader。
module.exports = function (content, map, meta) {return content.replace(/console\.log\(.*\);?/g, "");
};
module.exports.pitch = function(request) { // pitch函数在模块被处理之前执行 // request 参数包括请求的路径,请求的上下文和使用的其它 Loader
};
对于以下配置,执行顺序
module.exports = {//...module: {rules: [{//...use: ['a-loader', 'b-loader', 'c-loader'],},],},
};
结束语
纯属个人总结,不喜勿喷。