webpack loader自定义编写

loader

  • 文档定义

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

  • 编写
    • 本质上一个loader就是一个node模块,也就是一个js文件。
    • 这个文件导出一个函数, 导出的这个函数接收一个 source参数, 用来接受,webpack传过来的文件源码
    • 这个函数返回一个新的source 供链式调用。
    • 以字符串替换为例, loader代码如下
const  loaderUtils = require('loader-utils')
module.exports = function (source) {
	const  options = loaderUtils.getOptions(this)  || {}
	const {key = 'like', value = '❤'} = options;
	const  re = new RegExp(key,'ig')
	const res = source.replace(re,value)
	return res
}
  1. loader-utilswebpack内置的模块, 不需要安装, 可以直接使用。
  2. 通过 loader-utils下的 getOptions方法,获取 webpack配置loader时的参数。
  • 自定义loader的使用
  1. 可以发布npm包(参考npm发布包的相关使用)
  2. 本地使用
  • 本地使用

  • 创建loader文件夹 专门存放自定义的loader文件

  • 由于webpack默认的loader是从 node_modules文件夹下查找的。所以需要配置路径, 让webpack能找到你本地的loader:

  • 有两个方式配置loader路径

     module:{
     	rules:[
     		{
     			test:/\.js$/,
     			use:[
     				{
     					loader:path.resolve('./loader/k-loader.js'),
     					options:{
     						value:'LIKE'
     					}
     				}
     			]
     		}
     	]
     }
    

    通过webpack的 resolveLoader扩展 loader目录。

     resolveLoader:{
    modules:[
    	'node_modules',
    	path.resolve(__dirname, './loader')
    ]
    },
    module:{
    rules:[
    	{
    		test:/\.js$/,
    		use:[
    			{
    				loader:'k-loader', 
    				options:{
    					value:'LIKE'
    				}
    			}
    		]
    	}
    ]
    }
    
  • 返回多个值

    • 上面的loader返回了一个结果。有些场景下 需要返回多个值, 可以用 this.callback()来返回多个值。
     module.exports = function(source) {
      this.callback(err|| null, source, sourceMap,meta)
      return; // 当调用 callback() 时总是返回 undefined
     }
    
    1. 第一个参数是 Error或者null
    2. 第二个参数是 String或 BUffer
    3. 第三个必须是一个可以被这个模块解析的 source map。【可选】
    4. 会被 webpack 忽略,可以是任何东西比方元数据。 【可选】
  • 同步&异步

  1. 无论是return 还是 this.callback都可以同步的返回转换后的content内容。this.callback方法更灵活,可以传递更多参数。
  2. 对于异步loader, 使用this.async 获取callback函数
  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);
    });
  };
<!-- 多个返回值-->
module.exports = function(content, map, meta) {
  var callback = this.async();
  someAsyncOperation(content, function(err, result, sourceMaps, meta) {
    if (err) return callback(err);
    callback(null, result, sourceMaps, meta);
  });
};
posted @ 2020-05-27 14:46  橙云生  阅读(690)  评论(0编辑  收藏  举报