evergreen: Icon Tree Shaking not working

Version: 4.26 Bundler: Create-React-App default (Webpack)

Hello, I updated to the latest version to take advantage of tree-shaking but am still seeing all of the icons in my bundle:

image

I am not using the Icon component anywhere in my app. I do, however, use Menu and Menu.Item and am wondering if the icon prop on Menu.Item is causing all icons to be included.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 26 (19 by maintainers)

Most upvoted comments

@mshwery is this something we’d want to add to v5? since it is a breaking change and all or are looking for a solution that’s backwards compatible

@Chrischuck 100% will be part of v5: Screen Shot 2020-04-28 at 1 16 11 PM

@mshwery is this something we’d want to add to v5? since it is a breaking change and all or are looking for a solution that’s backwards compatible

Hi @totaldis! Yes there are some incorrect assumptions in there 😅

If you were using the <Icon/> component before 4.26.0 it was bundling all icons from blueprintjs, but now it’s only bundling those you’ve specifically asked for.

<Icon /> behavior is unchanged. If you use this component you will not get any tree-shaking. Similarly if you use any other Evergreen component that internally uses <Icon /> you will not get the benefit of tree-shaking (plans to fix this as a breaking change in v5).

It actually looks more like the icons themselves were created as separate components

Correct. If you want to tree-shake icons you should import them individually (e.g. import { CogIcon } from 'evergreen-ui'. There is a codemod in the package under /codemods/ that will automatically do this for you if you want to use it.

…but previously I was swapping blueprints icons out with NormalModuleReplacementPlugin which was simple since their exports all had one of two names: IconSvgPaths16 and IconSvgPaths20.

In this latest version I’d have to accomplish that by replacing every icon component with some generic component (except for those that are necessary since they’re baked into some components like <CrossIcon />) .

Correct.

@cstrat you can do that today, but you’d have to pass the entire component: iconBefore={<FontAwesomeIcon icon={faHome} />}

Interesting approach. So while still supporting icon strings, you’d have to preload them.

Instead of reading from a map of all possible strings, we would be reading from the map of icons explicitly imported. That’s a good idea. Would require some additional setup – and could still be considered a breaking change since you can’t safely upgrade without adding that registration step.

To get icon tree-shaking across all of evergreen we’ll need to implement a breaking change that will require rewriting all imports and usage of icons to pass explicit icon components, instead of using icon strings like icon="cog"