Ant-design: SVG图标使Bundde尺寸过大

创建于 2018-09-03  ·  223评论  ·  资料来源: ant-design/ant-design


Issuehunt badges

  • []我搜索了此存储库的问题,并认为这不是重复的。

3.9.0

环境

webpack4

复制链接

https://zlab.github.io/report.html

重现步骤

webpack构建

期望什么?

icon按需打包,js文件拆分

实际发生了什么?

打包到chunk-vendors里去了




IssueHunt摘要

vagusx

支持者(总计:$ 203.00)

  • issuehunt
  • rororofff
  • ssprettychill

提交拉取请求

- #18217使用蚂蚁设计图标4.0

提示

IssueHunt得到了以下赞助商的支持。 成为赞助商

Rewarded on Issuehunt Inactive IssueHuntFest ❓FAQ 🗣 Discussion

最有用的评论

💢 脑壳痛。。。。大爷的。。。

所有223条评论

此问题的翻译:


antd svg软件包太大,建议按需使用@ ant-design / icons软件包

  • []我搜索了此存储库的问题,并认为这不是重复的。

3.9.0

环境

Webpack4

复制链接

https://zlab.github.io/report.html

重现步骤

Webpack构建

期望什么?

图标包根据需要,js文件拆分

实际发生了什么?

包装成块供应商

我只用到了几个icon

image

<Icon /> 默认全量引入了图标库。因为不知道你会引入何种图标进行运行时引入。之前图标托管在 iconfont.cn 所以打包无感知。

这需要深入讨论
临时方案见 https://github.com/ant-design/ant-design/issues/12011#issuecomment-420038579

cc @yesmeck

需要提供一个可以按需加载的方式,antd 组件内部也用这个方式。

import Star from 'antd/icons/star';

<Star />

但是这样做的话,以前的写法无法兼容

<Icon type="star" /> // should import star icon first

不能按需打包, 异步加载也好啊,

之前使用iconfont就是页面内容会先出来, 图标会慢慢加载出来

<Icon.Star />

但是这样做的话,以前的写法无法兼容

不会的,只要不用 <Icon /> 就不全量打包进来。

有些场景不能按需打包, 比如设置menu的图标, 如果可以后台配置, 这样前端是无法预知会设置成什么图标的,
异步加载比较适合, 把@ant-design/icons打成一个chunk就好

实际上内置使用了 <Icon /> 的组件例如 <DatePicker />, <Select /> 等,用到也会全量引入。

如果可以后台配置, 这样前端是无法预知会设置成什么图标的,异步加载比较适合

我们做的后台系统的menu就是配置的,图标异步加载真的很需要,全量打包实在太大了。

感觉异步比较好。
想按需打包估计得写个像 babel-plugin-importbabel 插件了。

analyzer

实际上内置使用了 <Icon /> 的组件例如 <DatePicker />, <Select /> 等,用到也会全量引入。

内部的写法都改掉

项目中有type是个变量,是只能引入全量了吗?
<Icon type={icon} />
这种有没有可以部分引入的?

另外 @ant-design/icons 内应该直接构建好 dist 包来用,直接依赖浅编译的源码并无必要。

+1 ,确实包大了一倍

💢 脑壳痛。。。。大爷的。。。

最骚的是带了很多 SourceMappingUrl

搞得我都退到 3.8.2版本了

https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo (umi project)

Here is a solution that use resolve.alias in webpack to reduce the bundle size.
We plan to design new APIs that allow import the icons in need in the furture.
Note that you should also import the icons used in antd component, such as loading, close-circle and so on.


https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo (umi 项目)
这里有一个临时的解决方案:配置webpack 的 resolve.alias 字段。
未来应该会想办法设计新的图标API来方便按需加载图标的使用。
注意按需的图标中也要包括 antd其他组件使用的图标,例如 loading, close-circle 等等。

@HeskeyBaozi 首先你的感谢辛勤付出!我现在时间是9:29,看到你提交的时间是6 hours ago,兄弟真的够拼!点赞:thumbsup::thumbsup::thumbsup:

我的理解是,单独列一份项目要用的icon,包括antd要用到的icon

@ChiaJune antd 组件中完整用到的图标列表,若有遗漏我可以补充
https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo/blob/master/src/icons.js#L10-L100

可以参考一下fontawsome的做法

A

import { library } from "@fortawesome/fontawesome-svg-core";
import faCalendar from "@fortawesome/free-solid-svg-icons/faCalendar";

library.add(faCalendar); // Load icon once

...

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
<FontAwesomeIcon icon="calendar" />

B

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import faCalendar from "@fortawesome/free-solid-svg-icons/faCalendar";

<FontAwesomeIcon icon={faCalendar} /> // Import directly or any svg

保留旧用法并在控制台中添加警告和迁移消息。

import { Icon } from 'antd';
<Icon type="star" />

提供者新的API,例如:

import Star from 'antd/icons/Star';
import Setting as SettingIcon from 'antd/icons/Setting';

<Star />
<SettingIcon />

还有树状交换方式:

import { Icon: { Star, Setting } } from 'antd';

<Star />
<SettingIcon />

@HeskeyBaozi @yesmeck

https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo (umi project)

Here is a solution that use resolve.alias in webpack to reduce the bundle size.
We plan to design new APIs that allow import the icons in need in the furture.
Note that you should also import the icons used in antd component, such as loading, close-circle and so on.

https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo (umi 项目)
这里有一个临时的解决方案:配置webpack 的 resolve.alias 字段。
未来应该会想办法设计新的图标API来方便按需加载图标的使用。
注意按需的图标中也要包括 antd其他组件使用的图标,例如 loading, close-circle 等等。

@HeskeyBaozi Great solution!! (until antd cleans this up and allows singular importing of icons) I have been making some attempts at using resolve.alias to fix this issue, but this hit the nail on the head. Thank you!

请注意这一点,因为我们也在使用此版本。

cc @jameswhf @xcqwan

我也是。 单独导入并不能涵盖所有使用情况,因此有必要修复树状抖动。 请在这里检查

@serayuzgur
我使用webpack.alias,它对我有用。 也许可以帮助您:)
image
我的仓库的antd-icon-tree-shaking分支(Webpack4 + Babel 7.0)

如果我所拥有的只是捆绑中的Button ,这也会引起问题(可能是因为它支持图标)。 如果我正在使用的话,减小包大小的任何解决方法都是Button

image

(在屏幕截图中-我只是有一个Button组件,但图标主要是使该包膨胀了)

对我一直有效的临时解决方案,直到解决为止(antd> = 3.9)

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

我认为,如果我们可以通过传递一些JSX来设置图标,那么我可以简单地只导入所需的图标并将其传递给按钮,这将是一个更好的api。 使用第三方图标(或任何svg)也将变得很简单。

<Button icon={<Icon type="search" />}>Search</Button>

只是我个人的喜好:)

对于通过react-app-rewired使用create-react-app的人们。

config-overrides.js

const path = require('path');

/* config-overrides.js */
module.exports = function override (config, env) {
  let alias = (config.resolve.alias || {});
  alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, "./src/icons.js");

  config.resolve.alias = alias;

  return config;
}

icons.js要点

对于通过react-app-rewired使用create-react-app的人们。

config-overrides.js

const path = require('path');

/* config-overrides.js */
module.exports = function override (config, env) {
  let alias = (config.resolve.alias || {});
  alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, "./src/icons.js");

  config.resolve.alias = alias;

  return config;
}

icons.js要点

这样做会消除twoToneColor的兼容性。
<Icon type="check-circle" theme="twoTone" twoToneColor="#52c41a" />
<Icon type="close-circle" theme="twoTone" twoToneColor="#f73131" />
结果是:
image

你好
造成此问题的原因是能够使用<Icon type="check-circle"类的图标。 此api需要包含每个图标,以便它可以提供您提供的任何类型。

这也使我们能够在运行时确定图标,这对我来说很有价值。 因此,根据我的说法,API应该保持不变,但Icon组件应支持按需按给定类型加载图标。

