编写一个webpack的loader
loader在webpack打包流程中,有着比较重要的地位,很多资源类型需要经过loader的转化改变成浏览器能够识别的资源类型。1,loader的本质是一个node模块,它输出了一个函数,当某个资源需要用这个loader转换时,该函数就会被调用。形式如下:module.exports= function(src){//可以通过 this 访问Loader API//...
loader在webpack打包流程中,有着比较重要的地位,很多资源类型需要经过loader的转化改变成浏览器能够识别的资源类型。
1,loader的本质是一个node模块,它输出了一个函数,当某个资源需要用这个loader转换时,该函数就会被调用。
形式如下:
module.exports = function(src){
//可以通过 this 访问Loader API
//this是由webpack提供的,可以直接使用
}
第一个 loader 的传入参数只有一个:资源文件(resource file)的内容。compiler 需要得到最后一个 loader 产生的处理结果。这个处理结果应该是 String
或者 Buffer
(被转换为一个 string),代表了模块的 JavaScript 源码。另外还可以传递一个可选的 SourceMap 结果(格式为 JSON 对象)。
如果是单个处理结果,可以在同步模式中直接返回。如果有多个处理结果,则必须调用 this.callback()
。在异步模式中,必须调用 this.async()
,来指示 loader runner 等待异步结果,它会返回 this.callback()
回调函数,随后 loader 必须返回 undefined
并且调用该回调函数。
2,loader分为同步loader和异步loader
同步loader sync-loader.js
module.exports = function(content, map, meta) {
return someSyncOperation(content);
};
异步loader async-loader.js
module.exports = function(content, map, meta) {
var callback = this.async();
someAsyncOperation(content, function(err, result) {
if (err) return callback(err);
callback(null, result, map, meta);
});
};
3,loader实例
使用const loaderUtils = require('loader-utils');获取loader的配置项
module.exports = function(source) {
// 通过 this.callback 告诉 Webpack 返回的结果
this.callback(null, source, sourceMaps);
// 当你使用 this.callback 返回内容时,该 Loader 必须返回 undefined,
// 以让 Webpack 知道该 Loader 返回的结果在 this.callback 中,而不是 return 中
return;
};
this.callback(
// 当无法转换原内容时,给 Webpack 返回一个 Error
err: Error | null,
// 原内容转换后的内容
content: string | Buffer,
// 用于把转换后的内容得出原内容的 Source Map,方便调试
sourceMap?: SourceMap,
// 如果本次转换为原内容生成了 AST 语法树,可以把这个 AST 返回,
// 以方便之后需要 AST 的 Loader 复用该 AST,以避免重复生成 AST,提升性能
abstractSyntaxTree?: AST
);
转换异步:
module.exports = function(source) {
// 告诉 Webpack 本次转换是异步的,Loader 会在 callback 中回调结果
var callback = this.async();
someAsyncOperation(source, function(err, result, sourceMaps, ast) {
// 通过 callback 返回异步执行后的结果
callback(err, result, sourceMaps, ast);
});
};
处理二进制数据:
module.exports = function(source) {
// 在 exports.raw === true 时,Webpack 传给 Loader 的 source 是 Buffer 类型的
source instanceof Buffer === true;
// Loader 返回的类型也可以是 Buffer 类型的
// 在 exports.raw !== true 时,Loader 也可以返回 Buffer 类型的结果
return source;
};
// 通过 exports.raw 属性告诉 Webpack 该 Loader 是否需要二进制数据
module.exports.raw = true;
以上代码中最关键的代码是最后一行 module.exports.raw = true
,没有该行 Loader 只能拿到字符串。
4,编写一个loader
在项目根目录建一个loaders文件夹
webpack中配置:ResolveLoader
module.exports = {
resolveLoader:{
// 去哪些目录下寻找 Loader,有先后顺序之分
modules: ['node_modules','./loaders/'],
}
}
或者使用npm link
1,确保正在开发的本地 Npm 模块(也就是正在开发的 Loader)的 package.json 已经正确配置好;
2,在本地 Npm 模块根目录下执行 npm link,把本地模块注册到全局;
3,在项目根目录下执行 npm link loader-name,把第2步注册到全局的本地 Npm 模块链接到项目的 node_moduels 下,
其中的 loader-name 是指在第1步中的 package.json 文件中配置的模块名称。
上面两种方法是用来调试本地loader
编写去除console.log()调试代码
delete-console-loader
function deleteConsole(content){
return content.replace('console','//console')
}
module.exports = function(source){
return deleteConsole(source)
}
参考:https://blog.csdn.net/wu5229485/article/details/96475954
https://www.jianshu.com/p/cb888d69ca34
更多推荐
所有评论(0)