create-react-app不运行 eject 配置less

问题的由来

crate-react-app是我们非常常用的初始化项目点的工具,在默认情况下,刚创建的好的项目是没有暴露出配置的,如果需要暴露则需要运行对应的命令:

yarn/npm run eject

但是既然官方不推荐我们来暴露这些配置,那么有没有办法不暴露配置就能实现我们的一些常用配置呢?

答案是肯定的:
有多种方式可以实现,我这里具体讲讲我探究出来的方案:
基于customize-cra 来配置less .

customize-cra的可配置项

开始配置

首先按照基本的套路来,先安装对应的库

yarn add customize-cra  react-app-rewired --save-dev
// 或者
npm install customize-cra  react-app-rewired --save-dev

接着我们在根目录下创建一个文件名为 config-overrrides的文件,输入如下代码:

const {
  override,
} = require('customize-cra');

module.exports = override(
  // 这里我们将实现对默认设置的覆盖条件
)

紧接着,我们来修改package.json里的scrip 命令:

 // 修改前
    "start": "react-scripts start",
    "build": "react-scripts build",
    "eject": "react-scripts eject"
// 修改后
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "eject": "react-scripts eject"

这里我们暂且保留 eject ,也许你不想配置了的时候还能继续使用,或者碰到其他解决不了的问题了想来暴露配置,这里预览。

配置less

less 是我们常用的css 预处理工具,能够提供给我们样式嵌套等丰富的功能,所以我们这里使用less.
还是老套路,先安装对应的库:

yarn add less less-loader  --save-dev
或者
npm install less less-loader --save-dev

接着在config-overrides文件中增加less文件配置:

const {
  override,
  addLessLoader,
} = require('customize-cra');

module.exports = override(
  addLessLoader({  
    lessOptions: { 
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    },
    sourceMap:true,
  }),
)

这里我们有一点需要特别注意的:
less-loader的版本问题
如果你是5.0.0的版本这里的配置应该是这个样子的:

const {
  override,
  addLessLoader,
} = require('customize-cra');

module.exports = override(
  addLessLoader({  
    javascriptEnabled: true,
    modifyVars: { '@primary-color': '#1DA57A' },
    sourceMap:true,
  }),
)

即没有lessOptions这一层;
这里我们的less 就配好了,可以将样式文件名称改为.less,然后代码中引入并使用:

配置css module

如果我们仅仅只是想使用less 并且用到css module,可以用一下方式:

方案1:

less-loader :版本为5.0.0

const {
  override,
  addLessLoader,
} = require('customize-cra');

module.exports = override(
  addLessLoader({  
    javascriptEnabled: true,
    modifyVars: { '@primary-color': '#1DA57A' },
    sourceMap:true,
    cssLoaderOptions: { 
    	modules: true,
	},
  }),
)

此方案有一个缺点,就是生成的类名完全是hash模式,不方便后期调试。

方案2

less-loader :版本为6及以上

const {
  override,
  addLessLoader,
  adjustStyleLoaders,
} = require('customize-cra');

module.exports = override(
  addLessLoader({  
    javascriptEnabled: true,
    modifyVars: { '@primary-color': '#1DA57A' },
    sourceMap:true,
  }),
  adjustStyleLoaders(({ use: [ , css] }) => {
    css.options.sourceMap = true;
    css.options.modules = {
      // 配置默认的样式名称规则
      localIdentName:'[name]__[local]--[hash:base64:5]',
    } 
  })
)

使用antd的时候发生冲突

产生原因:antd 默认是采用less 来渲染样式的,如果我们页面里采用css modules, 就会将antd的less文件也给编译一遍,导致样式渲染异常,所以我吗要排除掉对antd的影响。

less-loader版本 6及以上,最终的配置如下:

const {
  override,
  fixBabelImports,
  addLessLoader,
  adjustStyleLoaders,
} = require('customize-cra');

module.exports = override(
  // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true, //自动打包相关的样式 默认为 style:'css'
  }),
  // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
  addLessLoader({  
    lessOptions: { 
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    },
    sourceMap:true,
  }),
  adjustStyleLoaders(({ use: [ , css] }) => {
    css.options.sourceMap = true;
    css.options.modules = {
      // 配置默认的样式名称规则
      localIdentName:'[name]__[local]--[hash:base64:5]',
      getLocalIdent:(loaderContext, localIdentName, localName, options) => {
        // 处理antd 的样式
        if (loaderContext.resourcePath.includes('node_modules')) {
          return localName;
        }       
      }
    } 
  })
)

最终效果:

index.js

import React from "react";
import {
  Button
} from "antd";
import * as styles from "./style.less";

console.log(styles);

class Deom extends React.Component {
  render() {
    return <div className={styles.bbb}>
      <Button type="primary">antd button</Button>
        <div className={styles.test}>测试文字</div>
    </div>
  }
};

export default Deom;

style.less


.bbb {
  background: pink;
  .test {
    color: red;
  }
}

create-react-app不运行 eject 配置less_第1张图片

参考文章:
lessOptions 参数
lessLoader 版本的区别
getLocalIdent函数的灵感来源

你可能感兴趣的:(CSS,less,react)