也许使用动态导入(取决于#12235-升级到Webpack 4)或通过Webpack 3库(例如react-loadable)

根据此评论,进行进一步的临时解决方案:

$ yarn add purched-antd-icons
// webpack.config.js
module.exports = {
  // other configs
  resolve:{
    // other configs
    alias:{
      "@ant-design/icons":"purched-antd-icons"
    }
  }
}

purched-antd-icons软件包会删除antd的官方组件未使用的所有图标。 就我而言, Icomoon是项目图标系统提供者。

这是弹出的create-react-app捆绑分析比较。

webpack输出
output

捆绑分析
comparing

在官方给出异步加载的方案前可以将@ant-design/icons/lib/dist.js 这个文件导入dll文件做长期缓存

before:

image

after:

image

@tobiaslins的解决方法对我不起作用,它说Module not found: Error: Can't resolve '@ant-design/icons/lib/dist' in '/Users/fede/Projects/despe/deliveries/node_modules/antd/es/icon'谁能指出我该如何解决? 谢谢

@marcosfede我和你有同样的问题。 别名无法正常工作。

检查您是否在path.resolve(__dirname, "./src/icons.js")设置了__dirname path.resolve(__dirname, "./src/icons.js")

如果您正在通过react-app-rewired替代方案使用create-react-app,则可以执行以下操作:

3.9升级使我们的捆绑包增加了700kb(23%)。 虽然我们喜欢新的实现,但增加的捆绑包大小是一个很大的惊喜。 由于不包括“ iconfont”,所以抵消了增加。 我们将实施@Obooman解决方案,该解决方案仍会看到总体足迹增加,但是不足以保证将其冻结在3.8.4。

purched-antd-icons程序包的实现使我们的项目缺少许多图标。

@michaelpeterlee purched-antd-icons只提供官方组件需要的图标,我们使用它是因为我们没有在antd中使用其他图标。 要进行更多自定义,您将必须手动管理图标或选择字体图标生成器(如icomooniconfont)作为图标系统提供者。

@marcosfede我和你有同样的问题。 别名无法正常工作。

检查您是否在path.resolve(__dirname, "./src/icons.js")设置了__dirname path.resolve(__dirname, "./src/icons.js")

如果您正在通过react-app-rewired替代方案使用create-react-app,则可以执行以下操作:

这很有用,谢谢。 我已经弹出了项目,所以我有__dirname指向webpack文件所在的config文件夹而不是根文件夹

也许AntDesign团队应该考虑回到以前的方法(在3.9之前)。 是更好的方法,明智的方法。

@marcosfede我和你有同样的问题。 别名无法正常工作。
检查您是否在path.resolve(__dirname, "./src/icons.js")设置了__dirname path.resolve(__dirname, "./src/icons.js")
如果您正在通过react-app-rewired替代方案使用create-react-app,则可以执行以下操作:

这很有用,谢谢。 我已经弹出了项目,所以我有__dirname指向webpack文件所在的config文件夹而不是根文件夹

对我有用,谢谢!

这是我们将在下一发行版中进行的更改,以解决分发包大小的问题。

为每个单个图标创建一个单独的组件

import StarFilled from 'antd/icons/StarFilled';

<StarFilled />

弃用引用图标作为字符串

当您在以下组件中将图标作为字符串引用时,将显示不赞成使用的警告:

<Icon type="star" />
<Alert iconType="success" />
<Avatar icon="star" /> 
<Button icon="star" /> 
Modal.confirm({ iconType: 'star' })

为了兼容性,当您将图标引用为字符串时,我们将按需加载SVG精灵。

您应该将ReactNode显式传递给以下道具,而不是将图标作为字符串引用:

import StarFilled from 'antd/icons/StarFilled';

<Avatar icon={<StarFilled />} /> 

@yesmeck一个很好的解决方案,它引入了树抖动功能,同时没有addIcon方法!

一个问题。 如果我们在这些图标上具有CSS样式并且需要动态更改图标的类型怎么办? 我们是否必须将样式传递给所有替换图标?

@michaelpeterlee rc-calendar不依赖antd@ant-design/icons ,因此不应“加载整个图标库”。 您可以在https://github.com/react-component/calendar/issues中创建带有复制演示的问题。

我的错。 我已经删除了不相关的评论。 必须是引入图标的DatePicker组件:
image

我的意思是,我没有在项目中的任何地方导入antd图标,但是某些antd组件正在从antd导入Icon antd 。 如果这些组件只能导入所需图标而不是整个图标库,那将是很好的。

这是我们将在下一发行版中进行的更改,以解决分发包大小的问题。

@yesmeck

您是说3.11.x吗? 它似乎未包含在3.10.4

@johnernaut #12888

暂时退回到v3.8.4,3.9.0+的版本打包后体积太大,上面大神们说的版本只是临时解决方案,期待下个版本能异步加载icon

感谢@yesmeck ,我期待下一个版本。

我还想提到我已经为create-react-app v2和craco发布了一个Ant Design插件。 这是GitHub上的craco-antd插件

我刚刚在README中从Ant Design Icons部分添加了PR) 。感谢@sunel (及其他)的技巧。 我提供了一个指向您有关设置别名的评论的链接。


module.exports = {
  resolve: {
    alias: {
      "@ant-design/icons-angular/icons": "/path/to/node_modules/@ant-design/icons-angular/esm2015/icons/ant-design-icons-angular-icons.js"
    }
  }
}

我起草了一个展示此问题的复制存储库。 该webpack配置是从此处的原始ng-zorro-antd集成示例中修改而来的,似乎DllPlugin使扁平化ES模块中的树状摇晃没有用。

如果没有DllPlugin它将按预期工作。

以下是有关webpack不会在flatten es模块上摇树的一些历史背景。 我相信他们所引用的内容在$$$ DllPlugin一些极端情况下在最新版本中已得到修复。

有趣的是直到5月Webpack才支持DllPlugin上的entryOnly: true但没有运气。 我将草拟一个更孤立的示例,并向webpack提出一个问题。

编辑:添加了复制存储库和历史问题。

故事的结尾:正是在这里使复制库变得虚假。 没有entryOnly: true支持的webpack 3.5.6太旧了。 这就是为什么fesm5模块不会摇晃的原因。

对于那些想将ng-zorro-antd捆绑到DLL供应商的用户

  • 如果您的webpack > = 4.9.0 ,请将entryOnly: trueDllPlugin配置中。
  • 否则,将此设置添加到您的webpack配置中
module.exports = {
  resolve: {
    alias: {
      "@ant-design/icons-angular/icons": "/path/to/node_modules/@ant-design/icons-angular/esm2015/icons/ant-design-icons-angular-icons.js"
    }
  }
}

@issuehuntfest已为此问题资助了200美元。 在IssueHunt上查看

字体文件能不能别参与打包,自己本地引入?太大了

官方有计划优化这个问题吗?能否提供本地svg方案,类似3.8以前版本?

期待改进

有官方解决方案吗?

@fuhaiwei在下一个版本之前,通过直接导出图标来检查此注释是否可解决, https: //github.com/ant-design/ant-design/issues/12011#issuecomment -423173228

目前我使用 webpack.resolve.aliasantd/es/icon 替换成一个自定义组件。
该组件会将 <Icon />props.typeprops.theme 发送给指定的 API。
这样一来在页面测试时可以记录下所有使用的 Icon 数据。
然后根据数据和 https://github.com/ant-design/ant-design/issues/12011#issuecomment-423173228 自动生成icons.js
希望能找到更好的解决方法。


Currently I am using webpack.resolve.alias to replace antd/es/icon with a custom component.
That component will send props.type and props.theme of <Icon /> to the specified API.
This allows you to record all of the Icon data used during the page test.
Then generate icons.js automatically, based on the data and https://github.com/ant-design/ant-design/issues/12011#issuecomment-423173228.
Hope to find a better solution.

3个月过去了,官方找到按需加载的方法了吗

image

感觉最好的还是从引入方式入手,像material那样所有组件都单独引用多好。。现在只有那些可能用到内置Icon的组件,都把图标全部打包出来了。。

没有用到 Icon 组件也会加载 @ant-desigin/icons 这个包

没有用到 Icon 组件也会加载 @ant-desigin/icons 这个包

datepicker此类的也用到了,看下代码里有没有此类。menu也会用到吧

500多KB 实在太大了

期待ing,本来换到最新版了,一看打包出来那么大,吓得我又回退回去了

不想用SVG格式的,可以灵活配置吗?配置使用还是不使用svg

可以提供一个仅引用单个图标的方式,并且 antd 所有内部组件全部更新为使用这种方式:

import Search from 'antd/icons/Search";

<Search />

对于现有项目的兼容,依旧保留 import { Icon } from 'antd';,但是只要使用 import { Icon } from 'antd'; 就是全量图标导入。

同意楼上

mark 等待完美解决的方法

500k的icons , 有解决方案了?

有人可以用英语更新我吗? 500kb是我捆绑包的四分之一。 我正在使用webpack并像这样导入图标:

import Icon from 'antd/lib/icon';
<Icon type="logout" />

我尝试了各种导入方法,甚至一起删除了图标导入,但是无论如何,似乎500kb都保留了下来。 我使用的是webpack,并且能够使用包裹的实验性范围提升功能正确地摇晃图标,但由于它在其他20个地方中断了我的应用程序,因此我无法使用它。

人们如何处理此问题? 是这里的每个人都只是额外交付了500kb的项目,还是我忽略了一些明显的解决方法?

这样导入是否可以与标准的webpack构建一起使用?

import Star from 'antd/icons/star';
如果有人可以更新我,我将非常感激。

@ApolloGun此线程中已多次引用变通办法,所有内容均在此注释中: https :

它的工作方式是告诉Webpack从其他位置解析图标,特别是在一个新文件中,您可以在其中完全导出要使用的图标。 完成这些操作后,图标将正常运行,组件中的其他任何东西都无需更改。

我没有使用任何图标,但仍然得到了那个大文件。 也许antd中的组件在内部使用它。 我该如何查看组件使用的图标。 似乎是用自定义图标替换Select,Dropdown等东西的Antd图标的好方法。

我没有使用任何图标,但仍然得到了那个大文件。 也许antd中的组件在内部使用它。 我该如何查看组件使用的图标。 似乎是用自定义图标替换Select,Dropdown等东西的Antd图标的好方法。

@HeskeyBaozi使用webpack别名创建了antd组件中使用的图标的列表:
https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo/blob/master/src/icons.js#L10 -L100
请阅读整个问题讨论以了解此方法。

@ApolloGun当前没有官方解决方案。
拉取请求:#12888仍在进行中。

@ yesmeck@ afc163有什么计划要尽快关闭?

@HeskeyBaozi @afc163 ,请问要如何使用你们新写的这个??

@HeskeyBaozi我想问一下为什么你们不从事这个工作吗? 已经超过五个月了。 你们认为这不是优先事项吗?

@HeskeyBaozi我想问一下为什么你们不从事这个工作吗? 已经超过五个月了。 你们认为这不是优先事项吗?

