Code Monkey home page Code Monkey logo

Comments (22)

HeskeyBaozi avatar HeskeyBaozi commented on May 21, 2024 5

各个社区在开发时,可以先构建一次@ant-design/icons-svg(未发包),该包位于packages/icons-svg。之后可使用 lerna link 到对应社区的组件包进行开发。

开发思路可以分为两个阶段:

  • 组件文件生成阶段:利用@ant-design/icons-svg中的抽象节点(asn, Abstract Node)。生成对应的ReactElement或者VNode。(Angular社区可以使用helpers中的renderIconDefinitionToSVGElement渲染工具函数来渲染)。之后生成组件输出到src目录。当然,也可以利用旧的构建好的组件重新编写一个函数组件即可。注意旧的组件就不再需要内部的图标集合(即可以删去)
  • 构建阶段:使用构建工具或编译工具 babel/tsc 或者社区打包解决方案 father/webpack/rollup等构建。

思路示例:

Angular (仅供参考)

// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts
import * as allIconDefs from '@ant-design/icons-svg';
import { renderIconDefinitionToSVGElement } from '@ant-design/icons-svg/es/helpers';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';

export interface IconDefinitionNg extends Omit<IconDefinition, 'icon'> {
  identifier: string;
  icon: string;
}

export function walk<T>(fn: (iconDef: IconDefinitionNg) => Promise<T>) {
  return Promise.all(
    Object.keys(allIconDefs).map((identifier) => {
      const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
        identifier
      ];
      const { name, theme } = iconDef;
      const inlineSvg = renderIconDefinitionToSVGElement(iconDef, {
        // the options only affect the two-tone icons.
        placeholders: { primaryColor: '#333', secondaryColor: '#E6E6E6' }
      });

      return fn({ name, theme, icon: inlineSvg, identifier });
    })
  );
}

(async () => {
  await emptyDir(path.resolve(__dirname, `../lib/icons/defs`));

  const publicApiRows = await walk(async ({ identifier, ...iconDef }) => {
    await writeFile(
      path.resolve(__dirname, `../lib/icons/defs/${identifier}.ts`),
      `export const ${identifier} = ${JSON.stringify(iconDef)};`,
      'utf8'
    );

    return `export { ${identifier} } from './defs/${identifier}';`;
  });

  await writeFile(
    path.resolve(__dirname, `../lib/icons/public_api.ts`),
    publicApiRows.join('\n'),
    'utf8'
  );
})();

生成效果:
002

React (仅供参考)

// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts

import * as allIconDefs from '@ant-design/icons-svg';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';
import { template } from 'lodash';

export interface IconDefinitionWithIdentifier extends IconDefinition {
  identifier: string;
}

export function walk<T>(
  fn: (iconDef: IconDefinitionWithIdentifier) => Promise<T>
) {
  return Promise.all(
    Object.keys(allIconDefs).map((identifier) => {
      const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
        identifier
      ];
      return fn({ identifier, ...iconDef });
    })
  );
}

(async () => {
  await emptyDir(path.resolve(__dirname, `../src/icons`));

  const render = template(`
  import React from 'react';
  import <%= identifier %> from '@ant-design/icons-svg/es/<%= identifier %>';
  import AntdIcon, { AntdIconProps } from '../components/AntdIcon';

  const <%= _identifier %> = (props: AntdIconProps) => <AntdIcon {...props} icon={<%= identifier %>} />;
  export default <%= _identifier %>;
`);

  await walk(async ({ identifier }) => {
    // It will be better if an react antd icon component has theme suffix.
    // or use outline as default theme like this:
    const _identifier = identifier
      .replace(/Outline$/, '')
      .replace(/Fill$/, 'Filled')
      .replace(/TwoTone$/, 'TwoTone');

    await writeFile(
      path.resolve(__dirname, `../src/icons/${_identifier}.ts`),
      render({
        identifier,
        _identifier
      }),
      'utf8'
    );
  });
})();

效果:
image

Vue (仅供参考)

// generate.ts
// $ node --require ts-node/register/transpile-only generate.ts

import * as allIconDefs from '@ant-design/icons-svg';
import { IconDefinition } from '@ant-design/icons-svg/es/types';
import * as path from 'path';
import { writeFile, emptyDir } from 'fs-extra';
import { template } from 'lodash';

export interface IconDefinitionWithIdentifier extends IconDefinition {
  identifier: string;
}

export function walk<T>(
  fn: (iconDef: IconDefinitionWithIdentifier) => Promise<T>
) {
  return Promise.all(
    Object.keys(allIconDefs).map((identifier) => {
      const iconDef = (allIconDefs as { [id: string]: IconDefinition })[
        identifier
      ];
      return fn({ identifier, ...iconDef });
    })
  );
}

