当前位置: 首页 > 工具软件 > Loader > 使用案例 >

webpack 深入了解之loader配置详解(二)

佟嘉祯
2023-12-01

四,控制loader的执行顺序

用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

在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')
    }
}


 类似资料: