# React + antd 4.x + craco-antd 按需加載以及自定義樣式
###### tags: `React` `craco-antd` `babel-plugin-import` `configure`
:::info
- antd 4.x 後的版本也是用 craco 進行配置的 [(參考)](https://ant.design/docs/react/use-with-create-react-app-cn#%E9%AB%98%E7%BA%A7%E9%85%8D%E7%BD%AE)
- 所以開始之前,可以先了解一下 craco 並且配置配起來 [craco 配置](https://hackmd.io/@yellow/S1mlj0yCK)
:::
<br />
> 依照 antd 官方說明,antd 是通過 `ES6 Module` 的 `export` 來匯出各個元件,直接使用 `import { Button } from 'antd'` 就有匯入單元 JS 檔案的效果。
> [官方示例](https://ant.design/docs/react/getting-started-cn#2.-%E4%BD%BF%E7%94%A8%E7%BB%84%E4%BB%B6)
首先先安裝 antd
```
yarn add antd
```
接著直接手使用,但在使用當中發現,我們還需要引用全部的元件樣式?!
```javascript
import { Button } from 'antd';
import 'antd/dist/antd.css'; // 就是這行引用了 antd 所有 css~
```
這樣會造成可能只需要使用一個按鈕元件,但卻把所有樣式都引入了!!
執行 `yarn build` 打包出來的大小 `62.5KB`
```
62.5 KB build/static/css/2.289e503f.chunk.css
```
<br />
當然也可以只引用需要的元件樣式,像是:
```javascript
import { Button } from 'antd';
import 'antd/lib/button/style/index.css';
```
執行完打包,大小為 `3.47KB`, 小了很多呢!!
```
3.47 KB build/static/css/2.2f9f3c50.chunk.css
```
<br />
只是這樣會有個問題,就是當元件引用很多個的時候,引入的樣式也要變更多,在撰寫上就會顯得不方便 :cry:
```
import { Button, Alert, Badge } from 'antd';
import 'antd/lib/button/style/index.css';
import 'antd/lib/alert/style/index.css';
.
.
.
```
<br />
## craco-antd
查了一下發現 `babel-plugin-import` 可以解決這個問題。
> [實際運作可以參考 >> ](https://github.com/umijs/babel-plugin-import#example)
> 大致上實現的就是引用單一元件並且引入其樣式。
而使用方法需要新增 `.babelrc` 檔案去設定,實際造步驟完成是沒有效果的,那是因為在 CRA 中默認不是使用 `.babelrc` 檔案,而是使用 `package.json` 中的 `babel` 和內部配置。
既然這樣,打開 [craco 文檔](https://github.com/gsoft-inc/craco) 快速搜尋一下 antd,啊哈

<br />
### 點開 [craco-antd](https://github.com/DocSpring/craco-antd#craco-ant-design-plugin)
可以看到 `craco-antd` 包含了 `craco-less` 以及 `babel-plugin-import`

## 於是照著官方步驟:
### 1. 安裝
```
yarn add craco-antd
```
<br />
### 2. 配置
新增 `craco-antd` 到 `craco.config.js`
```javascript
const path = require('path');
const CracoAntDesignPlugin = require('craco-antd'); // ++
module.exports = {
plugins: [{ plugin: CracoAntDesignPlugin }], // ++
webpack: {
alias: {
'@': path.resolve(__dirname, 'src/'),
'@VIEW': '@/view',
'@COM': '@/components',
'@HOOK': '@/hook'
}
}
};
```
修改原本引用 antd 的地方並起重啟,可以發現不用在特別引入樣式檔案
```
import { Button } from 'antd';
// import 'antd/dist/antd.css'; // 註解這行
```
<br />
### 3. 打包 查看 bundle
執行完打包,大小為 7 KB,太棒了簡單兩行就搞定了
```
7 KB build/static/css/2.3fa9fe8f.chunk.css
```
<br />
### 4. antd 自定義樣式
在 antd 官方教學中需要安裝 `craco-less`,而 `craco-ant` 就已包含了,也有提[供配置教學](https://github.com/DocSpring/craco-antd#customize-ant-design-theme)
這裡自定樣式有兩種方式:
- 直接將覆蓋變數寫進 `craco.config.js` 裡
- 或是另外新增一隻 `less` >> 推推這個
#### 這邊直接新增一隻 less
- `src/style/AntDesign/customTheme.less`
```less
// customTheme.less
@primary-color: #1da57a;
@link-color: #1da57a;
```
[看更多變數名稱 >>](https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less)
- 修改 craco 配置
```javascript
const path = require('path');
const CracoAntDesignPlugin = require('craco-antd');
module.exports = {
plugins: [{
plugin: CracoAntDesignPlugin,
// ++
options: {
customizeThemeLessPath: path.join(
__dirname,
"src/style/AntDesign/customTheme.less"
),
},
}],
webpack: {
alias: {
'@': path.resolve(__dirname, 'src/'),
'@VIEW': '@/view',
'@COM': '@/components',
'@HOOK': '@/hook'
}
}
};
```
:::warning
記得更改配置後,都需要重啟才會更新!
:::
<br />
### 5. 在開發環境自動更新變動
在 `craco-antd` 文件中有提到 [Reload Custom Variables During Development](https://github.com/DocSpring/craco-antd#reload-custom-variables-during-development)
在開發時自動更新 less,但因為這些變數都是設定到 wabpack 裡,所以還是需要重新啟動,自動更新意思就是自動重啟啦
文件的做法是透過 `nodemon -w` 去監聽檔案更改時去執行 `craco start`
當然你也可以自己手動重啟~
如果想要在更新 `carco.config` 時也能自動重啟的話,可以把檔案加進指令裡
```javascript
"scripts": {
"start": "nodemon -w craco.config.js -w ./antd.customize.less --exec \"craco start\"",
}
```