用rules.enforce来控制,其有两个值:
pre:优先执行
post:最后执行
rules: [
{
test:/\.less$/,
loader:'less-loader'
},
{
test: /\.less$/,
loader:'css-loader',
},
{
test: /\.less$/,
loader:'style-loader',
},
],
按上面的书写顺序,style-loader先执行,再执行css-loader,最后执行less-loader。
结果肯定会报错。可以用Rule.enforce来控制loader的执行顺序。既不改变loader的书写顺序,也可以正确执行。
rules: [
{
test:/\.less$/,
loader:'less-loader',
enforce:'pre'
},
{
test: /\.less$/,
loader:'css-loader',
},
{
test: /\.less$/,
loader:'style-loader',
enforce:'post'
},
],
此时,less-loader先执行,再执行css-loader,最后执行style-loader。
其实loader还有一种“内联”的用法。
例 import ‘style-loader!css-loader!less-loader!./index.css’;
使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。
在这里可以把loader分为四种
pre normal inline post
其执行顺序 pre -> normal -> inline ->post
尽可能使用 module.rules,因为这样可以减少源码中的代码量,并且可以在出错时,更快地调试和定位 loader 中的问题。
Webpack官网中不推荐大家使用“内联”loader,所以在讲loader的执行顺序时把inline类型的loader排除掉了。
在Vue Cli3中配置loader,有两种方法,一是通过configureWebpack选项来配置,二是通过chainWebpack选项来配置。
在配置中,可以使用vue-cli-service inspect来审查一个 Vue CLI 项目的 webpack config。
在项目中package.json文件中scripts中添加一条命令
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"inspect": "vue-cli-service inspect --mode production > output.js"
},
inspect这条命令的意思是把这个项目的生产环境下的解析好的 webpack 配置输出到output.js这个文件中。
如果是--mode development,就是开发环境下的webpack config。
5.1 configureWebpack配置
configureWebpack选项的值可以是对象,也可以是函数
值为对象。
最后通过webpack-merge合并到最终的配置中。也就是说在这里,只能新增loader配置,不能修改loader配置或者删除lodaer配置。
例如在vue.config.js中配置
module.exports = {
configureWebpack:{
module:{
rules:[
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
}
]
}
},
}
值为函数。
函数接收config作为参数,参数内容是webpack 配置,此时可以通过config参数来修改webpack的配置,也可以返回一个对象来通过webpack-merge合并到最终的配置中。
例如在vue.config.js中配置
module.exports = {
configureWebpack:config =>{
config.module.rules[10]={
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
}
},
}
如果要进行更细粒度的修改loader配置,可以使用chainWebpack来配置。
5.2chainWebpack配置
chainWebpack选项的值是一个函数,会接收一个基于webpack-chain 的 ChainableConfig 实例。采用链式写法来配置Webpack。
关于loader配置的新增、修改、删除的用法。
1.新增一个规则rule
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
},
}
2.添加规则rule的条件
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
//添加test选项
.test(/\.less$/)
//添加include选项,其值是数组
.include.add('/src/').add('/view/').end()
//添加exclude选项,其值是数组
.exclude.add('/node_modules/').end()
//添加issuer选项
.issuer('/\main\.js$/')
//添加resourceQuery选项
.resourceQuery('/inline/')
},
}
也可以使用rule.resource来配置规则的条件,在chainWebpack中这样配置:
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.issuer('/\main\.js$/')
.resourceQuery('/inline/')
//添加resource选项
.resource({
test:/\.less$/,
include:['/src/','/view/'],
exclude:['/node_modules/'],
})
},
}
3.添加规则rule的loader
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.test(/\.less$/)
//先创建一个具名的use,后面修改有用到这个名称
.use('styleloader')
//往这个具名的use中添加一个loader
.loader('style-loader')
//添加多个loader时要先.end()回到主链路
.end()
.use('cssloader')
.loader('css-loader')
.end()
.use('lessloader')
.loader('less-loader')
},
}
最后写的先执行。
4.添加规则rule的loader的参数
例如要给less-loader添加参数。
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.test(/\.less$/)
.use('lessloader')
.loader('less-loader')
.options({
// 这里配置全局变量
globalVars: {
'primary': '#fff'
}
})
},
}
options()的参数是个对象,在对象里面配置loader的参数。
5.修改规则rule的loader的参数
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.use('lessloader')
.tap(options =>{
options.globalVars.primary= 'red';
return options
})
},
}
用.tag()来实现,其参数是个函数,函数的参数是原loader的参数对象集合options,
通过修改参数options,再返回options达到修改规则Rule的loader的参数的目的。
6.修改规则rule的loader
修改其中一个loader
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.use('lessloader')
.loader('sass-loader')
},
}
将这个rule的loader全部清除重新添加
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.uses.clear()
.end()
.use('styleloader')
.loader('style-loader')
}
}
7.创建rule.oneOf规则组
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.test(/\.less$/)
.oneOf('vue-modules')
.resourceQuery('/module/')
.use('css-loader')
.loader('css-loader')
.end()
.use('less-loader')
.loader('less-loader')
.end()
.end()
.oneOf('src')
.resourceQuery('/src/')
.use('style-loader')
.loader('style-loader')
.end()
.use('css-loader')
.loader('css-loader')
.end()
.use('less-loader')
.loader('less-loader')
}
}
复制代码执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
修改Rule.oneOf规则组
之前创建Rule.oneOf规则组,我们给每个Rule.oneOf都起了名称,可以利用.oneOf(name)找这个Rule.oneOf修改,修改和创建的语法一样。
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.oneOf('vue-modules')
.resourceQuery('/module11/')
.use('css-loader')
.loader('sass-loader')
}
}
8.控制loader的执行顺序
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule1')
.test(/\.less$/)
.use('lessloader')
.loader('less-loader')
config.module
.rule('myRule2')
.test(/\.less$/)
.use('styleloader')
.loader('style-loader')
config.module
.rule('myRule3')
.test(/\.less$/)
.use('cssloader')
.loader('css-loader')
}
}
在同一个规则rule的条件下,其规则rule中的loader都是后写的先执行。
所有在同一规则rule的条件test(/\.less$/)下,先执行css-loader、再执行style-loader、最后执行less-loader,
应该先执行less-laoder,再执行css-loader,最后执行style-loader。
可以利用.pre()、.post()、.enforce('pre'/'post')来控制loader的执行顺序。
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule1')
.test(/\.less$/)
.use('lessloader')
.loader('less-loader')
.end()
.pre()
config.module
.rule('myRule2')
.test(/\.less$/)
.use('styleloader')
.loader('style-loader')
.end()
.post()
config.module
.rule('myRule3')
.test(/\.less$/)
.use('cssloader')
.loader('css-loader')
}
}
此时loader的执行顺序就是先执行less-laoder,再执行css-loader,最后执行style-loader。
或者这样也可以实现
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule1')
.test(/\.less$/)
.use('lessloader')
.loader('less-loader')
.end()
.enforce('pre')
config.module
.rule('myRule2')
.test(/\.less$/)
.use('styleloader')
.loader('style-loader')
.end()
.enforce('post')
config.module
.rule('myRule3')
.test(/\.less$/)
.use('cssloader')
.loader('css-loader')
}
}