一、loader是什么
A loader is just a JavaScript module that exports a function.
从语法角度看,loader是一个普通的Node.js模块,只是必须以函数格式导出来供使用。如果有必要可以使用一切Node.js功能模块。 从功能角度看,loader是在Webpack中作用于指定格式的资源文件并将其按照一定格式转换输出。例如:less-loader将less文件转换为css文件输出。
二、loader的特点
单一职责,一个Loader只做一件事情,正因为职责越单一,所以Loaders的组合性强,可配置性好。 loader支持链式调用,上一个loader的处理结果可以传给下一个loader接着处理,上一个Loader的参数options可以传递给下一个loader,直到最后一个loader,返回Webpack所期望的JavaScript。
三、loader的配置
在学习loader的配置时,最好搭个简易的Webpack Demo,执行webpack命令打包,可以验证一下配置是否有误。 loader在Webpack中的配置有多种写法,下面一一详解。 先来看一个简单的loader配置。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader']
},
],
},
}
loader是配置在module.rules中,module.rules的含义是创建模块的规则,module.rules的值是一个数组,其中每一项都是一项规则。loader是用来生成符合Webpack的模块的。然后Webpack把这些模块打包起来生成对应的js文件。loader是在打包前执行的。 如下图所示,这是用style-loader和css-loader两个loader生成的模块。
在这里称module.rules中每一项规则为Rule,下面来讲配置规则Rule的条件和配置规则Rule的loader。
1、配置规则Rule的条件
Rule.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处理一下。
\project\03personal\05Webpack_demo\src\css\index.css
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']
},
],
},
}
Rule.include 符合条件的资源让这项规则中的loader处理,用法和Rule.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']
},
],
},
}
Rule.exclude 符合条件的资源要排除在外,不能让这项规则中的loader处理,用法和Rule.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']
},
],
},
}
Rule.issuer 用法和Rule.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']
},
],
},
}
Rule.issuer 和 Rule.test、Rule.include 、Rule.exclude同时使用时候,也是“与”的关系。 Rule.resource 此选项也可筛选资源,符合条件的资源让这项规则中的loader处理。 但配置resource选项后,test、include、exclude选项不能使用。issuer选项不生效。 resource选项中有以下子选项
test选项,用法和Rule.test一样。 exclude选项,用法和Rule.exclude一样。 include选项,用法和Rule.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']
},
],
},
}
Rule.resourceQuery 匹配资源引入路径上从问号开始的部分。例 import './ass/main.css?inline' 复制代码上面代码中Rule.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']
},
],
},
}
注意 Rule.test、Rule.include、Rule.exclude、Rule.issuer、Rule.resourceQuery同时使用时候,是“与”的关系,必须同时符合以上所有配置的条件才可以让这项规则中的loader处理。 Rule.issuer、Rule.resourceQuery、Rule.resource同时使用时候,也是“与”的关系。必须同时符合以上所有配置的条件才可以让这项规则中的loader处理。
2、配置规则Rule的loader
Rule.use 在上面已经提到过Rule.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',
},
]
},
},
],
},
}
参数info打印如下图所示
Rule.loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
},
],
},
}
loader: 'css-loader' 是 use: [ { loader: 'css-loader'} ]的简写。
Rule.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'
}
]
},
],
},
}
四、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。 由以上三个例子,可以得知,在同一个规则Rule的条件下,其规则Rule中的loader都是后写的先执行。从空间上来看,就是从右到左,从下到上执行。 五、控制loader的执行顺序 用Rule.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。 configureWebpack配置 configureWebpack选项的值可以是对象,也可以是函数值为对象。 最后通过webpack-merge合并到最终的配置中。也就是说在这里,只能新增loader配置,不能修改loader配置或者删除lodaer配置。 例如在vue.config.js中配置
module.exports = {
configureWebpack:{
module:{
rules:[
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
}
]
}
},
}
执行npm run inspect后,在output.js中会发现,如下图所示
值为函数。 函数接收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']
}
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,原先处理.less文件的loader配置已经被替成后面修改的。
但是用这种方法去修改loader的配置,太粗放了,如果要进行更细粒度的修改loader配置,可以使用chainWebpack来配置。
chainWebpack配置 chainWebpack选项的值是一个函数,会接收一个基于webpack-chain 的 ChainableConfig 实例。采用链式写法来配置Webpack。 用法文档点这里we。 这里只讲关于loader配置的新增、修改、删除的用法。 新增一个规则Rule
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
},
}
添加规则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/')
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
也可以使用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/'],
})
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
添加规则Rule的loader
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
//先创建一个具名的use,后面修改有用到这个名称
.use('styleloader')
//往这个具名的use中添加一个loader
.loader('style-loader')
//添加多个loader时要先.end()回到主链路
.end()
.use('cssloader')
.loader('css-loader')
.end()
.use('lessloader')
.loader('less-loader')
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。注意书写顺序,最后写的先执行。
添加规则Rule的loader的参数 例如要给less-loader添加参数。
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.use('lessloader')
.loader('less-loader')
.options({
// 这里配置全局变量
globalVars: {
'primary': '#fff'
}
})
},
}
options()的参数是个对象,在对象里面配置loader的参数。 执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
修改规则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的参数的目的。 修改前
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面修改后生成的。
修改规则Rule的loader 修改前
有两种做法
1.修改其中一个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')
}
}
创建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')
}
}
执行npm run inspect后,在output.js中会发现,修改后的结果如下图所示。
控制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')
}
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
因为在同一个规则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')
}
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
此时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')
}
}
五、控制loader的执行顺序
用Rule.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。
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']
}
]
}
},
}
执行npm run inspect后,在output.js中会发现,如下图所示 值为函数。 函数接收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']
}
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,原先处理.less文件的loader配置已经被替成后面修改的。
但是用这种方法去修改loader的配置,太粗放了,如果要进行更细粒度的修改loader配置,可以使用chainWebpack来配置。
2.chainWebpack配置
chainWebpack选项的值是一个函数,会接收一个基于webpack-chain 的 ChainableConfig 实例。采用链式写法来配置Webpack。 用法文档点这里we。 这里只讲关于loader配置的新增、修改、删除的用法。 新增一个规则Rule
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
},
}
3.添加规则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/')
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
也可以使用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/'],
})
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
4.添加规则Rule的loader
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
//先创建一个具名的use,后面修改有用到这个名称
.use('styleloader')
//往这个具名的use中添加一个loader
.loader('style-loader')
//添加多个loader时要先.end()回到主链路
.end()
.use('cssloader')
.loader('css-loader')
.end()
.use('lessloader')
.loader('less-loader')
},
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。注意书写顺序,最后写的先执行。
5.添加规则Rule的loader的参数
例如要给less-loader添加参数。
module.exports = {
chainWebpack: config =>{
config.module
.rule('myRule')
.use('lessloader')
.loader('less-loader')
.options({
// 这里配置全局变量
globalVars: {
'primary': '#fff'
}
})
},
}
options()的参数是个对象,在对象里面配置loader的参数。 执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
6.修改规则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的参数的目的。 修改前
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面修改后生成的。
7.修改规则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')
}
}
修改后,创建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')
}
}
执行npm run inspect后,在output.js中会发现,修改后的结果如下图所示。
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')
}
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
因为在同一个规则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')
}
}
执行npm run inspect后,在output.js中会发现,如下图所示,就是上面配置生成的。
此时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')
}
}
作者:叶秋 链接:juejin.cn/post/685457… 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。