Ant Design React 從 v4 到 v5

2023-09-27 11:04 更新

本文檔將幫助你從 antd 4.x 版本升級到 antd 5.x 版本,如果你是 3.x 或者更老的版本,請先參考之前的升級文檔升級到 4.x。

升級準備

  1. 請先升級到 4.x 的最新版本,按照控制臺 warning 信息移除/修改相關的 API。

5.0 有哪些不兼容的變化

設計規(guī)范調整

  • 基礎圓角調整,由統(tǒng)一的 2px 改為四級圓角,分別為 2px 4px 6px 8px,分別應用于不同場景,比如默認尺寸的 Button 的圓角調整為了 6px。
  • 主色調整,由 #1890ff 改為 #1677ff。
  • 整體陰影調整,由原本的三級陰影調整為兩級,分別用于常駐頁面的組件(如 Card)和交互反饋(如 Dropdown)。
  • 部分組件內間距調整。
  • 整體去線框化。

技術調整

  • 棄用 less,采用 CSS-in-JS,更好地支持動態(tài)主題。底層使用 @ant-design/cssinjs 作為解決方案。
    • 所有 less 文件全部移除,less 變量不再支持透出。
    • 產(chǎn)物中不再包含 css 文件。由于 CSS-in-JS 支持按需引入,原本的 antd/dist/antd.css 也已經(jīng)移除,如果需要重置一些基本樣式請引入 antd/dist/reset.css。
    • 如果需要組件重置樣式,又不想引入 antd/dist/reset.css 從而導致污染全局樣式的話,可以嘗試在應用最外層使用App 組件,解決原生元素沒有 antd 規(guī)范樣式的問題。
  • 移除 css variables 以及在此之上構筑的動態(tài)主題方案。
  • LocaleProvider 在 4.x 中已經(jīng)廢棄(使用 <ConfigProvider locale /> 替代),我們在 5.x 里徹底移除了相關目錄 antd/es/locale-provider、antd/lib/locale-provider。
  • 內置的時間庫使用 Dayjs 替代 Moment.js,具體請查看 使用自定義日期庫。
  • 不再支持 babel-plugin-import,CSS-in-JS 本身具有按需加載的能力,不再需要插件支持。

兼容性調整

  • 不再支持 IE 瀏覽器。

組件 API 調整

  • 組件彈框的 classname API 統(tǒng)一為 popupClassNamedropdownClassName 等類似 API 都會被替換。

    • AutoComplete 組件
    • Cascader 組件
    • Select 組件
    • TreeSelect 組件
    • TimePicker 組件
    • DatePicker 組件
    • Mentions 組件
      import { Select } from 'antd';
    
      const App: React.FC = () => (
        <Select
    -     dropdownClassName="my-select-popup"
    +     popupClassName="my-select-popup"
        />
      );
    
      export default App;
    
  • 組件彈框的受控可見 API 統(tǒng)一為 open,visible 等類似 API 都會被替換。

    • Drawer 組件 visible 變?yōu)?open。
    • Modal 組件 visible 變?yōu)?open
    • Dropdown 組件 visible 變?yōu)?open。
    • Tooltip 組件 visible 變?yōu)?open。
    • Tag 組件 visible 已移除。
    • Slider 組件 tooltip 相關 API 收斂到 tooltip 屬性中。
    • Table 組件 filterDropdownVisible 變?yōu)?filterDropdownOpen。
      import { Modal, Tag, Table, Slider } from 'antd';
    
      const App: React.FC = () => {
        const [visible, setVisible] = useState(true);
    
        return (
          <>
    -       <Modal visible={visible}>content</Modal>
    +       <Modal open={visible}>content</Modal>
    
    -       <Tag visible={visible}>tag</Tag>
    +       {visible && <Tag>tag</Tag>}
    
            <Table
              data={[]}
              columns={[
                {
                  title: 'Name',
                  dataIndex: 'name',
    -             filterDropdownVisible: visible,
    +             filterDropdownOpen: visible,
                }
              ]}
            />
    
    -       <Slider tooltipVisible={visible} />
    +       <Slider tooltip={{ open: visible }} />
          </>
        );
      }
    
      export default App;
    
  • getPopupContainer: 所有的 getPopupContainer 都需要保證返回的是唯一的 div。React 18 concurrent 下會反復調用該方法。

  • Upload List dom 結構變化。#34528
  • Notification
    • 靜態(tài)方法不再允許在 open 中動態(tài)設置 prefixCls maxCount top bottom getContainer,Notification 靜態(tài)方法現(xiàn)在將只有一個實例。如果需要不同配置,請使用 useNotification
    • close 改名為 destroy,和 message 保持一致。
  • Drawer styleclassName 遷移至 Drawer 彈層區(qū)域上,原屬性替換為 rootClassNamerootStyle。
  • 4.x 中已經(jīng)廢棄的 message.warn 現(xiàn)在被徹底移除,請使用 message.warning 代替。

組件重構與移除

  • 移除 locale-provider 目錄。LocaleProvider 在 v4 中已移除,請使用 ConfigProvider 替代。
  • 移除 Comment 組件,移至 @ant-design/compatible 中維護。
  • 移除 PageHeader 組件,移至 @ant-design/pro-components 中維護。

    - import { PageHeader, Comment } from 'antd';
    + import { Comment } from '@ant-design/compatible';
    + import { PageHeader } from '@ant-design/pro-layout';
    
      const App: React.FC = () => (
        <>
          <PageHeader />
          <Comment />
        </>
      );
    
      export default App;
    
  • BackTop 組件在 5.0.0 中廢棄,移至 FloatButton 懸浮按鈕中。如需使用,可以從 FloatButton 中引入。

    - import { BackTop } from 'antd';
    + import { FloatButton } from 'antd';
    
      const App: React.FC = () => (
        <>
    -     <BackTop />
    +     <FloatButton.BackTop />
        </>
      );
    
      export default App;
    

