引言

这两天正在学习react,学习使用ant-desgin快速搭建网站,在配置按需引入和自定义主题的时候,遇到一些问题,特此记录一下整个配置流程和解决方案的过程。如果仅仅是想看如何配置的伙伴,请移步至第五节总结部分。

注:本次配置好的项目可以查看GitHub地址,寻找源码。

一、准备工作

1、项目搭建

我们先使用create-react-app创建一个react项目,方便后面的ant-design的引入和基本样式的搭建,这里直接创建一个小demo。

create-react-app demo

如果你的电脑没有安装create-react-app的话,请使用如下命令进行安装:

npm install create-react-app -g

项目搭建:项目搭建中
项目搭建完毕之后我们使用vscode打开项目,并使用npm start或者是yarn start启动项目。

项目最初样子

2、项目初始化

当然,我们在后续的使用时,并不需要这些东西,所以要把src目录下面的index.js留下,其他的全部删掉,并新建一个App.jsx

index.js如下

import React from "react"
import ReactDOM from "react-dom/client"

import App from './App'

const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(
    <App/>
)

App.jsx如下:

import React, { Component } from 'react'

export default class App extends Component {
  render() {
    return (
      <div>App</div>
    )
  }
}

修改好后运行的效果如下,只有App一个单词:
在这里插入图片描述

3、安装antd

接下来就是安装ant-design到这个小demo中,点击这里前往ant-desgin的官网。

我们使用yarn命令安装:

yarn add antd

安装中:
在这里插入图片描述
安装完毕:
在这里插入图片描述

二、使用ant-design

这里将介绍antd的基本使用,只要学会了一个组件的使用,其他组件的使用方式也是大同小异,由于只是简单的演示,所以一切样式都在App组件里面实现。

1. Button按钮组件

选用最基础的一种样式,点开下面的显示代码:
在这里插入图片描述
antd中引入Button组件:

import { Button } from 'antd';

render区域使用此组件:

<Button type="primary">Primary Button</Button>

最终App组件里面的代码如下:

import React, { Component } from 'react'

import { Button } from 'antd'

export default class App extends Component {
  render() {
    return (
      <div>
        App... <br />
        <Button type="primary">Primary Button</Button>
      </div>
    )
  }
}

2. icon图标组件

antd的图标是语义化的矢量图形。使用图标组件,需要先安装 @ant-design/icons 图标组件包:

yarn add @ant-design/icons

选择一组想要展示的图标,点击这个图标,会自动复制这个图标组件的标签,将其粘贴到需要展示图标的组件中。
在这里插入图片描述在这里插入图片描述

render() {
  return (
    <div>
      ....
      <DingtalkOutlined />
      <WechatOutlined />
    </div>
  )
}

但是这样是还不能显示图标的,需要引入刚才安装的图标组件包。
在这里插入图片描述
引入所需图标:

import { DingtalkOutlined, WechatOutlined } from '@ant-design/icons'

保存重新编译之后,这两个图标就能在页面上正常显示了。

3. 引入样式+解决样式引入报错的问题

现在App组件里面的代码如下:

import React, { Component } from 'react'

import { Button } from 'antd'
import { DingtalkOutlined, WechatOutlined } from '@ant-design/icons'

export default class App extends Component {
  render() {
    return (
      <div>
        App... <br />
        <Button type="primary">Primary Button</Button>
        <br />
        <DingtalkOutlined />
        <WechatOutlined />
      </div>
    )
  }
}

我们可以看到,Button组件里面使用了typeAPI,定义其类型为primary,这个按钮的颜色应该是主题蓝色才对,但是页面中的按钮,却是没有颜色的:
在这里插入图片描述

打开node_modules文件夹下antd/dist,可以看到有一个antd.css的文件,里面存放了antd的所有样式。

antd从4.x开始,就将组件和样式等文件都分开了,刚才在引入Button组件的时候是从antd.js中引入,并没有引入antd.css,所以这里需要引入一下这个css文件,才能正常显示样式。

import 'antd/dist/antd.css'

保存重新编译之后,查看浏览器。
在这里插入图片描述

样式完成显示了,但是不要着急,切换到控制台看一下输出:
在这里插入图片描述
一堆警告……

根据这些警告,我找到了antdissues,找到如下解决办法。

(1) 将antd.css修改成antd.min.css再引入:
在这里插入图片描述

import 'antd/dist/antd.min.css'

查看结果,控制台无报错:
在这里插入图片描述
浏览器里面的样式也是没有问题的,这个方法可行。
在这里插入图片描述

(2) 新建一个App.css,在里面使用@import引入样式,然后再将App.css引入到App组件中
在这里插入图片描述
删掉上一个方法的引入,在App.css中的引入如下:

@import '~antd/dist/antd.css'

App组件中的引入如下:

import './App.css'

保存编译之后,控制台没有报错:
在这里插入图片描述
浏览器中样式显示正常:
在这里插入图片描述
至此,antd的基本使用已经讲解完毕,后续在使用其他组件也是差不多的方法,可以查看每个组件的API,给组件添加事件、样式、属性等。

三、antd的按需引入

在上面的样式引入中,我们直接引入了整个antd.css文件,加载了所有antd组件的样式(gzipped 后一共大约 60kb)。

我们直接用SpaceSniffer看一下全部引入css样式后打包的的体积,可以看到css样式表文件占据一大部分。
在这里插入图片描述
打包时间比较长,有251.47s
在这里插入图片描述

整个文件的打包体积也达到了2.7MB之多。

在这里插入图片描述

跟着我引入antd组件的小伙伴都知道,在上面的代码编写中,我们只放了一个Button按钮组件(icon图标是来源于@ant-design/icons 图标组件包),很显然我们引入了很多无用的组件样式。这个时候,如果react能根据我们所写的组件,导入对应组件所需的样式,这样在项目打包的时候,就能节省一大部分空间。

ant-design官方提供了按需引入的方式,在高级配置中可以看到具体的配置方式,这里我将具体的配置做了如下总结。

1. 安装依赖并修改package.json

此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 react-app-rewired (一个对 create-react-app 进行自定义配置的社区解决方案)。

引入 react-app-rewired 并修改 package.json 里的启动配置。由于新的 react-app-rewired@2.x 版本的关系,你还需要安装 customize-cra

yarn add react-app-rewired customize-cra

修改package.json的scripts节点,更改默认的执行脚本。

/* package.json */
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
},

在项目的根目录下面新建一个config-overrides.js文件,在里面添加如下配置代码,用于默认配置。

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  return config;
};

此时我们还没有进行任何配置,所以说配置还不能生效。

2. 按需加载的babel插件

我们需要安装一个能够按需加载组件代码和样式的插件babel-plugin-import

babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件(原理)。

yarn add babel-plugin-import

config-overrides.js中的配置替换成下面的配置选项。

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
);

移除App.css中使用@import引入css文件的代码,重新启动项目。

控制台无报错:
在这里插入图片描述
浏览器中样式显示正常:
在这里插入图片描述

我们将配置好的项目打包,看看打包后的结果。

首先还是打包时间,缩小到124.92s:
在这里插入图片描述

然后就是打包体积,css样式表的体积已经减小了很多:
在这里插入图片描述

打包后的整体体积也差不多缩小为原来的三分之一:
在这里插入图片描述

这里我为了方便做对比,新建了一个demo-1的小demo,除了按需引入部分配置,内容和插件安装方式等都是和刚开始的demo是一样的。
在这里插入图片描述

四、自定义主题

我们在使用antd的时候不难发现,不管是按钮的默认颜色还好,还是时间选择组件,还是input输入框的focus边框颜色,都是基于支付宝蓝作为主题色进行设计的。但是在项目开发中,也有其他的主题颜色的需求。

常见的修改方式就是,找到设置组件为蓝色那个class选择器,在里面写上需要的颜色,然后加上权重。这种方式进行样式修改也是可行的,但是在设计antd的时候,设计者可能也添加了权重,导致我们自己定义的颜色不一定能显示。而且如果需要修改多个组件的主题色的话,多次定义就显得比较麻烦。

对于以上情况,antd官网也提供了想要的配置方法,但是我在自己配置的时候,踩了不少坑,现在就一一进行配置,并填补这些坑。

1. 安装less和less-loader

antd在设计的时候,使用less进行组件样式的设定。官方文档提到需要使用less变量覆盖功能,替换成我们需要的主题。引入 customize-cra 中提供的 less 相关的函数 addLessLoader 来帮助加载 less 样式,同时修改 config-overrides.js 文件。

首先安装less和less-loader

yarn add less less-loader

2. 更改config-overrides.js相关配置

找到config-overrides.js 文件,把fixBabelImports函数下面的style的值由'css'改为true

然后再这个函数的后面添加以下代码:

addLessLoader({
  javascriptEnabled: true,
  modifyVars: { '@primary-color': '#1DA57A' }, // #以及后面的就是你需要切换的主题色,更改这个颜色代码就可以更改主题色了
}),

这里利用了 less-loadermodifyVars 来进行主题配置。

yarn start重启项目:
在这里插入图片描述
有报错,说是我们配置的对象是无效的,且在配置中modifyVars是未知的,

ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'modifyVars'. These properties are valid:
   object { lessOptions?, additionalData?, sourceMap?, webpackImporter?, implementation? }
    at validate 

查看customize-craissues找到,我们所添加到addLessLoader里面的配置由于less-loader的更新,新版本的写法发生了变化,原来addLessLoader的配置选项现在需要嵌套到一个lessOptions对象中去。
在这里插入图片描述
新版本的写法应该是这样的:

// config-overrides.js
const { override, fixBabelImports, addLessLoader } = require('customize-cra');

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    }
  }),
);

修改完之后,还是yarn start重启项目:
在这里插入图片描述

还是有报错(捂脸),但是这个报错和之前不一样了,这个问题是由于使用了create-react-app的问题,因为版本升级到了5.0.1,所以webpack的版本也变成了5.0.1,
在这里插入图片描述

我们可以在config-overrides.js文件中addLessLoader后面添加如下代码:

adjustStyleLoaders(({ use: [, , postcss] }) => {
  const postcssOptions = postcss.options;
  postcss.options = { postcssOptions };
})

别忘了在前面require引入的时候,添加adjustStyleLoaders的引入。

最终config-overrides.js的配置代码如下:

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    }
  }),
  adjustStyleLoaders(({ use: [, , postcss] }) => {
    const postcssOptions = postcss.options;
    postcss.options = { postcssOptions };
  })
);

然后重启项目即可。

控制台输出无报错:
在这里插入图片描述

浏览器页面已经修改成所需颜色:

配置的颜色:
在这里插入图片描述
显示的颜色:
在这里插入图片描述

3. 拓展

我们在配置的时候,肯定不可能只是定义全局主色这么简单,还可能需要配置其他的颜色、字号、圆角大小等,可以参考选下面的通用变量,所有的样式变量点击这里可以查看。

@primary-color: #1890ff; // 全局主色
@link-color: #1890ff; // 链接色
@success-color: #52c41a; // 成功色
@warning-color: #faad14; // 警告色
@error-color: #f5222d; // 错误色
@font-size-base: 14px; // 主字号
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
@text-color-secondary : rgba(0, 0, 0, .45); // 次文本色
@disabled-color : rgba(0, 0, 0, .25); // 失效色
@border-radius-base: 4px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影

五、总结

这里就写上一步到位的配置吧,不用弯弯绕绕了,有需求的小伙伴直接安装配置就行。

1. 安装插件

安装ant-design

## yarn
yarn add antd
## npm
npm install antd

安装@ant-design/icons 图标组件包:

## yarn
yarn add @ant-design/icons
## npm
npm install @ant-design/icons

按需引入插件安装:

## yarn
yarn add react-app-rewired customize-cra babel-plugin-import
## npm
npm install react-app-rewired customize-cra babel-plugin-import

自定义主题安装less 和 less-loader

## yarn
yarn add less less-loader
## npm
npm install less less-loader

2. 选项配置

修改package.json中scripts节点:

/* package.json */
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
},

在项目根目录新建一个名为config-overrides.js的文件

按需引入组件和组件css样式表配置代码:

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
);

按需引入+自定义主题配置代码:

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    }
  }),
  adjustStyleLoaders(({ use: [, , postcss] }) => {
    const postcssOptions = postcss.options;
    postcss.options = { postcssOptions };
  })
);

按需引入+自定义主题配置代码:

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    }
  }),
  adjustStyleLoaders(({ use: [, , postcss] }) => {
    const postcssOptions = postcss.options;
    postcss.options = { postcssOptions };
  })
);

有什么问题请指正!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