(async () => {
  await emptyDir(path.resolve(__dirname, `../src/icons`));

  const render = template(`
  import Vue from 'vue';
  import Icon from '../components/Icon';
  import <%= identifier %> from '@ant-design/icons-svg/es/<%= identifier %>';

  export default Vue.component('<%= kebabCaseIdentifier %>', {
    functional: true,
    render: (h, { data, children }) => h(Icon, { ...data, type: <%= identifier %> }, children)
  });
`);

  await walk(async ({ identifier, ...iconDef }) => {
    const { name, theme } = iconDef;
    await writeFile(
      path.resolve(__dirname, `../src/icons/${identifier}.ts`),
      render({
        identifier,
        kebabCaseIdentifier: `${name}-${theme}`
      }),
      'utf8'
    );
  });
})();

from ant-design-icons.

HeskeyBaozi avatar HeskeyBaozi commented on May 21, 2024 3

确认一下命名风格:

// 以 account-book 为例
// @ant-design/icons-svg/es/asn/AccountBookFilled
var AccountBookFilled = {
  "name": "account-book",
  "theme": "filled",
  "icon": {
    "tag": "svg",
    "attrs": {
      "viewBox": "64 64 896 896",
      "focusable": "false"
    },
    "children": [{
      "tag": "path",
      "attrs": {
        "d": "M880 184..."
      }
    }]
  }
};

// @ant-design/icons-svg/es/asn/AccountBookOutlined
var AccountBookOutlined = {
  "name": "account-book",
  "theme": "outlined",
  "icon": {
    "tag": "svg",
    "attrs": {
      "viewBox": "64 64 896 896",
      "focusable": "false"
    },
    "children": [{
      "tag": "path",
      "attrs": {
        "d": "M880 184..."
      }
    }]
  }
};

// @ant-design/icons-svg/es/asn/AccountBookTwoTone
var AccountBookTwoTone = {
  "name": "account-book",
  "theme": "twotone",
  "icon": function icon(primaryColor, secondaryColor) {
    return {
      "tag": "svg",
      "attrs": {
        "viewBox": "64 64 896 896",
        "focusable": "false"
      },
      "children": [{
        "tag": "path",
        "attrs": {
          "d": "M712 304...",
          "fill": secondaryColor
        }
      }, {
        "tag": "path",
        "attrs": {
          "d": "M639.5 414...",
          "fill": primaryColor
        }
      }, {
        "tag": "path",
        "attrs": {
          "d": "M880 18...",
          "fill": primaryColor
        }
      }]
    };
  }
};

短横线连字形式可以由name + '-' + theme得到,通常用于Vue组件名称形式中

  • account-book-filled
  • account-book-outlined
  • account-book-twotone

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024 1

icons-react 库已完成对应 更新

from ant-design-icons.

zWingz avatar zWingz commented on May 21, 2024 1

观察了下, 目前使用icons-react是需要逐个icon引入并且使用

我的做法是一次性把需要用到icon引入进来, 然后通过svg-sprite 形式使用, 使用时候只需要用过<icon name='xxxx'/>, 不需要多次import icon

刚完成vue版, 不知道是否有其他坑

from ant-design-icons.

tangjinzhou avatar tangjinzhou commented on May 21, 2024 1

@zWingz Vue版本完成了?可以提pr上来

from ant-design-icons.

BANG88 avatar BANG88 commented on May 21, 2024 1

@HeskeyBaozi 我的修改太少了。 我直接push到v4了..

from ant-design-icons.

HeskeyBaozi avatar HeskeyBaozi commented on May 21, 2024

之前pr #100

包相关变动

packages/icons 中的包名由 @ant-design/icons-svg 修改为 @ant-design/icons-svg-legacy。包名 @ant-design/icons-svg 由项目下的目录重写的 packages/icons-svg 继承。

新的 @ant-design/icons-svg 包和原来的版本 ( 4.0.0-alpha.0@ant-design/icons <= 2.1.1 ) 相比,有如下改动:

  • 不再提供用于存放未处理的图标的 svg 目录
  • 不再提供用于全量引入的 dist.js 文件和压缩过的 umd.js 文件,全量引入直接用 import * as allIcons from '@ant-design/icons-svg', 走 index.js 即可
  • 不再提供用于 tree-shakinglib/index.es.js 文件
  • 不再提供用于字符串字面量引入用的短横线图标名称的清单 manifest.js 文件
  • 提供 es 目录用于 tree-shaking

最终用户得到的目录如下:

