1.6.6 • Published 2 years ago

icons-svg v1.6.6

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

icons-svg

icons-svg 是一个能使用 svg icon 就像使用 @ant-design/icons 一样的工具。

本项目核心逻辑参考自 @ant-design/icons,将其改写为一个能在任意项目中使用的包。 核心逻辑就是将 svg 文件解析为 js 对象,并提供 React 组件可直接使用该 js 对象渲染图标。

本项目分几种使用方式

  1. 将 svg 作为单个 npm 包发布后使用
  2. 将 svg 作为多个 npm 包发布后使用(@ant-design/icon 就是如此,好处是多框架复用,不局限于 react)
  3. 在项目中直接使用
  4. 在 umi 项目中使用

下面详细说明各种使用方式

1、将 svg 作为单个 npm 包发布后使用

yarn create icons-svg ./my-icons
cd my-icons
yarn

将自己的 svg 图标按主题放入项目 svg 下的主题文件夹中。

- svg
  - filled 填充类型的图标
  - outlined 线性图标
  - twotone 颜色图标

执行命令 npm publish 即可发布到 npm 上。之后有新增 svg icon 也是直接 npm publish 发布即可。

2、将 svg 作为多个 npm 包发布后使用(todo)

在不同包中执行不同命令。

3、仅在项目中使用

必须是 ts 项目,否则还是建议发成 npm 包后使用。

和之前步骤类似,找一个目录存放 svgoutlined 等文件夹,以如下目录结构为例

- package.json
- src
  - svg
    - filled
    - outlined
  - icons

依次执行

yarn ei gen all --svg src/svg --output src/icons

然后在项目中引用即可。

// src/App.tsx
const { SmileOutlined } from '@/icons';

4、在 umi 项目中使用

使用 umi-plugin-icons 插件即可。

faq

新增一个 icon 要怎么做

目前没有增量新增或指定新增 icon 功能,每次都是全量处理,所以和初始化流程相同

yarn gen all --svg <svg-dir> --output <output-dir>

如何实现按需加载

使用 babel-plugin-import 插件,并配置

 {
  libraryName: '@icons',
  libraryDirectory: 'icons',
  camel2DashComponentName: false,
},

原理说明

现在有一个 svg 图标,使用编辑器打开查看,它的的内容是这样的(省去了路径的一些信息,标签结构是这样的)

<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 1024 1024">
  <path d="M885.9 533.  .....     2.1-19.6 43z"/>
</svg>

将其作为字符串读取并使用 SVGO 解析、处理,偏向「清理」这种行为,对属性排序、移除不必要的属性等等。

const svg = '<?xml version="1.0" ...>';
const optimizer = new SVGO({
  floatPrecision: 2,
  // 通过 plugins 来对内容进行修改,支持自定义 plugin
  plugins: [],
});
const { data } = await optimizer.optimize(svg);

处理得到的 data 还是字符串,但移除掉了一些无关信息,如 classfill 等属性。

接下来就是重点,根据「清理」后的 svg 字符串,生成 asn,类似这样

{
  "tag": "svg",
  "attrs": { "viewBox": "0 0 1024 1024", "focusable": "false" },
  "children": [
    {
      "tag": "path",
      "attrs": {
        "d": "..."
      }
    }
  ]
}

再生成一个 asn.ts 文件,里面会导出上述对象,这样一个文件就可以供组件调用。

// React Icon component
import * as React from 'react';
import LikeOutlinedSvg from './asn/LikeOutlined.ts';
import AntdIcon, { AntdIconProps } from '../components/AntdIcon';

const LikeOutlined = (
  props: AntdIconProps,
  ref: React.ForwardedRef<HTMLSpanElement>,
) => <AntdIcon {...props} ref={ref} icon={LikeOutlinedSvg} />;

LikeOutlined.displayName = 'LikeOutlined';
export default React.forwardRef<HTMLSpanElement, AntdIconProps>(LikeOutlined);

这个组件可以直接在项目中使用。

当然,上面所有流程都会由本项目完成,用户只需要直接使用 <LikeOutlined /> 即可在页面中渲染一个点赞按钮。