Closed HeskeyBaozi closed 4 years ago
之前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-shaking
的 lib/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'
只会导出图标信息。
https://github.com/ant-design/ant-design-icons/pull/90
@ant-design/icon-kit
这个脚手架已自我废弃
不使用 rxjs
响应式编程这类范式强大之处在于对可观察数据的时序性控制和数学上持续性赋值:=
不同流的可组合性。图标生成就是文件系统IO和数据结构转换。显然gulp
及其生态能把这个任务做得更好,rxjs
也可以做但显然其长处并没有发挥出来,且编写无确切规范导致维护性差。
速度与维护选择
Before | icon-kit (rxjs) | gulp |
---|---|---|
15.42s | 6.88s | 9.55s |
各个社区在开发时,可以先构建一次@ant-design/icons-svg
(未发包),该包位于packages/icons-svg
。之后可使用 lerna link
到对应社区的组件包进行开发。
开发思路可以分为两个阶段:
@ant-design/icons-svg
中的抽象节点(asn, Abstract Node)。生成对应的ReactElement或者VNode。(Angular社区可以使用helpers中的renderIconDefinitionToSVGElement
渲染工具函数来渲染)。之后生成组件输出到src
目录。当然,也可以利用旧的构建好的组件重新编写一个函数组件即可。注意旧的组件就不再需要内部的图标集合(即可以删去)思路示例:
// 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'
);
})();
生成效果:
// 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'
);
});
})();
效果:
// 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'
);
});
})();
赞赞赞
@HeskeyBaozi 我有个想法就是 icons-svg
这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要
@HeskeyBaozi 我有个想法就是
icons-svg
这边 theme 也统一改成 Filled/Outlined/TwoTone 避免从 fill/outline/twoTone 转换,这里显得有点没有必要
这个可以的。做好和其他开发者的沟通工作即可。我会尽快完成。
确认一下命名风格:
// 以 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
观察了下, 目前使用icons-react
是需要逐个icon引入并且使用
我的做法是一次性把需要用到icon引入进来, 然后通过svg-sprite
形式使用, 使用时候只需要用过<icon name='xxxx'/>
, 不需要多次import icon
刚完成vue版, 不知道是否有其他坑
@zWingz Vue版本完成了?可以提pr上来
@zWingz 欢迎 pr
目前我开发方案是使用svg-symbol来实现, twotone方案是通过css variable
, 可能兼容性上跟ant-design所要求的有点出入
icons-vue done
目前各个社区的进度跟进方面 Vue
社区已经完成了。
关于合并有一些要注意的点:
Vue
之前是合并到 master
分支上的,正常情况下合并应该是没有冲突 @tangjinzhou Angular
和 React Native
方面:
SVG
图标 @bang88 需要修改路径到 icons-svg/svg
,同时注意主题风格名字的变化 fill
-> filled
,outline
-> outlined
icons-svg/svg
@wendellhu95 且注意主题风格名字的变化 fill
-> filled
,outline
-> outlined
好久没动 卡在 lerna bootstrap 😢
@HeskeyBaozi 我的修改太少了。 我直接push到v4了..
我这边统计了下图标的变化,主要是新增了图标,以及删除了 typo 错误的图标
React/React-Native/Vue/Angular各自社区实现对应支持
tree shaking
的图标组件或指令,分支在仓库ant-design-icons下的next-v4
分支
- [x] @ant-design/icons (React) @vagusX #112
- [x] @ant-design/icons-vue (Vue) @tangjinzhou #153
- [ ] @ant-design/icons-angular (Angular) @wendzhue
- [x] @ant-design/icons-react-native (React-Native) @bang88
各自社区支持
tree shaking
的图标组件或指令实现后,即可去掉WIP:
前缀。 同时原来的icons-svg-legacy
可以考虑删除。 之后将next-v4
分支合并到master
分支上。
@wendellhu95 https://github.com/ant-design/ant-design-icons/pull/196 这个 mr 合并了,我理解 ng 的也完成了哈
嗯,完成~
在 2019年12月21日,16:47,vagusX notifications@github.com 写道:
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 的也完成了哈
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
后续 actions:
后续原稳定分支的修复都在 legacy 上发布和修复 master 分支用来开发新的分支代码
分支不如叫 legacy
分支不如叫 legacy
有道理
@HeskeyBaozi 这个 issue 可以先 close 掉?
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
分支上。