開始升級

通過 git 保存你的代碼,然后按照上述文檔進行依賴安裝:

npm install --save antd@5.x

如果你需要使用 v4 廢棄組件如 Comment、PageHeader,請安裝 @ant-design/compatible@ant-design/pro-layout 做兼容:

npm install --save @ant-design/compatible@v5-compatible-v4
npm install --save @ant-design/pro-layout

你可以手動對照上面的列表逐條檢查代碼進行修改,另外,我們也提供了一個 codemod cli 工具 @ant-design/codemod-v5 以幫助你快速升級到 v5 版本。

在運行 codemod cli 前,請先提交你的本地代碼修改。

# 使用 npx 直接運行
npx -p @ant-design/codemod-v5 antd5-codemod src

# 或者使用 pnpm 直接運行
pnpm --package=@ant-design/codemod-v5 dlx antd5-codemod src

注意 codemod 不能涵蓋所有場景,建議還是要按不兼容的變化逐條排查。

less 遷移

如果你使用到了 antd 的 less 變量,通過兼容包將 v5 變量轉譯成 v4 版本,并通過 less-loader 注入:

const { theme } = require('antd/lib');
const { convertLegacyToken } = require('@ant-design/compatible/lib');

const { defaultAlgorithm, defaultSeed } = theme;

const mapToken = defaultAlgorithm(defaultSeed);
const v4Token = convertLegacyToken(mapToken);

// Webpack Config
module.exports = {
  // ... other config
  loader: 'less-loader',
  options: {
    lessOptions: {
      modifyVars: v4Token,
    },
  },
};

同時移除對 antd less 文件的直接引用:

// Your less file
--  @import (reference) '~antd/es/style/themes/index';
or
--  @import '~antd/es/style/some-other-less-file-ref';

移除 babel-plugin-import

從 package.json 中移除 babel-plugin-import,并從 .babelrc 移除該插件:

"plugins": [
- ["import", { "libraryName": "antd", "libraryDirectory": "lib"}, "antd"],
]

Umi 用戶可以在配置文件中關閉:

// config/config.ts or .umirc
export default {
  antd: {
-   import: true,
+   import: false,
  },
};

替換 Day.js 語言包

將 moment.js 的 locale 替換為 day.js 的 locale 引入:

-   import moment from 'moment';
+   import dayjs from 'dayjs';
-   import 'moment/locale/zh-cn';
+   import 'dayjs/locale/zh-cn';

-   moment.locale('zh-cn');
+   dayjs.locale('zh-cn');

如果你暫時不想替換 day.js,也可以使用 @ant-design/moment-webpack-plugin 插件將 day.js 替換回 moment.js:

npm install --save-dev @ant-design/moment-webpack-plugin
// webpack-config.js
import AntdMomentWebpackPlugin from '@ant-design/moment-webpack-plugin';

module.exports = {
  // ...
  plugins: [new AntdMomentWebpackPlugin()],
};

使用 V4 主題包 Updated

如果你不希望樣式在升級后發(fā)生變化,我們在兼容包中提供了完整的 V4 主題,可以還原到 V4 的樣式。

const sandpackConfig = {
  dependencies: {
    '@ant-design/compatible': 'v5-compatible-v4',
  },
};

import {
  defaultTheme,   // 默認主題
  darkTheme,      // 暗色主題
} from '@ant-design/compatible';
import { ConfigProvider, Button, Radio, Space } from 'antd';

export default () => (
  <ConfigProvider theme={defaultTheme}>
    <Space direction="vertical">
      <Button type="primary">Button</Button>
      <Radio.Group>
        <Radio value={1}>A</Radio>
        <Radio value={2}>B</Radio>
        <Radio value={3}>C</Radio>
        <Radio value={4}>D</Radio>
      </Radio.Group>
    </Space>
  </ConfigProvider>
);

舊版瀏覽器兼容

Ant Design v5 使用 :where css selector 降低 CSS-in-JS hash 值優(yōu)先級,如果你需要支持舊版本瀏覽器(如 IE 11、360 瀏覽器 等等)??梢酝ㄟ^ @ant-design/cssinjsStyleProvider 去除降權操作。詳情請參閱 兼容性調整。

多版本共存

一般情況下,并不推薦多版本共存,它會讓應用變得復雜(例如樣式覆蓋、ConfigProvider 不復用等問題)。我們更推薦使用微應用如 qiankun 等框架進行分頁研發(fā)。

通過別名安裝 v5

$ npm install --save antd-v5@npm:antd@5
# or
$ yarn add antd-v5@npm:antd@5
# or
$ pnpm add antd-v5@npm:antd@5

對應的 package.json 為:

{
  "antd": "4.x",
  "antd-v5": "npm:antd@5"
}

現(xiàn)在,你項目中的 antd 還是 v4 版本,antd-v5 是 v5 版本。

import React from 'react';
import { Button as Button4 } from 'antd'; // v4
import { Button as Button5 } from 'antd-v5'; // v5

export default () => (
  <>
    <Button4 />
    <Button5 />
  </>
);

接著配置 ConfigProvider 將 v5 prefixCls 改寫,防止樣式?jīng)_突:

import React from 'react';
import { ConfigProvider as ConfigProvider5 } from 'antd-v5';

export default () => (
  <ConfigProvider5 prefixCls="ant5">
    <MyApp />
  </ConfigProvider5>
);

需要注意的是,npm 別名并不是所有的包管理器都有很好的支持。

遇到問題

如果您在升級過程中遇到了問題,請到 GitHub issues 進行反饋。我們會盡快響應和相應改進這篇文檔。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號