什么是loader?
因为webpack不识别非js结尾的文件,所以需要借助loader来告诉webpack如何对这些文件进行处理和输出的 loader都有哪些类型
loader类型
loader在webpack 中有四种loader:
- pre(前置)
- normal(普通)
- inline(行内)
- post(后置)
loader的执行顺序:pre>normal>inline>loader
如何指定loader类型
在webpack中通过Rule.enforce来指定loader的类型
{
test: /\.less$/,
use: 'less-loader',
enforce: 'pre'
}
如果没有enforce就会指定为普通的loader
如何禁用一些loader?
比如说一个eslint-loader,有的的开发者可能使用不了,但是不能干扰到其他同事,可以选择直接禁用它
require('!inline-loader!./a.js')
使用 ! 禁用配置文件中的普通loader
require('-!inline-loader!./a.js')
使用-!禁用所有的前置和普通loader
require('!!inline-loader!./a.js')
使用!! 禁用所有的后置和普通loader
下面开始直奔主题,开始说说url-loader和file-loader
为什么要用url-loader和file-loader?
url-loader和file-loader在webpack中是最常用的两个loaderl了,首先这两个loader存在一个相同点,上面已经提到webpack不能处理像css,scss,less,jpg,svg或者是其他文件格式的资源,这个时候就需要借助这两个loader其中一个去处理。
下面说一下这两个loader的区别
相同点:这两个loader都是用来处理在webpack编译的时候不能识别的文件格式
不同点:url-loader会在特定的条件下将资源输出为base64编码格式,为什么说在特定条件下,用过此loader的人都知道有一个limit的配置,通过这个配置来识别文件以哪种格式输出,并且在他内部也引用了file-loader,file-loader就是讲webpack不能识别的文件进行编译,并输出到指定的目录,url-loader就相当于对file-loader进行了二次封装,所以现在还是url-loader用的比较多一些。
开发自定义两个loader,并分别实现url-loader和file-loader
在编写源码之前需要安装三个依赖,分别是:
- loader-utils
loader的工具库
- mime
文件类型匹配
- schema-utils
验证loader参数
file-loader
- 创建文件loader/file-loader.js
const LoaderUtils = require('loader-utils')
module.exports = function(content,map,mate){
// 1. 获取参数
var options = loaderUtils.getOptions(this) || {};
// 2. 是否使用ESM导出
const esModule = typeof options.esModule !== 'undefined' ? options.esModule : true;
// 3. 根据文件生成带hash值文件名
const publicPath = LoaderUtils.interpolateName(this,"[hash].[ext][query]",content);
// 4. 将文件输出出去
this.emitFile(publicPath,content)
// 5. export 文件名
return `${esModule ? 'export default' : 'module.exports ='}${publicPath}`;
}
// 需要处理 文件 ,图片等文件格式都是 buffer格式的 需要使用rawloader才能处理
module.exports.raw = true;
url-loader
- 创建文件loader/option.json
{
"type":"object",
"properties":{
"limit":{
"type":["string","number"]
},
"mimeType":{
"type":"string"
},
"esModule":{
"type":"boolean"
}
}
}
- 创建文件loader/url-loader.js
var loaderUtils = require("loader-utils");
var mime = require("mime");
var validate = require("schema-utils");
var schema = require('./option.json');
function shouldTransform(limit, size){
if (typeof limit === 'boolean') {
return limit;
}
if (typeof limit === 'string') {
return size <= parseInt(limit, 10);
}
if (typeof limit === 'number') {
return size <= limit;
}
return true;
}
module.exports = function(content) {
// 1. 获取参数
var query = loaderUtils.getOptions(this) || {};
// 2. 验证参数 - 当出现错误的时候会自动抛出错误
validate(schema, query,{name:'url-loader'});
// 3. 文件大小限制
var limit = (this.options && this.options.url && this.options.url.dataUrlLimit) || 0;
// 2.0+版本以后新增的esModuleApi
let esModule = query.esModule
// 类型
var mimetype = query.mimetype || query.minetype || mime.lookup(this.resourcePath);
// 通过文件大小
if(shouldTransform(query.limit,content.length)){
// 如果比较文件小于limit 以base64的形式去展示
return `${esModule ? 'export default' : 'module.exports ='}` + JSON.stringify("data:" + (mimetype ? mimetype + ";" : "") + "base64," + content.toString("base64"));
} else {
// 这里引入我们自己的file-loader
// 如果比较文件大于limit,以url的形式展示
var fileLoader = require("./file-loader.js");
return fileLoader.call(this, content);
}
}
module.exports.raw = true;
如何测试使用
在loader统计目录下创建webpack.config.js
,只需要验证url-loader就可以了,因为内部已经有file-loader的导入
// webpack.config.js 中
{
oneOf:[
{
test:/\.js$/,
use:[
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: './loader/url-loader.js',
exclude: [resolve('src/icons')],
options: {
limit: 10000,
// 名称
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
]
}
]
},
本篇文章主要介绍loader的基础知识和如何去开发自定义loader,并介绍了两个常用的loaderurl-loader
和file-loader
,也进行了基本的实现,通过本片文章希望你能对webpack的loader的使用以及开发有一个基本的认识,更多关于webpack自定义loader的资料请关注编程网其它相关文章!