[关闭]
@MickeyWang 2018-01-11T15:41:33.000000Z 字数 2752 阅读 1429

vue中引入全局less的问题分析

forJD


问题描述

现状:在hotel项目中,用less作为css预处理器,现在src/assets/css目录下有common.less文件,需要在每个组件中显式引入。

期望:现想在全局引入一个less文件,其中的变量及mixin等便可在各子组件得以访问,不必主动引入。

方案尝试

  1. require('!style-loader!css-loader!less-loader!./assets/css/common.less');

结果:子组件中无法访问到common.less

结果:子组件中无法访问到common.less

  1. let lessOptions = {
  2. includePaths: [
  3. '../src/assets/css'
  4. ],
  5. data: '@import "~common.less";'
  6. }
  7. ···
  8. return {
  9. css: generateLoaders(),
  10. postcss: generateLoaders(),
  11. less: generateLoaders('less', lessOptions),
  12. sass: generateLoaders('sass', { indentedSyntax: true }),
  13. scss: generateLoaders('sass'),
  14. stylus: generateLoaders('stylus'),
  15. styl: generateLoaders('stylus')
  16. }

结果:子组件中无法访问到common.less

结果:依旧达到预期效果

分析与结论

在此整理一些论坛、文章中关于此问题的延伸与观点。

  1. @import '~assets/css/common.less';

可实践的方案

可以为less-loader在加载时注入全局变量。

方案思路

  1. loader: "less-loader",
  2. options: {
  3. globalVars: {
  4. 'primary-color': 'blue'
  5. }
  6. }

这样做对于全局变量的添加是生效的,为了方便后期配置维护,可以将所有需要的全局变量存入一个less文件,然后解析注入到配置项中

下面是本次在hotel项目中,对于以上方案的实现。

hotel中的改造记录

1、首先在webpack.base.conf.js文件的vue-loader配置项中,添加cssLoader的相关处理配置,即添加第9行。

  1. {
  2. test: /\.vue$/,
  3. loader: 'vue-loader',
  4. options: {
  5. js: 'babel-loader',
  6. postcss: [
  7. require('autoprefixer')()
  8. ],
  9. loaders: utils.cssLoaders()
  10. }
  11. }

2、对utils.jscssLoaders方法的返回值增加对于less的配置。(第4、5、6行)

  1. return {
  2. css: generateLoaders(),
  3. postcss: generateLoaders(),
  4. less: generateLoaders('less',{
  5. globalVars: getLessVariables(config.themePath)// 读取less全局变量文件
  6. }),
  7. sass: generateLoaders('sass', { indentedSyntax: true }),
  8. scss: generateLoaders('sass'),
  9. stylus: generateLoaders('stylus'),
  10. styl: generateLoaders('stylus')
  11. }

3、同时在cssLoaders方法中加入读取less全局变量文件的方法

  1. // 读取less全局变量文件
  2. function getLessVariables(file) {
  3. var themeContent = fs.readFileSync(file, 'utf-8')
  4. var variables = {}
  5. themeContent.split('\n').forEach(function(item) {
  6. if (item.indexOf('//') > -1 || item.indexOf('/*') > -1) {return}
  7. var _pair = item.split(':')
  8. if (_pair.length < 2) return;
  9. var key = _pair[0].replace('\r', '').replace('@', '')
  10. if (!key) return;
  11. var value = _pair[1].replace(';', '').replace('\r', '').replace(/^\s+|\s+$/g, '')
  12. variables[key] = value
  13. })
  14. return variables
  15. }

4、最后在assets/css目录下添加全局less变量文件theme.less。(注意遵循命名规范)

  1. // 请以'g-'开头命名,以区分全局与局部less变量
  2. @g-primary-color: grey;

使用用例

在之后的开发使用上,只需要维护theme.less文件,以及在需要引入全局变量的地方引入即可。如下:

  1. .mainColor {
  2. color: @g-primary-color;
  3. }

需要注意的是,theme.less文件的加载时机是在webpack打包前,所以只加载一次,不支持热更新(HMR),更改theme.less文件后,需要重启服务以生效

参考文档1
参考文档2

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注