question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Refactor icons-svg@4.x with gulp

See original GitHub issue
  • 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分支

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

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:7
  • Comments:22 (15 by maintainers)

github_iconTop GitHub Comments

5reactions
HeskeyBaozicommented, Aug 28, 2019

各个社区在开发时,可以先构建一次@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'
    );
  });
})();
3reactions
HeskeyBaozicommented, Aug 29, 2019

确认一下命名风格:

// 以 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
Read more comments on GitHub >

github_iconTop Results From Across the Web

Icons with SVG's minified and layered using gulp - Medium
This post is about a quick POC implementing SVG Icons and a quick Angular directive for generating SVG icons. The gulp task is...
Read more >
A Gulp-Based External SVG Symbol Sprite Icon System
A Gulp-Based External SVG Symbol Sprite Icon System ... Font icons and data URI's in CSS content are a hack, while SVG icons...
Read more >
Hiswe/gulp-svg-symbols: Convert svg files to symbols - GitHub
gulp -svg-symbols is a minimal plugin for gulp. It converts a bunch of svg files to a single svg file containing each one...
Read more >
Gulp Vector SVG Icon (2) - SVG Repo
Free Gulp Vector Icon in SVG format. ✓ Download Free Gulp Vector and icons for commercial use. Gulp SVG vector illustration graphic art...
Read more >
gulp-svg-sprite - npm
SVG sprites & stacks galore — Gulp plugin wrapping around svg-sprite that reads in a bunch of SVG files, optimizes them and creates...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found