【问题标题】:Tree shakable icon component可摇树图标组件
【发布时间】:2021-04-11 12:40:22
【问题描述】:

我正在ChakraUI 和引导图标之上创建一个自定义设计系统。

引导图标包含 1000 多个 svg 图标。
我创建了一个抽象的 Icon 组件来抽象图标名称,这似乎更方便 IMO。

但是,我不确定这个模块是否会被摇树,而且我不知道如何更改实现以使其可摇树。

图标.tsx

import React from 'react'
import * as bootstrapIcons from '@emotion-icons/bootstrap'

// Union of all icon names: 'Alarm' | 'Circle' | 'Square' ...
type IconNames = keyof typeof bootstrapIcons

export const Icon: FC<{name: IconNames}> = ({name}) => {
  const Icon = bootstrapIcons[name]

  return (
    <div>
      <Icon style={{...}} />
    </div>

  )
}

App.tsx

import React from 'react'
import { Icon } from './Icon'

const App = () => {
  return <div>
    <Icon name="Alarm" />
  </div>
}

【问题讨论】:

    标签: reactjs typescript performance webpack tree-shaking


    【解决方案1】:

    Astrix 导入不能摇树。

    一般来说,当涉及到图标时,您可以使用 Sprite Sheet 或 Tree Shaking,但不能同时使用两者。

    要使这个特定的库树摆脱图标,您必须将导入和使用更改为如下所示(尚未测试,但应该可以工作)。

    import { Alarm } from '@emotion-icons/bootstrap/Alarm';
    
    const Use = () => <Alarm/>
    

    这里肯定有一个警告,可以构建一个可以更改的构建时插件...

    <Icon name="Alarm"/>
     // to.
    import { Alarm } from '@emotion-icons/bootstrap/Alarm';
    <Alarm/>
    

    并删除导入。

    astrix 导入不能进行树摇动的原因是因为 javascript 是一种非常动态的语言,静态分析使用了哪些键有时非常困难。

    考虑下面的代码

    import * as bootstrapIcons from '@emotion-icons/bootstrap'
    
    bootstrapIcons["mralA".reverse()] // which icons should be tree shaken?
    const Icons = new Proxy(bootstrapIcons) // which icons should be included? using proxy traps.
    const SubSet = PullSubset(bootstrapIcons) // which icons should be included? no matter what the implementation of PullSubset is it will be impossible to preform static analysis on it to determine which icons have been used.
    
    

    【讨论】:

    • 你的例子会起作用,但我会失去图标顶部的抽象。这种抽象允许我只对图标应用特定的品牌颜色。一个想法是做这样的事情:&lt;Icon icon={Alarm} color="blue" /&gt; - 但是这种方法不方便,因为我不会有打字稿的图标道具约束,我需要每次我需要使用图标时导入特定图标
    • 您需要找到另一种方法来实现这种抽象,因为静态分析不能再次摇动这种导入模式。一种解决方案可能是将您正在使用的每个 Icon 显式导入 Icon.tsx 中,每次您需要一个新 Icon 时,向 Icon.tsx 添加一个新的导入语句
    • 我明白你的意思。如果我写以下内容怎么办:import { Alarm } from '@emotion-icons/bootstrap' import { Icon } from '../Icon' const App = () =&gt; { return &lt;Icon icon={Alarm} color="blue" /&gt; } - 抱歉缩进..
    • 这里的行为超出了单个评论的范围,但几乎总是这不会摇树摇晃,是的,它不使用 astrix,但是 commonjs 规定第二个你导入文件的所有导出都存在该文件将最终出现在您的捆绑包中。对此有一些警告,但它们不太可能适用于此。 webpack.js.org/guides/tree-shaking 带有短语“确保没有编译器将您的 ES2015 模块语法转换为 CommonJS 模块”
    猜你喜欢
    • 2020-05-15
    • 2021-11-26
    • 2020-11-29
    • 2018-10-15
    • 2020-02-19
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    相关资源
    最近更新 更多