Loader是什么?
Loader配置
Loader是解析处理器,通过loader我们可以将ES6语法的JS转化为ES5的语法,可以将图片转化为base64的dataURL,在JavaScript文件中直接import css和HTML也是通过对应的loader来实现的。
我们在使用loader之前,需要先安装它,例如,我们要在javaScript中引入less,则需要安装less-loader
然后在module.rules中指定*.less文件都是用less-loader:
module.exports = {
module:{
rules:[
test: /.less$/,
use:'less-loader'
]
}
}
简单来理解上面的配置,test项使用 /.less$/正则匹配需要处理的模块文件(即 less 后缀的文件),然后交给less-loader来处理,这里的less-loader是个 string,最终会被作为require()的参数来直接使用。
这样 less 文件都会被less-loader处理成对应的 css 文件。
除了直接在webpack.config.js使用 loader 的方式之外,还可以在对应的 JavaScript 文件中使用 loader:
const html = require('html-loader!./loader.html');
console.log(html);
上面的代码,实际是将loader.html的内容转化成 string 变量,直接给输出了,等同于:
const html = require('./loader.html');
console.log(html);
加上下面配置的效果:
module.exports = {
module: {
rules: [{test: /.html$/, use: ['html-loader']}]
}
};
如果没有 html-loader,直接require
一个 html 文件,会被当作 js 模块来执行,则会报错:
Tips:require('html-loader!./loader.html')中!类似 Unix 系统中命令行的管道,这里!隔开的命令是从右到左解析的,即先加载loader.html然后在将加载的文件内容传给html-loader处理。
综上,loader 有两种配置方式:
- 使用 webpack.config.js 的配置方式:
module.exports = {
module: {
rules: [{test: /.html$/, use: ['html-loader']}]
}
};
- 在 JavaScript 文件内使用内联配置方式:
const html = require('html-loader!./loader.html');
// or
import html from 'html-loader!./loader.html';
Tips:use 中传递字符串(如:use: ['style-loader'])是 loader 属性的简写方式(如:use: [{loader: 'style-loader'}])
Loader 的参数
给 loader 传参的方式有两种:
- 通过
options
传入 - 通过
query
的方式传入:
// inline内联写法,通过 query 传入
consthtml
=require("html-loader?attrs[]=img:src&attrs[]=img:data-src!./file.html");
// config内写法,通过 options 传入
module
:{
rules
:[{
test
:/.html$/,
use
:[{
loader
:'html-loader',
options
:{
minimize
:true,
removeComments
:false,
collapseWhitespace
:false
}
}]
}]
}
// config内写法,通过 query 传入
module
:{
rules
:[{
test
:/.html$/,
use
:[
{
loader
:'html-loader?minimize=true&removeComments=false&collapseWhitespace=false',
}]
}]
}
Loader 的解析顺序
对于一些类型的模块,简单配置一个 loader 是不能够满足需求的,例如 less 模块类型的文件,只配置了 less-loader 仅仅是将 Less 语法转换成了 CSS 语法,但是 JS 还是不能直接使用,所以还需要添加css-loader
来处理,这时候就需要注意 Loader 的解析顺序了。前面已经提到了,Webpack 的 Loader 解析顺序是从右到左(从后到前)的,即:
// query 写法从右到左,使用!隔开
conststyles
=require('css-loader!less-loader!./src/index.less');
// 数组写法,从后到前
module
.exports
={
module
:{
rules
:[
{
test
:/.less$/,
use
:[
{
loader
:'style-loader'
},
{
loader
:'css-loader'
},
{
loader
:'less-loader'
}
]
}
]
}
};
如果需要调整 Loader 的执行顺序,可以使用enforce
,enforce
取值是pre|post
,pre
表示把放到最前,post
是放到最后:
use
:[
{
loader
:'babel-loader',
options
:{
cacheDirectory
:true
},
// enforce:'post' 的含义是把该 loader 的执行顺序放到最后
// enforce 的值还可以是 pre,代表把 loader 的执行顺序放到最前
enforce
:'post'
}
];
oneOf:只应用第一个匹配的规则
oneOf
表示对该资源只应用第一个匹配的规则,一般结合resourceQuery
,具体代码来解释:
module
.exports
={
//...
module
:{
rules
:[
{
test
:/.css$/,
oneOf
:[
{
resourceQuery
:/inline/,
// foo.css?inline
use
:'url-loader'
},
{
resourceQuery
:/external/,
// foo.css?external
use
:'file-loader'
}
]
}
]
}
};