1.从语法角度看,loader是一个普通的Node.js模块,只是必须以函数格式导出来供使用。
如果有必要可以使用一切Node.js功能模块。
2.从功能角度看,loader是在Webpack中作用于指定格式的资源文件并将其按照一定格式转换输出
3.一个Loader只做一件事情,可配置性好。loader支持链式调用。
上一个loader的处理结果可以传给下一个loader接着处理,上一个Loader的参数options可以传递给下一个loader,直到最后一个loader,返回Webpack所期望的JavaScript。
1.简单配置
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader']
},
],
},
}
loader是配置在module.rules中,module.rules的含义是创建模块的规则,module.rules的值是一个数组,其中每一项都是一项规则。
loader是用来生成符合Webpack的模块的。
然后Webpack把这些模块打包起来生成对应的js文件。loader是在打包前执行的。
rules.test
在简单的loader配置中,test:/\.css$/,是筛选到名称以.css结尾的文件后,交给user选项里面的loader处理一下。
那么test选项的作用就是筛选资源,符合条件的资源让这项规则中的loader处理。
test的值可以是字符串、正则表达式、函数、数组。
值为字符串时,可以为资源所在目录绝对路径 、资源的绝对路径。
const path = require('path');
module.exports = {
module: {
rules: [
{
test: path.resolve(__dirname, 'src/css'),
//test: path.resolve(__dirname, 'src/css/index.css'),
use: ['style-loader','css-loader']
},
],
},
}
值为函数时,接收的参数为资源的绝对路径。返回true表示该资源可以交给user选项里面的loader处理一下。
module.exports = {
module: {
rules: [
{
test: function (path) {
return path.indexOf('.css') > -1
},
use: ['style-loader','css-loader']
},
],
},
}
值为数组时,数组每一项可以为字符串、正则表达式、函数,只要符合数组中任一项条件的资源就可以交给user选项里面的loader处理一下。
const path = require('path');
module.exports = {
module: {
rules: [
{
test: [/\.css$/,path.resolve(__dirname, 'src/css')]
use: ['style-loader','css-loader']
},
],
},
}
rules.include
符合条件的资源让这项规则中的loader处理,用法和rules.test一样。
const path = require('path');
module.exports = {
module: {
rules: [
{
include:/\.css$/,
//include: path.resolve(__dirname, 'src/css'),
//include: path.resolve(__dirname, 'src/css/index.css'),
//include: [/\.css$/,path.resolve(__dirname, 'src/css')],
//include:function (content) {
//return content.indexOf('src/css') > -1
//},
use: ['style-loader','css-loader']
},
],
},
}
rules.exclude
符合条件的资源要排除在外,不能让这项规则中的loader处理,用法和rules.test一样。例如排除node_modules中的css文件。
const path = require('path');
module.exports = {
module: {
rules: [
{
exclude:/node_modules/,
//exclude: path.resolve(__dirname, 'node_modules'),
//exclude: [/node_modules/ , path.resolve(__dirname, 'node_modules')],
//exclude:function (content) {
//return content.indexOf('node_modules') > -1
//},
use: ['style-loader','css-loader']
},
],
},
}
rules.issuer
用法和rules.test一样,但是要注意是匹配引入资源的文件路径,
如在main.js中引入css/index.css
const path = require('path');
module.exports = {
module: {
rules: [
{
issuer: /\main\.js$/,
//issuer: path.resolve(__dirname, 'main.js'),
//issuer: [/\main\.js$/ , path.resolve(__dirname, 'main.js')],
//issuer:function (content) {
//return content.indexOf('main.js') > -1
//},
use: ['style-loader', 'css-loader']
},
],
},
}
rules.issuer 和 rules.test、rules.include 、rules.exclude同时使用时候,也是“与”的关系。
rules.resource
此选项也可筛选资源,符合条件的资源让这项规则中的loader处理。
但配置resource选项后,test、include、exclude选项不能使用。issuer选项不生效。
resource选项中有以下子选项
test选项,用法和rules.test一样。
exclude选项,用法和rules.exclude一样。
include选项,用法和rules.include一样。
not选项,值为数组,数组每一项可以为字符串、正则表达式、函数,只要符合数组中任一项条件的资源就不能交给user选项里面的loader处理一下。
and选项,值为数组,数组每一项可以为字符串、正则表达式、函数,必须符合数组中每一项条件的资源才能交给user选项里面的loader处理一下。
or选项,值为数组,数组每一项可以为字符串、正则表达式、函数,只要符合数组中任一项条件的资源就可以交给user选项里面的loader处理一下。
const path = require('path');
module.exports = {
module: {
rules: [
{
resource:{
test:/\.css$/,
include: path.resolve(__dirname, 'src/css'),
exclude: path.resolve(__dirname, 'node_modules'),
},
use: ['style-loader', 'css-loader']
},
],
},
}
rules.resourceQuery
匹配资源引入路径上从问号开始的部分。
import './ass/main.css?inline'
上面代码中rules.resourceQuery要匹配?inline,
const path = require('path');
module.exports = {
module: {
rules: [
{
resourceQuery:/inline/,
// resourceQuery:function (content) {
//return content.indexOf('inline') > -1
// },
//resourceQuery:[/inline/],
use: ['style-loader', 'css-loader']
},
],
},
}
注意
rules.test、rules.include、rules.exclude、rules.issuer、rules.resourceQuery同时使用时候,是“与”的关系,必须同时符合以上所有配置的条件才可以让这项规则中的loader处理。
rules.issuer、rules.resourceQuery、rules.resource同时使用时候,也是“与”的关系。必须同时符合以上所有配置的条件才可以让这项规则中的loader处理。
1.rules.use
意思是使用哪些loader处理符合条件的资源。
use: ['style-loader']其实是use: [ { loader: 'style-loader'} ]的简写。
还可以通过options传入loader,可以理解为loader的选项。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
]
},
],
},
}
use的值还可以是函数,返回一个数组,参数为info,info中有以下内容
compiler:当前webpack的编译器(可以是undefined值)。
issuer:引入被处理资源的所在文件的绝对路径。
realResource:被处理资源的绝对路径。
resource:被处理资源的绝对路径,它常常与realResource替代,只有当资源名称被请求字符串中的!=!覆盖时才不近似。
resourceQuery:被处理资源的绝对路径中?后面的部分。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: (info) =>{
console.log(info)
return [
'style-loader',
{
"loader": 'css-loader',
},
]
},
},
],
},
}
2.rules.loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
},
],
},
}
loader: 'css-loader' 是 use: [ { loader: 'css-loader'} ]的简写。
3.rules.oneOf
当规则匹配时,只使用第一个匹配规则。
例如说要处理css文件资源时,one.css要用url-loader处理,two.css要用file-loader处理。可以用Rule.oneOf来配置,其用法和module.rules一样。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
oneOf: [
{
resourceQuery: /one/, // one.css?one
//test: /one\.css/,
use: 'url-loader'
},
{
resourceQuery: /two/, // two.css?two
//test: /one\.css/,
use: 'file-loader'
}
]
},
],
},
}
从右到左,从下到上执行。换句话来说,就是后写的先执行,跟栈一样后进先出。
rules: [
{
test: /\.less$/,
use: ['style-loader','css-loader','less-loader']
},
],
以上配置中,less-loader先执行,再执行css-loader,最后执行style-loader。
rules: [
{
test: /\.less$/,
use:[
{
loader:'style-loader'
},
{
loader:'css-loader'
},
{
loader:'less-loader'
}
]
},
],
以上配置中,less-loader先执行,再执行css-loader,最后执行style-loader。
rules: [
{
test: /\.less$/,
loader:'style-loader',
},
{
test: /\.less$/,
loader:'css-loader',
},
{
test:/\.less$/,
loader:'less-loader'
}
],
以上配置中,less-loader先执行,再执行css-loader,最后执行style-loader。
可以得知,在同一个规则rules的条件下,其规则rules中的loader都是后写的先执行。从空间上来看,就是从右到左,从下到上执行。