es
inline-svg # 此为处理后存放的svg图标
lib
package.json
ReadMe.md

这些改动的原则都是倾向于按需引入,保证主入口文件只有图标的导出,使得 import * as allIcons from '@ant-design/icons-svg' 只会导出图标信息。

此PR来源于

#90
@ant-design/icon-kit 这个脚手架已自我废弃

目前图标

查看当前全部图标

为什么

  • 不使用 rxjs
    响应式编程这类范式强大之处在于对可观察数据的时序性控制和数学上持续性赋值:=不同流的可组合性。图标生成就是文件系统IO和数据结构转换。显然gulp及其生态能把这个任务做得更好,rxjs也可以做但显然其长处并没有发挥出来,且编写无确切规范导致维护性差。

  • 速度与维护选择

Before icon-kit (rxjs) gulp
old-generate-use-15s new after
15.42s 6.88s 9.55s

from ant-design-icons.

wzhudev avatar wzhudev commented on May 21, 2024

赞赞赞

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

@HeskeyBaozi 我有个想法就是 icons-svg 这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要

from ant-design-icons.

HeskeyBaozi avatar HeskeyBaozi commented on May 21, 2024

@HeskeyBaozi 我有个想法就是 icons-svg 这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要

这个可以的。做好和其他开发者的沟通工作即可。我会尽快完成。

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

@zWingz 欢迎 pr

from ant-design-icons.

zWingz avatar zWingz commented on May 21, 2024

目前我开发方案是使用svg-symbol来实现, twotone方案是通过css variable, 可能兼容性上跟ant-design所要求的有点出入

from ant-design-icons.

tangjinzhou avatar tangjinzhou commented on May 21, 2024

icons-vue done

from ant-design-icons.

HeskeyBaozi avatar HeskeyBaozi commented on May 21, 2024

目前各个社区的进度跟进方面 Vue 社区已经完成了。

关于合并有一些要注意的点:

  • Vue 之前是合并到 master 分支上的,正常情况下合并应该是没有冲突 @tangjinzhou

AngularReact Native 方面:

  • rn 代码是直接跨包使用 SVG 图标 @BANG88

const svgFolder = path.resolve(process.cwd(), '../icons/svg/', name);

需要修改路径到 icons-svg/svg,同时注意主题风格名字的变化 fill -> filledoutline -> outlined

  • Angular 方面之前本身是全拷贝4.0之前的构建过程,总体来说这次有修改是构建本身的优化,对于用户来说,图标的变化是最直接的感知。所以应急方案为 路径修改到 icons-svg/svg @wendellhu95

SVG_DIR: path.resolve(__dirname, '../../icons/svg'),

且注意主题风格名字的变化 fill -> filledoutline -> outlined

from ant-design-icons.

BANG88 avatar BANG88 commented on May 21, 2024

好久没动 卡在 lerna bootstrap 😢

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

我这边统计了下图标的变化,主要是新增了图标,以及删除了 typo 错误的图标

https://github.com/vagusX/icons-v4-diff/pull/1/files

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024
  • ant-design-icons 仓库新建 next-v4 分支,之后社区的next-v4分支 将会提pr,该pr包含对原icons-svg的命名和新的icons-svg增加。

React/React-Native/Vue/Angular各自社区实现对应支持tree shaking的图标组件或指令,分支在仓库ant-design-icons下的next-v4分支

  • @ant-design/icons (React) @vagusX #112
  • @ant-design/icons-vue (Vue) @tangjinzhou #153
  • @ant-design/icons-angular (Angular) @wendzhue
  • @ant-design/icons-react-native (React-Native) @BANG88

各自社区支持tree shaking的图标组件或指令实现后,即可去掉WIP:前缀。
同时原来的icons-svg-legacy可以考虑删除。
之后将next-v4分支合并到master分支上。

@wendellhu95 #196 这个 mr 合并了,我理解 ng 的也完成了哈

from ant-design-icons.

wzhudev avatar wzhudev commented on May 21, 2024

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

后续 actions:

  • 从 master 中切出 legacy 分支
  • 将 next-v4 合并到 master
  • 发布 @ant-design/[email protected]
  • 发布 @ant-design/icons 的对应版本 (react集成包)

后续原稳定分支的修复都在 legacy 上发布和修复
master 分支用来开发新的分支代码

from ant-design-icons.

wzhudev avatar wzhudev commented on May 21, 2024

分支不如叫 legacy

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

分支不如叫 legacy

有道理

from ant-design-icons.

vagusX avatar vagusX commented on May 21, 2024

@HeskeyBaozi 这个 issue 可以先 close 掉?

from ant-design-icons.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.