webpack loader

什么是 Loader

在webacpk 中万物皆模块,loader本质上是一个node模块,该模块导出了一个处理函数。在处理函数中输入我们的源模块、输出通用模块。借助loader我们不仅仅可以处理js类型的文件,其他任何类型的文件都可以被处理。loader 运行在nodejs 环境中,可以做任何在nodejs 中可以做的事情十分强大。

Loader 的基本配置

一般情况下我们可以通过webpack配置文件中的module.rules字段来loa配置loaders,常见的配置如下。

  • 常用写法
 module.exports = {
 	// ...
 	module: {
 		rules: [
 			// 单loader
 			{
 				test: /\.js$/,
 				use: ['babel-loader']
 			}
 			// 多loader
 			{
 				test: /\.less$/,
 				use: [
 				'style-loader',
 				 {
 				 	loader: 'css-loader',
 				  	options: module: true
 				  },
 				  'less-loader'
 				]
 			}
 		]
 	}
 }
  • 兼容写法
module.exports = {
 	// ...
 	module: {
 		rules: [
 		// 相当于 use: [{loader: 'babel-loader'}]
 			{
 				test: /\.js$/,
 				loader:  'babel-loader'
 			}
 			{
 				test: /\.less$/,
 				loader:  'style-loader!css-loader?module!less-loader'
 			}
 			/// loaders 等于 use
 			{
 				test: /\.css$/,
 				loaders: ['style-loader', 'css-loader']
 			}
 		]
 	}
 }

本地开发一个loader

  • 创建最基本的loader,在根目录创建loaders文件夹,创建a-loader.js.
  // source 为处理文件的内容 默认是字符串格式
  const loader = function(source){
  	// 什么也不处理直接返回
  	return source
  }
  module.exports = loader
  • 加载本地loader
	module.exports = {
	// 添加loaders 目录作为查找loader的默认目录
		resolveLoader: {
   			modules: ['node_modules', 'loaders']
 		},
 		module: {
 			rules: [
 				{
 					test: /\.js$/,
 					use: [{loader: 'a-loader'}]
 				}
 			]
 		}
	}

loader 的执行顺序

  • loader 是链式的处理原则,每个loader 处理一种单一功能,上一个loader的返回值将会作为下一个loader的入参。
  • loader 默认顺序: 从右往左, 从下到上。

a-loader.js

  const loader = function(source){
 	console.log('a-loader')
  	return source
  }
  module.exports = loader

b-loader.js

  const loader = function(source){
 	console.log('b-loader')
  	return source
  }
  module.exports = loader

c-loader.js

  const loader = function(source){
 	console.log('c-loader')
  	return source
  }
  module.exports = loader

webpack.connfig.js
use多个loader 将会从右往左执行

	module.exports = {
	 // ...
	 module: {
	 	rules: [{
	 		test: /\.js$/,
	 		//  控制台 输出: c-loader b-loader a-loader
	 		use: ['a-loader', 'b-loader', 'c-loader']
	 	}]
	 }
	}

webpack.config.js
匹配多个rule 将会从下至上执行

// 控制台输出 c-loader b-loader a-loader
	module.exports = {
	 // ...
	 module: {
	 	rules: [{
	 		test: /\.js$/,
	 		use: ['a-loader']
	 	},{
	 		test: /\.js$/,
	 		use: ['b-loader']
	 	}{
	 		test: /\.js$/,
	 		use: ['c-loader']
	 	}]
	 }
	}
  • loader 类型顺序:
  1. loader的类型有4种: 普通loader、前置loader、后置loader、行内loader,默认类型为普通loader。
  2. 在rule 中设置enforce: ''pre" (前置loader)、“post”(后置loader)
  3. 行内loader是在代码中引入模块的时候的一种写法如:import ‘inline-loader!./test.js’
  4. 执行顺序为 pre -> normal -> inline -> post

inline-loader

const loader = function(source){
	console.log('inline-loader')
 	return source
 }
 module.exports = loader
// 控制台输出: 
// a-loader 
// b-loader
// inline-loader
// c-loader
 module.exports = {
 	entry: 'inline-loader!./src/app.js',
 	module: {
	 	rules: [{
	 		test: /\.js$/,
	 		use: ['a-loader'],
	 		enforce: 'pre'
	 	},{
	 		test: /\.js$/,
	 		use: ['b-loader']
	 	}{
	 		test: /\.js$/,
	 		use: ['c-loader'],
	 		enforce: 'post'
	 	}]
	 }
 	
 }
