一文掌握less-loader在vue.config.js中的高级配置

4,942 阅读4分钟

引言:随着vue-cli以及less语法的普及,极大程度的方便了大家对组件的开发和控制。至于如何在vue-cli搭建的项目中引入对less的资源配置,相信大家都曾遇到这样的问题。不过本文的重点是less-loader里的那些高级配置,帮助大家从编译构建的角度掌握less-loader在vue.config.js中的高级配置。

关键词:vue-cli、less-loader、lessOptions、prependData、appendData

1. vue.config.js中的less基本配置

module.exports = {
    css: {
        loaderOptions: {
            less: {
                lessOptions: {
                    javascriptEnabled: true 
                } 
            } 
        } 
    } 
}

与直接在webpack.config.js中配置less-loader不同,由于项目是通过vue-cli搭建起来,而vue-cli把webpack配置这部分内容也封装起来,对开发者只暴露出来一个vue.config.js配置文件。正常情况下只通过vue.config.js做一些简单的资源解析配置就可以满足需要,但是遇到一些比较复杂的需求可能就会造成阻碍。

2.简单配置无法满足的复杂需求

比如从编译层面在全局声明less变量、在less文件引入前或者引入后添加less变量、引入某个less文件之后再引入别的less文件进行变量覆盖等等。

以上需求主要是基于less的变量机制,在组件封装组件库主题定制项目主题设计等方面非常有价值。因为通过变量可以更加灵活的实现样式控制,极大程度的封装和重定义

3. 查找vue-cli源码对less-loader的处理

首先要找到vue-cli是如何处理less-loader配置的,毕竟是黑盒,要从官网和源码入手,查找过程比较曲折,最后找到是在@vue/cli-service/lib/config/css.js文件中使用css文件解析配置。这里我使用的版本是vue-cli@4.5.14。

由于重点不在于解读vue-cli源码,所以我直接提供一段对less-loader配置处理的源码截图,其余部分如果大家感兴趣的话,可以自己去对应的源码里学习。

vue-cli-css.png

可以找到对应的行数231行,很明显loaderOptions.less正好就是我们在vue.config.js中配置的对象结构,那也就是说最终传递给less-loader的配置是{lessOptions: {javascriptEnabled: true}}。知道这些对于我们在vue-config.js中活用less-loader配置已经足够了,下面开始接触less-loader的高级配置。

4. less-loader的高级配置prependData和appendData

less-loader的高级配置,官网其实是不全的,比如在对less文件引入前或者引入后添加代码这个需求点,less-loader也是支持的,可以通过设置prependData和appendData实现,只不过在webpack中文官网甚至连它自己的github里的README都没有提到。。。

这里我们直接从源码入手,可以从less-loader/dist/options.json中看到全面的配置信息。

{
  "type": "object",
  "properties": {
    "lessOptions": {
      "description": "Options to pass through to `Less` (https://github.com/webpack-contrib/less-loader#lessoptions).",
      "anyOf": [
        {
          "type": "object",
          "additionalProperties": true
        },
        {
          "instanceof": "Function"
        }
      ]
    },
    "prependData": {
      "description": "Prepends `Less` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata).",
      "anyOf": [
        {
          "type": "string"
        },
        {
          "instanceof": "Function"
        }
      ]
    },
    "appendData": {
      "description": "Add `Less` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata).",
      "anyOf": [
        {
          "type": "string"
        },
        {
          "instanceof": "Function"
        }
      ]
    },
    "sourceMap": {
      "description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/less-loader#sourcemap).",
      "type": "boolean"
    },
    "implementation": {
      "description": "The implementation of the `Less` to be used (https://github.com/webpack-contrib/less-loader#implementation).",
      "type": "object"
    }
  },
  "additionalProperties": false
}

可以看到我们使用prependData和appendData就能在less文件解析之前或者之后添加对应的代码处理。

5.学习less-loader源码

下面学习一下less-loader的入口文件代码,也是有相关配置api的使用信息。说到webpack的loader自定义写法,其实loader就是一个导出为函数的js文件,该函数的入参是源代码,输出是处理之后的代码块。

less-loader源码.png

从源码不难看出,我们使用prependData和appendData不仅可以传递一个"代码字符串",还可以传递一个函数,入参是less-loader的执行上下文。

module.exports = {
    css: {
        loaderOptions: {
            less: {
                lessOptions: {
                    javascriptEnabled: true
                },
                // 在解析less文件之前引入a.less内的变量,作用:提前声明
                prependData: `@import "a.less";`,
                // 在解析less文件之后引入b.less内的变量,作用:进行覆盖
                appendData: `@import "b.less";`
            } 
        } 
    } 
}

彩蛋

其实less-loader的github地址里有个地方隐藏了对prependData和appendData的描述,位置在github.com/webpack-con…,也就是changelog里有记录,不过官方README里一直没有更新这部分。

less-loader-changelog.png