同意,这真的很烦=(

在检查了antd的代码之后,我看到诸如Button导入了Icon ,而该组件又导入了(根据生成的代码)

// import everything here
import * as allIcons from '@ant-design/icons/lib/dist';

//...

// use everything here :(
ReactIcon.add.apply(
  ReactIcon,
  _toConsumableArray(
    Object.keys(allIcons).map(function(key) {
      return allIcons[key];
    })
  )
);

这会导致树状握手失败,从而导入所有图标。 请考虑将导入指向@ant-design/icons/lib/index.es.js ,直到需要时才对所有图标执行操作。 另外,请查看此行的历史记录: https :

这直接导致整个项目不能用 好吗

@poorel

<Icon /> 默认全量引入了图标库。因为不知道你会引入何种图标进行运行时引入。之前图标托管在 iconfont.cn 所以打包无感知。

这需要深入讨论
临时方案见 #12011 (comment)

这个方案还是可以用的,我测试过了,但是你要整理出来你项目中有哪些icon,就这个略麻烦些

但是你要整理出来你项目中有哪些icon...

之前试着看了, 发现 icon 的引用很多是 antd 自带组件做的, 而且数量也不小. 自己在业务直接引用的虽然很小, 但是考虑组件可能引用到的, 数量也不好统计了.

@chenyong 额,那蛋疼了。。。

@aryzing您的方法听起来很有吸引力。 是否会比#12888花费更少的精力? 该PR涉及太多重大更改,这可能是几个月后仍未完成的部分原因。

@zachguo我浏览了#12888,但我真的不明白发生了什么。 经过一番思考后,我不确定我们是否可以成功地摇晃图标,因为某些组件用来渲染图标的动态api与用于摇晃ES导入的静态特性发生了冲突。

在某些antd组件中使用的图标会基于prop动态呈现(即在运行时确定)。 例如,看一下Button的api:

<Button icon="search">Search</Button>

为了使此组件正确呈现,Button组件(或使用的基础Icon组件)必须有权(在运行时)所有图标,并且不允许摇晃树。

解决方案是拥有一个API,例如

import { 
  SearchIcon // not sure if this actually exists
} from '@antd/some-icons-package';

<Button icon={SearchIcon}>Search</Button> {/* option 1 - component */}
<Button icon={() => <SearchIcon />}>Search</Button> {/*option 2 - render prop */}

在这种情况下,您只需要导入所需的内容,就可以摇晃树,并丢弃示例@antd/some-icons-package所有未使用的导出。

这个问题已经超过半年了,仍然没有官方的解决方案。目前我使用的解决方案是采用 import() 进行异步加载。
This problem has been more than half a year, and there is still no formal solution. The solution I'm currently using is to use import() for asynchronous loading.

使用到 React 官方文档中的推荐的 Loadable Components
Use the Loadable Components recommended in the official React documentation.

import React from 'react';
import ReactDOM from 'react-dom';
import { Icon } from 'antd';

ReactDOM.render(
  <Icon type="github" />,
  document.getElementById('root')
);

image

image

  • 第一步,安装依赖项:@loadable/component@babel/plugin-syntax-dynamic-import
    The first step is to install dependencies: @loadable/component and @babel/plugin-syntax-dynamic-import.
  • 第二步,在项目根目录创建一个文件夹 icons,并使用脚本将 @ant-design/icons 中的所有图标进行导出:
    The second step is to create a folder icons in the project root and export all the icons in @ant-design/icon using a script:

    #!/usr/bin/env node
    const fs = require('fs');
    const path = require('path');
    const util = require('util');
    const icons = require('@ant-design/icons');
    
    const fsMkdir = util.promisify(fs.mkdir);
    const fsWriteFile = util.promisify(fs.writeFile);
    
    // https://github.com/ant-design/ant-design-icons/blob/master/packages/icons-react/src/utils.ts#L94-L108
    const mapping = {
    fill: 'fill',
    outline: 'o',
    twotone: 'twotone',
    };
    const saveFlag = { encoding: 'utf8', mode: 0o644, flag: 'w' };
    
    (async () => {
    const dir = path.join(__dirname, 'icons');
    await fsMkdir(dir, 0o755);
    const processes = Object.values(icons).map(value => {
      if (value && value.name && value.theme) {
        // https://github.com/ant-design/ant-design-icons/blob/master/packages/icons-react/src/components/Icon.tsx#L38-L42
        const file = path.join(dir, `${value.name}-${mapping[value.theme]}.js`);
        const data = `export default ${JSON.stringify(value)}`;
        return fsWriteFile(file, data, saveFlag);
      }
    });
    await Promise.all(processes);
    })();
    

    直接在项目下使用 node 执行此脚本即可将 @ant-design/icons 中导出的所有图标存储到 icons 目录中。
    Execute this script directly under the project using the node to store all the icons exported from @ ant-design/icons in the icons folder.

  • 第三步,复制 Antd 代码仓库中的 components/icon/index.tsx 到项目根目录,命名为 Icon.jsxIcon.js,然后将代码中的 TypeScript 类型定义删除以得到纯 JavaScript 代码。(如果你的项目使用 TypeScript,也可以直接命名为 Icon.tsxIcon.ts,也就不用再删类型定义了)
    In the third step, copy components/icon/index.tsx in the Antd code repository to the project root, and named to Icon.jsx or Icon.js, then remove the TypeScript type definition in the code to get pure JavaScript code. (If your project uses TypeScript, you can also name it directly as Icon.tsx or Icon.ts, so you don't have to delete the type definition)
    然后修改这个代码文件,使用 import() 配合 @loadable/component 来按需加载图标文件。
    Then modify the code file and use import() with @loadable/component to load the icon file as needed.

    diff -- a/Icon.tsx b/Icon.jsx
    --- a/Icon.tsx
    +++ b/Icon.jsx
    @@ -1,70 +1,29 @@
    import * as React from 'react';
    import classNames from 'classnames';
    -import * as allIcons from '@ant-design/icons/lib/dist';
    +import loadable from '@loadable/component';
    import ReactIcon from '@ant-design/icons-react';
    -import createFromIconfontCN from './IconFont';
    +import createFromIconfontCN from 'antd/es/icon/IconFont';
    import {
    svgBaseProps,
    withThemeSuffix,
    removeTypeTheme,
    getThemeFromTypeName,
    alias,
    -} from './utils';
    +} from 'antd/es/icon/utils';
    -import warning from '../_util/warning';
    +import warning from 'antd/es/_util/warning';
    -import LocaleReceiver from '../locale-provider/LocaleReceiver';
    +import LocaleReceiver from 'antd/es/locale-provider/LocaleReceiver';
    -import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor';
    +import { getTwoToneColor, setTwoToneColor } from 'antd/es/icon/twoTonePrimaryColor';
    +
    +const AllIcons = loadable.lib(props => import(
    +  /* webpackChunkName: "icons/icon-" */
    +  `./icons/${props.type}.js`
    +));
    
    // Initial setting
    -ReactIcon.add(...Object.keys(allIcons).map(key => (allIcons as any)[key]));
    setTwoToneColor('#1890ff');
    -let defaultTheme: ThemeType = 'outlined';
    +let defaultTheme = 'outlined';
    -let dangerousTheme: ThemeType | undefined = undefined;
    +let dangerousTheme = undefined;
    -
    -export interface TransferLocale {
    -  icon: string;
    -}
    -
    -export interface CustomIconComponentProps {
    -  width: string | number;
    -  height: string | number;
    -  fill: string;
    -  viewBox?: string;
    -  className?: string;
    -  style?: React.CSSProperties;
    -  spin?: boolean;
    -  rotate?: number;
    -  ['aria-hidden']?: string;
    -}
    -
    -export type ThemeType = 'filled' | 'outlined' | 'twoTone';
    -
    -export interface IconProps {
    -  tabIndex?: number;
    -  type?: string;
    -  className?: string;
    -  theme?: ThemeType;
    -  title?: string;
    -  onKeyUp?: React.KeyboardEventHandler<HTMLElement>;
    -  onClick?: React.MouseEventHandler<HTMLElement>;
    -  component?: React.ComponentType<CustomIconComponentProps>;
    -  twoToneColor?: string;
    -  viewBox?: string;
    -  spin?: boolean;
    -  rotate?: number;
    -  style?: React.CSSProperties;
    -  prefixCls?: string;
    -  role?: string;
    -}
    -
    -export interface IconComponent<P> extends React.SFC<P> {
    -  createFromIconfontCN: typeof createFromIconfontCN;
    -  getTwoToneColor: typeof getTwoToneColor;
    -  setTwoToneColor: typeof setTwoToneColor;
    -  unstable_ChangeThemeOfIconsDangerously?: typeof unstable_ChangeThemeOfIconsDangerously;
    -  unstable_ChangeDefaultThemeOfIcons?: typeof unstable_ChangeDefaultThemeOfIcons;
    -}
    -
    -const Icon: IconComponent<IconProps> = props => {
    +const Icon = props => {
    const {
      // affect outter <i>...</i>
      className,
    @@ -107,7 +66,7 @@
      [`anticon-spin`]: !!spin || type === 'loading',
    });
    
    -  let innerNode: React.ReactNode;
    +  let innerNode;
    
    const svgStyle = rotate
      ? {
    @@ -116,7 +75,7 @@
        }
      : undefined;
    
    -  const innerSvgProps: CustomIconComponentProps = {
    +  const innerSvgProps = {
      ...svgBaseProps,
      className: svgClassString,
      style: svgStyle,
    @@ -165,12 +124,19 @@
        dangerousTheme || theme || defaultTheme,
      );
      innerNode = (
    -      <ReactIcon
    -        className={svgClassString}
    -        type={computedType}
    -        primaryColor={twoToneColor}
    -        style={svgStyle}
    -      />
    +      <AllIcons type={computedType}>
    +        {({ default: loadedIcon }) => {
    +          ReactIcon.add(loadedIcon);
    +          return (
    +            <ReactIcon
    +              className={svgClassString}
    +              type={computedType}
    +              primaryColor={twoToneColor}
    +              style={svgStyle}
    +            />
    +          );
    +        }}
    +      </AllIcons>
      );
    }
    
    @@ -181,7 +147,7 @@
    
    return (
      <LocaleReceiver componentName="Icon">
    -      {(locale: TransferLocale) => (
    +      {locale => (
          <i
            aria-label={type && `${locale.icon}: ${type}`}
            {...restProps}
    @@ -196,7 +162,7 @@
    );
    };
    
    -function unstable_ChangeThemeOfIconsDangerously(theme?: ThemeType) {
    +function unstable_ChangeThemeOfIconsDangerously(theme) {
    warning(
      false,
      'Icon',
    @@ -206,7 +172,7 @@
    dangerousTheme = theme;
    }
    
    -function unstable_ChangeDefaultThemeOfIcons(theme: ThemeType) {
    +function unstable_ChangeDefaultThemeOfIcons(theme) {
    warning(
      false,
      'Icon',
    
  • 最后一步,配置 Webpack:
    The final step is to configure Webpack:
    ```diff
    diff -- a/webpack.js b/webpack.js
    --- a/webpack.js
    +++ b/webpack.js
    @@ -1,4 +1,5 @@
    const path = require('path');
    +const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const TerserPlugin = require('terser-webpack-plugin');

    @@ -33,12 +34,16 @@
    plugins: [
    new HtmlWebpackPlugin({
    title: 'Awesome Page',
    template: path.join(__dirname, 'public/index.html'),
    meta: {
    viewport: 'width=device-width, initial-scale=1',
    },
    hash: true,
    }),

    • new webpack.NormalModuleReplacementPlugin(
    • /node_modules\/antd\/es\/icon\/index.js/,
    • path.resolve(__dirname, 'Icon.jsx')
    • ),
      ],
      resolve: {
      modules: ['node_modules'],
      @@ -56,13 +61,14 @@
      use: [{
      loader: 'babel-loader',
      options: {
      presets: [
      ['@babel/preset-env', { targets: '> 2.486%, not dead' }],
      '@babel/preset-react',
      ],
      plugins: [
    • ['@babel/plugin-syntax-dynamic-import'],
      ['@babel/plugin-proposal-class-properties'],
      ['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
      ],
      },
      }]

      ```

这个解决方案的优点是,你可以保留所有图标,在可配置后台管理系统中也可以任意修改图标而不用担心缺少图标;并且图标是按需加载的,只有开始渲染特定页面的图标时才会加载对应的图标文件。必须加载的只有打包后的 index 中有 50K 左右的图标列表数据(在 Icon.jsx 中的 webpack 魔术注释中指定更短的名字可以缩小这个体积)。
The advantage of this solution is that you can keep all the icons, you can also modify icons in the configurable background management system without worrying about the missing icons, and the icons are loaded on demand, only the icons needed to be rendered will be loaded when you start rendering a specific page. The packaged index file which must be loaded has only about 50K of icon list data (specifying a shorter name in the Webpack magic comment in Icon.jsx can reduce this size).

这个方案的缺点是,每一个图标都包含了除图标内容以外的额外的 Webpack 模块信息,因此可以看到 icons 文件夹的大小比之前整体打包的单文件大小要大很多,加上 index 中的 50K 图标列表数据,实际打包下来的尺寸接近 3M。但是由于实际上能使用到的图标来来回回也就那么几个、十几个,所以用户浏览器下载的数据量不会太大,并且由于是异步加载,只要单页面同时显示的图标数不多,对加载速度影响也就不大。
The downside of this solution is that each icon contains Webpack module information in addition to the icon content, so you can see that the size of the icons folder is much larger than the size of the single file packaged before, and 50K of icon list data in the index file, the actual packaged size is close to 3M. However, because the icons that can actually be used are only a few or a dozen, the amount of data downloaded by the user's browser is not too large, and since it is asynchronously loaded, as long as the number of icons displayed on a single page is not more, the impact on the loading speed is not large.

@jinliming2 很酷炫的修改,才发现webpack的import其实可以传变量的

Fully dynamic statements, such as import(foo), will fail because webpack requires at least some file location information. This is because foo could potentially be any path to any file in your system or project. The import() must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files.

居然只要有一个目录的前缀就可以了,之前以为是不行的。
话说回来,antd用户也不是只用webpack,这就有点尴尬了。

@aryzing似乎您提议的API的选项1实际上是#12888试图实现的。 涉及很多重大更改,因此可能我们仍然需要等待Ant Design团队完成它。

可以考虑使用xhr异步加载svg?
弓箭手

由于ant deisgn本身组件会使用到较多的图标,所以是否考虑将图标文件改为异步加载方案,这样就不用占用主文件体积,可以参考下这个:

Since ant deisgn itself will use more icons, so consider changing the icon file to an asynchronous loading scheme, so that you don't need to occupy the main file size, you can refer to this:

webpack-ant-icon-loader

@rororofff已为该问题资助2.00美元。


对于那些对对话时间长短感到害怕并且只想使用create-react-app和ant-design的人,我在这里https://github.com/AustinGreen/cra-antd-starter创建了一个样板项目

其中包括针对图标捆绑包大小问题的修复,以及不弹出的自定义Webpack配置。 感谢@ndbroadbent@patricklafrance和整个蚂蚁设计团队的辛勤工作。

对于那些对对话时间长短感到害怕并且只想使用create-react-app和ant-design的人,我在这里https://github.com/AustinGreen/cra-antd-starter创建了一个样板项目

其中包括针对图标捆绑包大小问题的修复,以及不弹出的自定义Webpack配置。 感谢@ndbroadbent@patricklafrance和整个蚂蚁设计团队的辛勤工作。

我如何在Nextjs应用程序中使用它?

@AustinGreen我尝试了您的示例。

image

对于带有侧边栏和一个按钮的应用程序,其大小约为100kB,压缩后仍然太多了。

@anjmao,如果有办法进一步减小捆绑包的大小,请告诉我,我将其添加进来。如果您要构建的企业Web应用程序,〜100kB压缩为一个前端框架,〜5个组件(来自一个全面的组件库),图标和其他实用程序是非常标准的。

@anjmao,如果有办法进一步减小捆绑包的大小,请告诉我,我将其添加进来。如果您要构建的企业Web应用程序,〜100kB压缩为一个前端框架,〜5个组件(来自一个全面的组件库),图标和其他实用程序是非常标准的。

https://github.com/ant-design/ant-design/issues/12011#issuecomment -420038579。 这是一个很好的解决方案

@ Oscar-ren该项目已经在使用图标别名(这就是为什么捆绑包大小仅为〜100kB而不是〜400kB的原因)

@tobiaslins自从您上次发表评论以来,是否更改了解决方法?
当我在Nuxt项目中使用它时,客户端和服务器端渲染将不同步:
The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

仅供参考,Vue使用Webpack别名来减少捆绑包大小的版本:
https://github.com/atjason/ant-design-vue-demo

参考:
https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo

包裹大小Hello World

image

由于ant deisgn本身组件会使用到较多的图标,所以是否考虑将图标文件改为异步加载方案,这样就不用占用主文件体积,可以参考下这个:

Since ant deisgn itself will use more icons, so consider changing the icon file to an asynchronous loading scheme, so that you don't need to occupy the main file size, you can refer to this:

webpack-ant-icon-loader

For posterity, this only works for React.

您好, @ jinliming2解决方案什么时候发布?
webpack-ant-icon-loader对我不起作用。

您好,能否提供有关使用的信息
webpack-ant-icon-loader和你在一起吗?
让我看看是否可以帮助您解决。

哈@ @ beven91!

我之前已经做过一些测试,但是没有用,所以我无法
弄清楚为什么。 但是,您的问题使我无法在
专门的项目我确实为您创建了一个示例测试以向您展示
它确实起作用了! 我不断从结果包中节省1.21 Mb
演示项目和正在进行的项目都很棒
商业上。

我在这里发布示例项目,以防其他人拥有相同的示例项目
问题:
https://github.com/vladimirmoushkov/ant-icons-webpack-loade-test/#readme

没有webpack-ant-icon-loader,我得到以下结果:
bundle.development.js 4.59 MiB应用[已发布]应用

使用webpack-ant-icon-loader我得到:
../../index.html 555字节[发射]
0.bundle.development.js 1.21 MiB 0 [发出]
bundle.development.js 3.41 MiB应用程序[发射]应用程序

几个注意事项:

  • 认为如果删除产生的0.bundle.development.js会更好
    人工制品。
  • 图标从最终产品中消失,即它们在页面上不可见。 我看到了您的umirc.js配置,但是我正在使用react-router。 如何使它们重新出现?

在2019年4月5日星期五,2:38 PM beven91 [email protected]写道:

您好,能否提供有关使用的信息
webpack-ant-icon-loader和你在一起吗?
让我看看是否可以帮助您解决。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/ant-design/ant-design/issues/12011#issuecomment-480244343
或使线程静音
https://github.com/notifications/unsubscribe-auth/AUPfoCCVrb5j4s8Qleju8LvdPsxC02FFks5vdzW7gaJpZM4WW7EA

https://github.com/AustinGreen/cra-antd-starter

@AustinGreen只是好奇,怎么会是你的解决方案不同的比蚂蚁记录react-app-rewiredbabel-plugin-import这里记录方法- https://ant.design/docs/react/use-with-create-react -app

的GitHub
使用create react app和ant设计的样板-AustinGreen / cra-antd-starter
企业级UI设计语言和基于React的实现,带有一组高质量的React组件,这是企业最好的React UI库之一

@annjawn作为创建反应的应用程序内2.0,反应-APP-重新布线不再维持,所以我的项目用途craco它的建立是为了取代反应过来-APP-重新接线CRA 2.0 + craco-antd。

@ Beven91您能帮我解决我之前的评论吗?

  • 图标从最终产品中消失,即它们在页面上不可见。 我看到了您的umirc.js配置,但是我正在使用react-router。 如何使它们重新出现?

我的意思是说它很好,整个捆绑包中的图标之间存在分隔,但是使用过的图标仍然保留在分开的捆绑包中,因此使用它们意味着将其作为单独的捆绑包包含在内,这使得分隔毫无意义。

@annjawn作为创建反应的应用程序内2.0,反应-APP-重新布线不再维持,所以我的项目用途craco它的建立是为了取代反应过来-APP-重新接线CRA 2.0 + craco-antd。

@AustinGreen是有意义的,但是使用CRACO基本上是相同的。 顺便说一句,我也将使用react-loadable进行代码拆分,并且我认为您的方法+模块化导入+异步组件加载应大大减少捆绑包的大小。

@vladimirmoushkov
对不起,我会尽力解决的。

你好@vladimirmoushkov

您可以在此处查看详细信息。 ant-icons-webpack-loade-test#1

对我一直有效的临时解决方案,直到解决为止(antd> = 3.9)

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

这不适用于使用图标的ant组件。 例如,警报组件使用检查和关闭图标,但此解决方案不可见

@ Venugopal46,您也可以将这些图标(由蚂蚁组件使用)添加到icons.js中。
对我来说很好。

看起来我们已经接近解决方案了; 最后,我们可以构建一个在生成过程中自动生成icons.js的util。

您如何准确地知道哪些图标是通过ant自己的组件导入的,以便将它们放入icons.js

对我来说,上述技巧:

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

并使用以下generateIconsList.sh文件生成src/icons.js

grep -iR \<Icon\  ./src/ | cut -d: -f2 | sed -e s/.*\<Icon\ //g | sort | uniq | while read icon; do 
    theme='Outline';
    themelowercase="outline";
    if [[ $icon =~ ^.*twoTone.*$ ]]; then
        theme="TwoTone";
        themelowercase="twotone";
    fi
    if [[ $icon =~ ^.*fill.*$ ]]; then
        theme="Fill";
        themelowercase="fill";
    fi
    icon=$(echo $icon | sed -e 's/type\=\"//g'| sed -e 's/\".*//g' | sed -e 's/\-/ /g')
    icon=$(python -c "print('"$icon"'.title())")
    icon=$(echo $icon | sed -e 's/ //g')
    core_path="@ant-design/icons/lib/"$themelowercase"/"$icon$theme
    search_path="node_modules/"$core_path".js"
    if [ -e $search_path ]; then
        echo "export { default as "$icon$theme" } from \""$core_path"\";"
    fi
done | sort | uniq

通过从项目根目录运行generateIconsList.sh 2>/dev/null >src/icons.js -完成任务!
该脚本很丑陋,显然不能捕获内部图标引用或多行<Icon />引用。 就我而言,我需要手动添加几个Icon案例,但是脚本最终还是可以完成任务-在最终的捆绑包中减少了1.1 mb!

您如何准确地知道哪些图标是通过ant自己的组件导入的,以便将它们放入icons.js

我只是添加网页上缺少(但未显示)但应该在其中的图标。 这取决于您使用的antd组件数量,但是对我来说,添加大约需要10分钟。 (不过,我使用了大量的antd组件)

例如,如果缺少表上的排序器箭头:

  1. 检查蚂蚁表并找到<i aria-label="icon: caret-down" class="anticon anticon-caret-down ant-table-column-sorter-down off"> 。 您会看到此<i />标签为空。 您可以在此处看到该图标的名称为caret-down
  2. @ant-design/icons/lib文件夹中找到此图标,选择filledoutline文件夹(取决于所需的图标类型),然后将新的导入添加到icons.js如下所示:
export { default as CaretDownOutline } from '@ant-design/icons/lib/outline/CaretDownOutline';

这不是最好的方法,但是可以正常工作。 期待蚂蚁开发团队在将来的版本中修复此问题,以便我们避免此类卑鄙的黑手。

嗨!

关于这个主题有什么消息吗? 它是下一个蚂蚁释放的候选者吗?
我尝试了一些方法来解决此问题( webpack-ant-icon-loaderbabel-import-plugin ),但没有一个起作用。

谢谢!

真的需要一个解决方案,捆绑包太大!

@zlab @nuintun @anjmao 求助,请问一下https://zlab.github.io/report.html 这个页面是通过什么插件生成的呢,想分析一下自己的项目

找到了,是webpack-bundle-analyzer

只用到了 modal,却打包了500k 的 icon lib

都大半年了,没有进展吗?

放弃antd了 这么重要的问题居然没标注important...

现在按需加载必定会打包进icons的文件,500kb

我在Webpack中添加了别名,并在icon.ts中导出了图标,但是当我运行npm start ,出现了错误

ERROR in ./node_modules/antd/lib/icon/index.js
Module not found: Error: Can't resolve '@ant-design/icons/lib/dist' in 'xxx\node_modules\antd\lib\icon'

这是我的webpack解决配置

resolve: {
      modules: [path.resolve(__dirname, '../src'), 'node_modules'],
      alias: {
        '@ant-design/icons/lib/dist$': path.resolve(
          __dirname,
          '../src/utils/antdIcon.ts',
        ),
      },
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
      plugins: [
        new TsConfigPathsPlugin({
          tsconfig: path.resolve(__dirname, '../tsconfig.json'),
        }),
      ],
    },

1.项目中都没有用icon 图标,怎么有打包了,求大神解答?
image
2.用webpack externals = {'antd': 'antd'} 也不好使,打包分析中还是能看到antd?

1.项目中都没有用icon 图标,怎么有打包了,求大神解答?
2.用webpack externals = {'antd': 'antd'} 也不好使,打包分析中还是能看到antd?

@wiiler

  1. 参考这个,可能是用了引用 Icon 的组件

    https://github.com/ant-design/ant-design/issues/12011#issuecomment-418003883
    实际上内置使用了 <Icon /> 的组件例如 <DatePicker />, <Select /> 等,用到也会全量引入。

  2. 如果使用 externals 需要把 babel-plugin-import 插件关掉

我在Webpack中添加了别名,并在icon.ts中导出了图标,但是当我运行npm start ,出现了错误

ERROR in ./node_modules/antd/lib/icon/index.js
Module not found: Error: Can't resolve '@ant-design/icons/lib/dist' in 'xxx\node_modules\antd\lib\icon'

这是我的webpack解决配置

resolve: {
      modules: [path.resolve(__dirname, '../src'), 'node_modules'],
      alias: {
        '@ant-design/icons/lib/dist$': path.resolve(
          __dirname,
          '../src/utils/antdIcon.ts',
        ),
      },
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
      plugins: [
        new TsConfigPathsPlugin({
          tsconfig: path.resolve(__dirname, '../tsconfig.json'),
        }),
      ],
    },

我推荐这两种做法

@ As3ass1n
为什么“ ../src/utils/antdIcon.ts”具有“ ..”? webpack配置是否放置在单独的目录中?

1.项目中都没有用icon 图标,怎么有打包了,求大神解答?
2.用webpack externals = {'antd': 'antd'} 也不好使,打包分析中还是能看到antd?

@wiiler

  1. 参考这个,可能是用了引用 Icon 的组件
    > #12011 (comment)
    > 实际上内置使用了 <Icon /> 的组件例如 <DatePicker />, <Select /> 等,用到也会全量引入。
  2. 如果使用 externals 需要把 babel-plugin-import 插件关掉

明白了,感谢 @wangjianio

我在Webpack中添加了别名,并在icon.ts中导出了图标,但是当我运行npm start ,出现了错误

ERROR in ./node_modules/antd/lib/icon/index.js
Module not found: Error: Can't resolve '@ant-design/icons/lib/dist' in 'xxx\node_modules\antd\lib\icon'

这是我的webpack解决配置

resolve: {
      modules: [path.resolve(__dirname, '../src'), 'node_modules'],
      alias: {
        '@ant-design/icons/lib/dist$': path.resolve(
          __dirname,
          '../src/utils/antdIcon.ts',
        ),
      },
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
      plugins: [
        new TsConfigPathsPlugin({
          tsconfig: path.resolve(__dirname, '../tsconfig.json'),
        }),
      ],
    },

我推荐这两种做法

@ As3ass1n
为什么“ ../src/utils/antdIcon.ts”具有“ ..”? webpack配置是否放置在单独的目录中?

对不起,这是我的错。 我输入了错误的文件名,现在我使用别名解决了它。 谢谢

将来不会解决这个问题吗? 增加近40万

嗨,是否可以提供估计何时解决的至少大概时间?

image

捆绑包上的额外490kb使得Icon几乎不可用。 这是一个很大的问题,在您发布针对此问题的修复程序之前,我们是否可以做任何临时修复程序?

@smddzcy读了线程?

@ schester44用多种语言编写的线程……我本来要说字母,甚至是音节,但是我认为我必须讲到脚本……我敢说对于那些语言学通常限于语言的人来说,这是很难的仅限于从Etruscan派生的字母,以完全了解正在发生的事情。

嗨,大家好,我已经成功实现了非常简单的purched-antd-icons包实现,但这完全是手动的; 我估计需要花费3-4个小时的时间来检查DOM,以协调丢失的图标。 我们打算在我们的开发/发布周期的最后阶段实现这一点。 对于我们的打包/脱机优先应用程序,唯一的问题是接近非常适度的iOS WKWebview RAM限制。 对我们来说,如果iOS移动配置文件继续不显示伪像,我们将完全忽略这一点。 看到这里没有任何进展,我更喜欢将这个新的Icon API搁置起来,并将旧的API恢复回来。

@ afc163

您在2018年9月15日撰写的内容听起来是一个很好的解决方案(下面的Google翻译)。 您能否提供一个估算值?

保留旧用法并在控制台中添加警告和迁移消息。

import { Icon } from 'antd';
<Icon type="star" />

提供者新的API,例如:

import Star from 'antd/icons/Star';
import Setting as SettingIcon from 'antd/icons/Setting';

<Star />
<SettingIcon />

还有树状交换方式:

import { Icon: { Star, Setting } } from 'antd';

<Star />
<SettingIcon />

@HeskeyBaozi @yesmeck

根据V4路线图,此问题将在今年第四季度解决。

酷:笑脸

VàoTh 7,1 thg 6,2019vàolúc01:51 Zach Guo [email protected]
:ãviết:

根据V4路线图
https://github.com/ant-design/ant-design/issues/16911 ,这将是
定于今年第四季度。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/ant-design/ant-design/issues/12011?email_source=notifications&email_token=ADKDE4RXC63VER4GSUMG5Q3PYFXT7A5CNFSM4FS3WEAKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKCTDN5ment
或使线程静音
https://github.com/notifications/unsubscribe-auth/ADKDE4TGAYRMSJQB246RQ33PYFXT7ANCNFSM4FS3WEAA

ICYMI, Icon文档提到了这一点。 下面的副本。

“⚠️关于我们在3.9.0中导入的所有SVG图标带来的额外捆绑包大小,我们将提供新的API,以允许开发人员根据需要导入图标,您可以跟踪#12011以取得进一步的进展。
在此之前,您可以使用社区中的webpack插件对图标文件进行分块。”

最后一点很酷,代码拆分并异步加载图标,在我的情况下,代码拆分并且根本不使用图标。

官方是不是放弃了这个了,都多久了,还不解决

官方是不是放弃了这个了,都多久了,还不解决

@zhe-he

image

没有明确的解决方案!

这个官方真的不打算解决这个问题吗? 这么大不需要的打包,真的劝退啊

@DemoHu
image

@tibotiber感谢您到icon-loader的链接,图标块仍仍插入到index.html中? 关于如何从index.html中插入块中删除任何建议

@ jasan-s我猜这取决于您如何构建捆绑包以及在哪里使用图标。 例如,我在最新的create-react-app上,该应用程序为我配置代码拆分,并且确保在主捆绑包的组件树中的任何位置都不要import图标(我从不使用图标) 。

@tobiaslins的解决方法对我不起作用,它说Module not found: Error: Can't resolve '@ant-design/icons/lib/dist' in '/Users/fede/Projects/despe/deliveries/node_modules/antd/es/icon'谁能指出我该如何解决? 谢谢

@marcosfede我使用

./node_modules/antd/lib/icon/index.js
Cannot find module: '@ant-design/icons/lib/dist'. Make sure this package is installed.

You can install this package by running: yarn add @ant-design/icons/lib/dist.

@marcosfede哦! 我的错。 我知道了

我有个想法 💡 @afc163

我们可以使用 svg 图标,然后保持之前的用法:

<Icon type='search' />

然后通过 babel 插件转换成:

import _searchIcon from '@ant-design/icons/lib/dist/search.svg'
<Icon component={ _searchIcon } />

// 或者直接转化成
<Icon component={ require('@ant-design/icons/lib/dist/search.svg') } />

然后就可以借助 tree-shaking 只打包使用的 icon。

至于动态的 type ,不支持使用就好。有动态的需求可以使用即可:

import * as AllIcons from '@ant-design/icons/lib/dist'

<Icon component={ AllIcons[type] } />

实际上是去掉了原 type 的实际功能,将所有的 type 用法转换成了 component 用法。

我有个想法 💡 @afc163

我们可以使用 svg 图标,然后保持之前的用法:

<Icon type='search' />

然后通过 babel 插件转换成:

import _searchIcon from '@ant-design/icons/lib/dist/search.svg'
<Icon component={ _searchIcon } />

// 或者直接转化成
<Icon component={ require('@ant-design/icons/lib/dist/search.svg') } />

然后就可以借助 tree-shaking 只打包使用的 icon。

至于动态的 type ,不支持使用就好。有动态的需求可以使用即可:

import * as AllIcons from '@ant-design/icons/lib/dist'

<Icon component={ AllIcons[type] } />

实际上是去掉了原 type 的实际功能,将所有的 type 用法转换成了 component 用法。

思路和 4.0 改造是一样的,不过这个用 babel 转义显然降低了工作量,只有动态变更的需要手动处理了。

昨晚发完评论后临时写了个 Babel 插件,本地试了一下,完全可行 @wendzhue @afc163

const template = require('@babel/template')

function genRequireEpx (name) {
  return template.expression(`require('@ant-design/icons/lib/dist/${name}.svg')`)()
}

module.exports = function ({ Plugin, types: t }) {
  return {
    visitor: {
      // <Icon type='search' />
      JSXElement({ node }, { opts: { patterns = [] } }) {
        const { name, attributes } = node.openingElement
        if (!(name && name.name === 'Icon') || !attributes || !attributes.length) {
          return
        }
        attributes.forEach(attr => {
          if (attr.name.name === 'type') {
            attr.name.name = 'component'
            attr.value = genRequireEpx(attr.value.value)
          }
        })
      },
      // React.createElement(Icon, { type: "search" }
      CallExpression({ node }, { opts: { patterns = [] } }) {
        const cal = node.callee
        const arg = node.arguments
        if (!(cal.object && cal.object.name === 'React' &&
            cal.property && cal.property.name === 'createElement' &&
            arg[0] && arg[0].name === 'Icon' &&
            arg[1] && arg[1].properties
          )) {
          return
        }
        arg[1].properties.forEach(obj => {
          if (obj.key.name === 'type') {
            obj.key.name = 'component'
            obj.value = genRequireEpx(obj.value.value)
          }
        })
      },
    }
  };
}

还需要完善下转换规则和阉割 type 的实际功能。

任何进展 ?

看到官方icon源码里面的对这个打包的解决方案,把icon单独打包出一个js
https://github.com/Beven91/webpack-ant-icon-loader

@ARKKYN antd v4正在开发中#16911

您可以立即试用antd 4的Alpha版本

这个官方真的不打算解决这个问题吗? 这么大不需要的打包,真的劝退啊

其实这东西跟 afc163 在圣诞节的所作所为是一样的调性,潜台词是“老子喜欢,你爱用不用”

@lizy0329 4.0.0-alpha.2 已经在改了,涉及到精力和时间安排,着急的话fork自己改了...

@ lizy0329参见https://github.com/ant-design/ant-design/pull/18217

不酷,真的。

@lizy0329 see #18217

No cool, realy.

这不酷,真的。但这东西其实在改动的时候都应该想象到后果了,跟 HO!HO! 一样的调性没办法不拿来比较。

@ lizy0329

其实这东西跟afc163在圣诞节的效果所为是一样的调性,潜台词是“老子喜欢,你爱用不用”

为什么使用SVG代替字体?
将React SVG组件用于图标而不是图标字体

公司以前做过吗?
使用SVG交付Octicons

现在有什么问题?
之前的图标使用的字体由cdn加载,其大小不会反映在供应商上。 没有默认的CDN(您仍然可以将所有图标放入一个块中,并使用自己的CDN进行托管)来托管svg图标,这部分内容将反映在供应商中。
在本期中讨论的是如何摇树,如何按需加载图标。

如果您不能忍受,请立即加载所有图标,至少有三种方法可以避免。

@ afc163
我认为3.9的更改日志非常不友好。 没有解释为什么更改为SVG。 字体的缺点是什么,好处是什么?

顺便说一句,我反对使用svg(像这样,将viewBox设置为1024 * 1024),这会增加复合层操作的耗时。

@ afc163这太短,不足以解释为什么需要更改为SVG。 该官员没有给出足够明显的解释来解释为什么使用svg以及如何按需加载图标,我认为这是此问题中引起许多负面情绪的原因之一。

@muzea 感谢吐槽建议
viewBoxsvg在浏览器的渲染性能的影响,比起svg其子path路径绘制的定义、数量、节点关系,算小头吧。真正导致合成层操作增加的,后者是大头吧。
如果是指svg图标本身(宽高)过大,图标大的确会带来绘制的复杂度,但是这个相关系数比较低。可以保证的是,在处理从设计师得到的图标过程中,会尽量提高用户认知体验(图标无较大变形)的前提下,进行最大粗略的精度的路径压缩和相关优化。实际上,如果要保证浏览器在合成层阶段渲染时,会考虑svg sprite方案,但是这样通常做法会给页面添加副作用(头部或其他位置添加相关定义),对于一个维护性和通用性要求较高的库来说,可能不会考虑。

什么场景下人们讨厌svg作为web应用图标的解决方案是值得肯定的?

  • IE8用户
  • 用户网络情况一直良好
  • 图标只要能看就行(不关心清晰度)
  • 现在及未来单色图标永远够用

官方对这个issue跟进不足,的确其对应assign的人面对问题没有解决,但是现在不会了。

@lizy0329 一个人愿意用多大的恶意揣测他人的这个行为,别人没有权利干涉。但是这个人仍然被欢迎提一个pr

@HeskeyBaozi
该文档的图标部分在我的浏览器上的性能非常低。
image
实际上,在osx上的chrome上,当页面上有很多antd图标时,性能将非常糟糕。

也许babel-plugin-macros可以帮助我们解决这个问题?

@lizy0329 一个人愿意用多大的恶意揣测他人的这个行为,别人没有权利干涉。但是这个人仍然被欢迎提一个pr

这不是恶意揣测,这叫“找共性”。HO!HO! 事件绝对不是偶然发生的,必然是个长期积累。我也没诋毁意思,只是想 antd 发展更好,每次 update 时想下后果及解决方案。

所以说这个什么时候可以用呢? 在项目中用了antd,什么都没有做,就import了一个Button,打包后的bundle从177k直接变成了1.1m... analyzer 看了一下 确实是icons太大了

不使用捆绑包时,有没有办法将其从捆绑包中删除?

我正在使用create-react-app覆盖。 像这样:

fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
}),

你们应该为antd@3查看@ qaiser110解决方案

包的大小很大,因为antd source会对所有图标进行resolve.alias@ant-design/icons/lib/dist import重定向到一个自定义文件,该文件具有从@ant-design/icons挑选的图标。

它比拥有一大捆包要好,但是仍然不理想,因为您必须手动挑选图标。 尽管您通常会根据需要(仅在缺少图标的情况下)挑选樱桃。 要弄清楚需要挑剔的内容,可以在antd和源代码中搜索使用的图标。

如果我们有一个共享文件或来自antd来源的精心挑选的图标包,它将很有用。 这样,我们只需要担心为自己的来源挑选樱桃。 这是一个主意。 我们可以对antd组件导出的图标进行分组,而不是手动查看antd源以进行自动选择,您可以在自定义图标文件中仅export * from 'antd-cherry-pick-icons/icon' 。 可以通过社区的努力来做到这一点,以使其尽可能与antd源保持最新。

@LucasBassetti ,您确定不需要图标吗? 即使您不是直接使用<Icon /> ,某些antd组件也会使用` 。 例如, <Alert />

请注意,antd 4.0(在alpha中)通过不使用通配符import来解决此问题。 相反,他们选择了每个组件的导入

对我一直有效的临时解决方案,直到解决为止(antd> = 3.9)

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

如果有人在寻找config-overwrites.js

const { override, fixBabelImports, addWebpackAlias } = require('customize-cra');
const rewireCompressionPlugin = require('react-app-rewire-compression-plugin');
const rewireUglifyjs = require('react-app-rewire-uglifyjs');
const path = require('path');


module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
  addWebpackAlias({
    ['@ant-design/icons/lib/dist$']: path.resolve(__dirname, './src/client/icons.js')
  }),
  rewireUglifyjs,
  rewireCompressionPlugin
);

@adinnc图标路径已更改,不再@ant-design/icons/lib/outline/DownOutline

mark 关注一下这个问题,目前用到antd 3, 引入一个button, 就联动吧moment和icon都引过来了,光是icon文件的全部引入就有 500多k的大小

@DemonCloud moment 的问题可以关注一下 https://github.com/ant-design/babel-plugin-import/issues/352

对于通过react-app-rewired使用create-react-app的人们。

config-overrides.js

Const  path  =  require ( ' path ' );

/* config-overrides.js */
 module . exports  =  function  override ( config , env ) {
   let alias = ( config . resolve . alias  || {});
  Alias[ ' @ant-design/icons/lib/dist$ ' ] =  path . resolve ( __dirname , " ./src/icons.js " );

  Config . resolve . alias  = alias;

  Return config;
}

icons.js要点

不知道为什么,但是在使用了icons.js之后,我的捆绑包增加了600KB。

也许是因为我必须在我的代码https://www.npmjs.com/package/html-webpack-inline-source-plugin中使用此软件包

我通过编辑config-override.js将包大小减小了500KB,如下所示:

config-override.js

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css'
  }),
  // used to minimise bundle size by 500KB
  function(config, env) {
    const alias = config.resolve.alias || {};
    alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './src/icons.js');
    config.resolve.alias = alias;
    return config;
  }
);

./src/icons.js

/**
 * List all antd icons you want to use in your source code
 */
export {
  default as SearchOutline
} from '@ant-design/icons/lib/outline/SearchOutline';

export {
  default as CloseOutline
} from '@ant-design/icons/lib/outline/CloseOutline';

export {
  default as QuestionCircleOutline
} from '@ant-design/icons/lib/outline/QuestionCircleOutline';

export {
  default as PlayCircleOutline
} from '@ant-design/icons/lib/outline/PlayCircleOutline';

export {
  default as PauseCircleOutline
} from '@ant-design/icons/lib/outline/PauseCircleOutline';

export {
  default as LoadingOutline
} from '@ant-design/icons/lib/outline/LoadingOutline';

之前

Screen Shot 2019-11-05 at 2 56 54 pm

Screen Shot 2019-11-05 at 2 56 48 pm

我通过编辑config-override.js将包大小减小了500KB,如下所示:

config-override.js

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css'
  }),
  // used to minimise bundle size by 500KB
  function(config, env) {
    const alias = config.resolve.alias || {};
    alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './src/icons.js');
    config.resolve.alias = alias;
    return config;
  }
);

./src/icons.js

/**
 * List all antd icons you want to use in your source code
 */
export {
  default as SearchOutline
} from '@ant-design/icons/lib/outline/SearchOutline';

export {
  default as CloseOutline
} from '@ant-design/icons/lib/outline/CloseOutline';

export {
  default as QuestionCircleOutline
} from '@ant-design/icons/lib/outline/QuestionCircleOutline';

export {
  default as PlayCircleOutline
} from '@ant-design/icons/lib/outline/PlayCircleOutline';

export {
  default as PauseCircleOutline
} from '@ant-design/icons/lib/outline/PauseCircleOutline';

export {
  default as LoadingOutline
} from '@ant-design/icons/lib/outline/LoadingOutline';

之前

Screen Shot 2019-11-05 at 2 56 54 pm

Screen Shot 2019-11-05 at 2 56 48 pm

谢谢! 对我有帮助!

@adinnc图标路径已更改,不再@ant-design/icons/lib/outline/DownOutline

嘿,您能找到解决方法吗? 我也遇到同样的错误

根据我在此处看到的内容,仅介绍了解决方法。 组件仅导入它们使用的图标会不会变得更加轻松和整洁? 这样可以解决根本原因,如果我们使用命名导入,我希望这不会太难,不是吗?

@Nomeasmo ,应根据路线图在v4中修复。

如果3.X修复了,那就太好了。 如果可能,我不打算升级到4。

希望有一天能完全从Ant迁移出来,因为按钮之类的简单事情的CSS太复杂了,该库缺乏可访问性功能,甚至补丁更新中都充满了近1,000次提交。 就我的口味而言,这真是太多了。

标记

对于通过react-app-rewired使用create-react-app的人们。

config-overrides.js

const  path  =  require ( ' path ' );

/ * config-overrides.js * /
 module . exports  =  function  override ( config , env ) {
   let alias = ( config . resolve . alias  || (});
  alias [ ' @ ant-design / icons / lib / dist $ ' ] =  path . resolve ( __dirname , " ./src/icons.js " );

  config . resolve . alias  = alias;

  return config;
}

icons.js要点

仍然不起作用图标的捆绑包尺寸仍然很大
image

在v4.0.0-beta.0中,似乎无法为图标摇摇欲坠。
有没有人成功缩小图标包? 您能分享您的配置吗?

我后来尝试使用v4.0.0-beta.1并删除了@ant-design/compatible软件包,所有图标仍包含在捆绑包中。

对于通过react-app-rewired使用create-react-app的人们。
config-overrides.js

const  path  =  require ( ' path ' );

/ * config-overrides.js * /
 module . exports  =  function  override ( config , env ) {
   let alias = ( config . resolve . alias  || (});
  alias [ ' @ ant-design / icons / lib / dist $ ' ] =  path . resolve ( __dirname , " ./src/icons.js " );

  config . resolve . alias  = alias;

  return config;
}

icons.js要点

仍然不起作用图标的捆绑包尺寸仍然很大
image

您需要一个icons.js文件来包含需要导入的图标,例如https://github.com/ant-design/ant-design/issues/12011#issuecomment -552117531

对我一直有效的临时解决方案,直到解决为止(antd> = 3.9)

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

如果有人在寻找config-overwrites.js

const { override, fixBabelImports, addWebpackAlias } = require('customize-cra');
const rewireCompressionPlugin = require('react-app-rewire-compression-plugin');
const rewireUglifyjs = require('react-app-rewire-uglifyjs');
const path = require('path');


module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
  addWebpackAlias({
    ['@ant-design/icons/lib/dist$']: path.resolve(__dirname, './src/client/icons.js')
  }),
  rewireUglifyjs,
  rewireCompressionPlugin
);

将我的捆绑包从700kb减少到200kb,谢谢

在v4.0.0-beta.0中,似乎无法为图标摇摇欲坠。
有没有人成功缩小图标包? 您能分享您的配置吗?

我后来尝试使用v4.0.0-beta.1并删除了@ant-design/compatible软件包,所有图标仍包含在捆绑包中。

尽管更新了图标导入,但在4.0.0-rc.0中存在相同的问题

@jhockett我有同样的问题! 我发现我的一些进口商品打破了树的砍伐过程。 例如:_import'antd / lib / typography / Text'中的文本; _
我用'antd'; _的_import {印刷术}替换了它,图标离开了我的包!

@jhockett我有同样的问题! 我发现我的一些进口商品打破了树的砍伐过程。 例如:_import'antd / lib / typography / Text'中的文本; _
我用'antd'; _的_import {印刷术}替换了它,图标离开了我的包!

我所有的ant设计导入都使用您提到的语法:_import {印刷术} from'antd'; _
因此这似乎不是我的问题,但也许其他人可能会受到它的影响!

对我一直有效的临时解决方案,直到解决为止(antd> = 3.9)

  1. 调整webpack以不同方式解析图标。 在您的webpack配置中:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. 在文件夹src/或任何需要的位置创建icons.js 。 确保它与别名路径匹配!
    在此文件中,您定义antd应该包括哪些图标! 我只需要antd的Select组件的Down图标。
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

也可以在config-overwrites.js内使用react-app-rewire (创建反应应用程序修改)来执行此操作

如果有人在寻找config-overwrites.js

const { override, fixBabelImports, addWebpackAlias } = require('customize-cra');
const rewireCompressionPlugin = require('react-app-rewire-compression-plugin');
const rewireUglifyjs = require('react-app-rewire-uglifyjs');
const path = require('path');


module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
  addWebpackAlias({
    ['@ant-design/icons/lib/dist$']: path.resolve(__dirname, './src/client/icons.js')
  }),
  rewireUglifyjs,
  rewireCompressionPlugin
);

将我的捆绑包从700kb减少到200kb,谢谢

当我使用它时,它不起作用,下一步我该怎么办:
image

对于使用Parcel.js的用户来说,执行以下操作确实对我有用:

npm install purched-antd-icons

并添加package.json

  "alias": {
    "@ant-design/icons": "purched-antd-icons"
  }

在v4.0.0-beta.0中,似乎无法为图标摇摇欲坠。
有没有人成功缩小图标包? 您能分享您的配置吗?

我后来尝试使用v4.0.0-beta.1并删除了@ant-design/compatible软件包,所有图标仍包含在捆绑包中。

我通过像这样更改babel-plugin-import的配置解决了我的问题。

  {
    "libraryName": "antd",
+   "libraryDirectory": "es",
    "style": true
  },

https://github.com/ant-design/ant-design/issues/12011#issuecomment -552117531的启发,我将其与antd@4 (https://github.com/ant-design/ant -design / issues / 20661)。

将以下resolve.aliaswebpack配置中(也应与customize-cra ):

// [...]
config.resolve.alias = {
    "@ant-design/icons$": resolve(__dirname, "path/to/your/src/icons.tsx")
};
// [...]

您的icons.tsx应该看起来像这样:

/**
 * Provide all needed icons from antd. This file is associated to the webpack.config.js resolve.alias.
 */

export { default as LoadingOutlined } from "@ant-design/icons/LoadingOutlined";

例如,上面的LoadingOutlined图标对于Button组件是必需的。 在该文件中添加所有需要的图标。 您还可以重用该文件。 但这取决于您,因为您也可以使用从@ant-design/icons的直接导入:

import { LoadingOutlined } from "./icons";
import { LoadingOutlined } from "@ant-design/icons";

@matzeeable建议的解决方案确实对我icons.tsx包括哪些图标的正确方法是什么? 例如:我有一些表单元素,例如InputNumber和Select下拉列表。 有什么提示吗?

我想知道知道应该在icons.tsx包括哪些图标的正确方法是什么? 例如:我有一些表单元素,例如InputNumber和Select下拉列表。 有什么提示吗?

@ pradeepb6假设您从antd到您的源中包括一个新组件。 Webpack将尝试解析图标,但是找不到命名的导出,因为您从未在icons.tsx定义它。 您将收到如下警告:

image

之后,您知道需要在icons.tsx导出哪些图标,以便组件按预期工作。 🙂

@matzeeable谢谢。 我试过了但是我得到了错误,如屏幕截图所示。 代码可以在这里找到。

image

我已经在babel-plugin-import github中写过,但是由于更多的人在这里,也许这里有人遇到了这个问题。 我已经迁移到V4,并且正在观察捆绑包的大小。
当我添加https://github.com/ant-design/ant-design/issues/12011#issuecomment -577513378中写的"libraryDirectory": "es" ,我观察到以下错误:

[ error ] /home/maciek/Dokumenty/websites/bookingapp/frontend/node_modules/antd/es/notification/index.js:3
import * as React from 'react';
       ^

SyntaxError: Unexpected token *
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.antd/es/notification (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10975:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../lib/withData.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:8200:78)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../pages/_app.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10614:71)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Object.0 (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10754:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at 

我正在使用next.js btw。 滴水:

    "@ant-design/compatible": "0.0.1-rc.1",
    "@ant-design/icons": "^4.0.0-rc.0",
    "antd": "^4.0.0-rc.3",
    "babel-plugin-import": "^1.13.0",

任何人?

@ afc163已向美元在IssueHunt上查看

  • :moneybag:总存款:$ 203.00
  • :tada:存储库奖励(20%):$ 40.60
  • :wrench:服务费(10%):$ 20.30

我遇到和 @chemicalkosek 一样的问题,也是 [email protected] + next.js 目前通过 esm 解决了。

yarn add esm
"scripts": {
    "dev": "NODE_OPTIONS=\"-r esm\" next",
    "build": "NODE_OPTIONS=\"-r esm\" next build",
    "start": "NODE_OPTIONS=\"-r esm\" next start"
}

希望对其他人有帮助 :)

@ i-tengfei哇,正在工作! 非常感谢你!

对于antd @ 4,我们现在使用自己的软件包,该软件包将覆盖@ ant-design / icons软件包,并用fontawesome图标替换antd图标。

它仅提供antd需要的图标。 并为我们大大减少了包的大小,因为我们没有设法启用树状握手,因此包括了整个设计/图标包。

https://github.com/DavidSichau/antd-fa-icons

请升级到[email protected] ,此问题已得到完美解决。

https://github.com/ant-design/ant-design/issues/20661

对于使用Parcel.js的用户来说,执行以下操作确实对我有用:

npm install purched-antd-icons

并添加package.json

  "alias": {
    "@ant-design/icons": "purched-antd-icons"
  }

谢谢,它有效!

@afc163 @yesmeck 根据后台返回的数据进行设置icon,前端如何做到异步加载,比如后台返回的icon字符串是AppstoreOutlined, 我的做法如下:

const iconStr = res.icon // 服务器返回的数据假如
const Icon = React.lazy(() => import(`@ant-design/icons/${iconStr}`))

// render
<Icon />

但是现在直接编译都过不了。动态加载貌似不行

@ afc163

请升级到[email protected] ,此问题已得到完美解决。

20661

我不确定是否完全解决了。 它仍然将所有图标包捆绑到包装中:
我已经以这种方式导入了所有图标。
我使用“ @ ant-design / icons”:“ ^ 4.0.6”和webpack 4.43.0
也有这个配置

 {
    "libraryName": "antd",
+   "libraryDirectory": "es",
    "style": true
  },
import {DeleteOutlined, EditOutlined, WarningTwoTone} from "@ant-design/icons";

image

@afc163 @yesmeck 根据后台返回的数据进行设置icon,前端如何做到异步加载,比如后台返回的icon字符串是AppstoreOutlined, 我的做法如下:

const iconStr = res.icon // 服务器返回的数据假如
const Icon = React.lazy(() => import(`@ant-design/icons/${iconStr}`))

// render
<Icon />

但是现在直接编译都过不了。动态加载貌似不行

我想应该是要将改成{Icon}。
如果你把报错信息贴上来能够更好的判断原因。

使用babel-plugin-import我将大小从500kb +减小了

['import', { 
  libraryName: '@ant-design/icons', 
  libraryDirectory: '', // defaults to 'lib'
  camel2DashComponentName: false  // defaults to true
}]

Screen Shot 2020-05-02 at 10 11 58 PM

import {
  DesktopOutlined,
  FileOutlined,
  PieChartOutlined,
  TeamOutlined,
  UserOutlined,
} from '@ant-design/icons'

@thangbn

  [
       "import",
       {
         "libraryName": "@ant-design/icons",
         "libraryDirectory": "es/icons",
         "camel2DashComponentName": false
      },
       "@ant-design/icons"

  ],

@ mit123suki @nwoeddie感谢您的建议,我尝试了两者,但还是没有运气。 不知道我在配置中弄错了什么。 我的完整配置如下:

const webpack = require("webpack");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const CopyWebpackPlugin = require("copy-webpack-plugin");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
var LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
const AntdDayjsWebpackPlugin = require("antd-dayjs-webpack-plugin");
const path = require("path");

let dev = {
  mode: "development",
  optimization: {
    usedExports: true,
    noEmitOnErrors: true
  },
  entry: [
    path.resolve(__dirname, "./src/index.tsx")
  ],
  output: {
    path: path.resolve(__dirname, "./public"),
    publicPath: "/",
    filename: "[name].js"
  },
  target: "web",
  devServer: {
    // writeToDisk: true,
    historyApiFallback: true, // catch all 404
    port: 8080,
    hot: true,
    proxy: {
      "/backend": {
        target: "http://localhost:4000",
        pathRewrite: { "^/backend": "" }
      },
      "/runner": {
        target: "http://localhost:4001",
        pathRewrite: { "^/runner": "" }
      }
    }
  },
  devtool: "cheap-module-eval-source-map",
  resolve: {
    alias: {
      "react-dom": "@hot-loader/react-dom"
    },
    extensions: [".js", ".jsx", ".less", ".tsx", ".ts"]
  },
  plugins: [
    new LodashModuleReplacementPlugin(),
    new AntdDayjsWebpackPlugin(),
    new CopyWebpackPlugin([{ from: path.join(__dirname, "./static"), to: "./" }]),
    new ProgressBarPlugin(),
    new ForkTsCheckerWebpackPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      "process.env.ENV": JSON.stringify("dev"),
    }),
    new BundleAnalyzerPlugin({
      "openAnalyzer": true,
      analyzerPort: 8889
    })
  ],
  module: {
    rules: [
      {
        test: /\.(tsx|ts)$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              transpileOnly: true
            }
          }
        ],
        exclude: /node_modules/
      }
      , {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            "presets": [
              [
                "@babel/preset-env",
                {
                  "targets": "defaults",
                  "modules": false
                }
              ],
              [
                "@babel/preset-react"
              ]
            ],
            plugins: [
              "@babel/plugin-transform-runtime",
              ["import",
                { "libraryName": "antd", "style": false, "libraryDirectory": "es" }, "antd"],
              ["import",
                {
                  "libraryName": "@ant-design/icons",
                  // "style": false,
                  "libraryDirectory": "es/icons",
                  "camel2DashComponentName": false
                }, "@ant-design/icons"],
              "react-hot-loader/babel"
            ]
          }
        }
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          {
            loader: "less-loader",
            options: {
              sourceMap: true,
              javascriptEnabled: true
            }
          }]
      },
      {
        test: /\.(png|jpg|gif|svg|ico)$/,
        use: [
          {
            loader: "file-loader"
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          "style-loader",
          "css-loader"
        ]
      }
    ]
  },

};

module.exports = dev;

@afc163 @yesmeck 根据后台返回的数据进行设置icon,前端如何做到异步加载,比如后台返回的icon字符串是AppstoreOutlined, 我的做法如下:

const iconStr = res.icon // 服务器返回的数据假如
const Icon = React.lazy(() => import(`@ant-design/icons/${iconStr}`))

// render
<Icon />

但是现在直接编译都过不了。动态加载貌似不行

我想应该是要将改成{Icon}。
如果你把报错信息贴上来能够更好的判断原因。

Failed to compile.

./node_modules/@ant-design/icons/dist/icons/index.d.ts
Module not found: Can't resolve './AccountBookFilled' in '/Users/andy/Projects/shop-platform/node_modules/@ant-design/icons/dist/icons'

@Xezzon 直接显示第一个图标module都找不到。我尝试了加babel-plugin-import的配置,也还是不行。

@nwoeddie

  [
       "import",
       [
         { libraryName: 'antd', style: true },
         {
         "libraryName": "@ant-design/icons",
         "libraryDirectory": "es/icons",
         "camel2DashComponentName": false
      }] 
  ],

“ babel-loader”:“ ^ 7.1.5”
“ babel-plugin-import”:“ ^ 1.13.0”

嗨,nwoeddie〜!,我的配置不起作用,我将导入选项拆分为单个,但是也没有使用。 我可以学习你完整的配置吗

这个aritcle可能会解决问题: https :

@nwoeddie

  [
       "import",
       [
         { libraryName: 'antd', style: true },
         {
         "libraryName": "@ant-design/icons",
         "libraryDirectory": "es/icons",
         "camel2DashComponentName": false
      }] 
  ],

“ babel-loader”:“ ^ 7.1.5”
“ babel-plugin-import”:“ ^ 1.13.0”

嗨,nwoeddie〜!,我的配置不起作用,我将导入选项拆分为单个,但是也没有使用。 我可以学习你完整的配置吗

这不是babel 7的正确语法。导入插件不支持数组。 正确的方式:

    ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": true}, "ant"],
    ["import", {
      "libraryName": "@ant-design/icons",
      "libraryDirectory": "es/icons",
      "camel2DashComponentName": false
    }, "ant-design-icons"],
此页面是否有帮助?
0 / 5 - 0 等级