```js
  1. inline-loader 添加前缀可以不走某些loader
    ! 不走normal
    -! 不走 pre 和 normal
    !! 不走其他所有

不走 normal

// 控制台输出: 
// a-loader 
// inline-loader
// c-loader
module.exports = {
	entry: '!inline-loader!./src/app.js',
	module: {
    	rules: [{
    		test: /\.js$/,
    		use: ['a-loader'],
    		enforce: 'pre'
    	},{
    		test: /\.js$/,
    		use: ['b-loader']
    	}{
    		test: /\.js$/,
    		use: ['c-loader'],
    		enforce: 'post'
    	}]
    }
	
}

不走 pre 和 normal

// 控制台输出: 
// inline-loader
// c-loader
module.exports = {
	entry: '-!inline-loader!./src/app.js',
	module: {
    	rules: [{
    		test: /\.js$/,
    		use: ['a-loader'],
    		enforce: 'pre'
    	},{
    		test: /\.js$/,
    		use: ['b-loader']
    	}{
    		test: /\.js$/,
    		use: ['c-loader'],
    		enforce: 'post'
    	}]
    }
	
}

不走其他所有

// 控制台输出: 
// inline-loader
module.exports = {
	entry: '!!inline-loader!./src/app.js',
	module: {
    	rules: [{
    		test: /\.js$/,
    		use: ['a-loader'],
    		enforce: 'pre'
    	},{
    		test: /\.js$/,
    		use: ['b-loader']
    	}{
    		test: /\.js$/,
    		use: ['c-loader'],
    		enforce: 'post'
    	}]
    }
	
}
  • loader.pitch 顺序
  1. loader还可以附带一个pitch函数
  2. 在执行loader 之前会默认先执行pitch 函数
  3. pitch 函数的执行顺序是和 loader 相反的。

a-loader.js

  let loader = function(source){
  	console.log(source)
  	return source
  }
  loader.pitch = function(){
  	console.log('a-pitch')
  }
  module.exports = loader

b-loader.js

  let loader = function(source){
  	console.log(source)
  	return source
  }
  loader.pitch = function(){
  	console.log('b-pitch')
  }
   module.exports = loader

c-loader.js

  let loader = function(source){
  	console.log(source)
  	return source
  }
  loader.pitch = function(){
  	console.log('c-pitch')
  }
   module.exports = loader

webpack.config.js

	// 控制台输出
	// a-pitch
	// b-pitch
	// c-pitch
	// c-loader
	// b-loader
	// a-loader
	module.exports = {
		// ...
		modules: {
			rules: [{
		 		test: /\.js$/,
		 		use: ['a-loader'],
	 		},{
		 		test: /\.js$/,
		 		use: ['b-loader']
		 	}{
		 		test: /\.js$/,
		 		use: ['c-loader'],
		 	}]
		}
	}
  1. 如果pitch 有返回值, 那么后面的pitch和本身对应的loader将不会执行,从下一个loader开始执行

b-loader.js

  let loader = function(source){
  	console.log(source)
  	return source
  }
  loader.pitch = function(){
  	console.log('b-pitch')
  	return ''
  }
   module.exports = loader

webpack.config.js

	// 控制台输出
	// a-pitch
	// b-pitch
	// a-loader
	module.exports = {
		// ...
		modules: {
			rules: [{
		 		test: /\.js$/,
		 		use: ['a-loader'],
	 		},{
		 		test: /\.js$/,
		 		use: ['b-loader']
		 	}{
		 		test: /\.js$/,
		 		use: ['c-loader'],
		 	}]
		}
	}

loader 执行图
在这里插入图片描述

实现简单的babel-loader

  1. 调用babel/core 模块对代码进行转化
    2)配置source-map
    3)为source-map 设置name

实现简单的file-loader url-loader

  1. file-loader 打包图片导出路径
    2)url-loader 实现图片base64 编码格式

实现简单的less-loader css-loader style-loader

  1. less-loader 调用less 库转化代码为css代码
  2. css-loader 对css 中对图片路基进行处理
  3. style-loader 创建style标签 将css 插入到head标签中

实现简单的banner-loader

1)在js 代码中添加头部注释
2)监听依赖文件变化进行打包

常用写法

  • 常用工具库 loader-utils、schema-utils
  • 异步返回 this.async
  • 处理文件 loader.raw = true
  • this.resourcePath 文件绝对路径
  • 更多用法参考 https://webpack.js.org/api/loaders/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值