[譯] 爲你的 React 應用製做 SVG 圖標庫

爲你的 React 應用製做 SVG 圖標庫

目前來講,使用 SVG 是爲應用建立圖標庫的最好方法。經過 SVG 製做出來的圖標是可縮放且可調整的,同時也是離散的,這意味着它們能夠進行增量加載或更新。而與之相反,使用字體進行構建的圖標是不能進行增量加載/更新的。僅這一點就使 SVG 圖標成爲了那些依賴於代碼分離和增量部署的高性能應用的更佳選擇。前端

這篇文章描述瞭如何從一個 SVG 圖標庫中建立一個由 React 組件構成的包。儘管我會着重於 React 框架,然而製做任何其餘類型的包也是同理的。在 Twitter 的項目中我使用了這篇文章介紹的幾種不一樣方式來打包公司內部的 SVG 圖標庫,包括:優化事後的 SVG ,純 JavaScript 模塊,React Dom 組件,和 React Native 組件。react

使用圖標

最終,咱們獲得的是一個能像任何其餘 JavaScript 包同樣被安裝並使用的 JavaScript 包。android

yarnpkg add @acme/react-icons
複製代碼

每個圖標均可以將其看做一個可用的,被獨立導出的 React 組件。ios

import IconCamera from '@acme/react-icons/camera';
複製代碼

上面這行代碼容許你的模塊打包工具只打包須要的圖標。當使用代碼分割功能時,圖標們能經過塊來進行高效地分離。相比於那些引入字體並將全部圖標打包入一個單一組件中的圖標庫來講,這是一個重大的優點。git

// 整個圖標庫都被打包進了你的應用
import Icon from '@acme/react-icons';
const IconCamera = <Icon name='camera' />;
複製代碼

每個圖標都能很簡單地根據使用狀況來進行自定義(例如,顏色和大小等)。github

import IconCamera from '@twitter/react-icons/camera';
const Icon = (
  <IconCamera
    style={{ color: 'white', height: '2em' }}
  />
);
複製代碼

然而圖標最終是渲染成 SVG 的,這是一個不爲組件使用者們所知的實現細節。web

建立組件

每一個 React 組件都利用從 SVG 源文件裏提取出的路徑和維度數據渲染出了一個行內 SVG 圖像。使用 createIconComponent 助手函數,咱們只需寥寥幾行模板代碼即可從 SVG 數據中建立一個組件。json

import createIconComponent from './utils/createIconComponent';
import React from 'react';
const IconCamera = createIconComponent({
  content: <g><path d='...'></g>,
  height: 24,
  width: 24
});
IconCamera.displayName = 'IconCamera';
export default IconCamera;
複製代碼

這是一個使用 createIconComponent 函數在搭建像 Twitter Lite 這樣的 web 應用(使用 React Native for Web 搭建)時的一個例子。後端

// createIconComponent.js
import { createElement, StyleSheet } from 'react-native-web';
import React from 'react';

const createIconComponent = ({ content, height, width }) =>
  (initialProps) => {
    const props = {
      ...initialProps,
      style: StyleSheet.compose(styles.root, initialProps.style),
      viewBox: `0 0 ${width} ${height}`
    };

    return createElement('svg', props, content);
  };

const styles = StyleSheet.create({
  root: {
    display: 'inline-block',
    fill: 'currentcolor',
    height: '1.25em',
    maxWidth: '100%',
    position: 'relative',
    userSelect: 'none',
    textAlignVertical: 'text-bottom'
  }
});
複製代碼

fill 這個樣式設置爲 currentcolor 可讓你經過 color 樣式屬性來控制 SVG 的顏色。react-native

如今咱們須要作的只剩下使用腳原本處理 SVG 並生成對應的 React 組件了。

建立圖標包

你能夠在 GitHub 上的一個叫作 icon-builder-example 的倉庫裏找到完成這一步工做的其中一種方式的完整示例代碼。

整個示例工具的項目結構大概長這樣:

.
├── README.md
├── package.json
├── scripts/
    ├── build.js
    ├── createReactPackage.js
    └── svgOptimize.js
└── src/
    ├── alerts.svg
    ├── camera.svg
    ├── circle.svg
    └── ...
複製代碼

構建腳本使用了 SVGO 來優化 SVG,提取 SVG 路徑信息和元數據。以後例子中的 React 打包工具 使用了模板來建立 package.json 文件和那些須要首屏展現的 React 圖標。

import createIconComponent from './utils/createIconComponent';
import React from 'react';
const ${componentName} = createIconComponent({
  height: ${height},
  width: ${width},
  content: <g>${paths}</g>
});
${componentName}.displayName = '${componentName}';
export default ${componentName};
複製代碼

爲了從相同的 SVG 源編譯其餘類型的包,也能夠引入額外的打包工具。當底層的圖標庫改變時,只須要幾條命令就能夠從新編譯數以百計的圖標併爲每一個包發佈新版本。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索