首頁 > 軟體

Iconfont不能上傳如何維護Icon

2022-07-09 14:00:19

引言

使用 iconfont 有很多優勢,比如只需要載入一次,全部圖示都可以設定字號大小,顏色、透明度等,可以隨意變換字型的形態,並且圖示是向量的,不會隨著字型大小的變化失真,得益於 iconfont.cn 提供的便利,大多情況下,我們不必上傳自己的圖示,只需要便捷的搜尋,就可以將圖示加入到自己的專案圖示庫中,但最近工作中卻遇到了比較嚴重的問題。

現在做的事情

我所在公司目前正在建設低程式碼平臺,這個低程式碼平臺可以說是無程式碼,需要從原先的各個應用中抽取部分頁面和元件成為低程式碼元件,這樣低程式碼平臺就可以通過拖拽元件,形成一個有個性化的業務場景。如果 A 應用中的 A 元件需要更新,那麼低程式碼中的元件也需要同步更新,所以說元件並不是單獨的一個 npm 包,而是類似於 webpack5 模組聯邦(Module Federation)打包出來的 remote(遠端)元件。

遇到的問題

問題一:命名衝突

原先都是一個個獨立的應用,都是可以獨立部署獨立執行,現在需要將這些應用組合在一起,形成一個新的應用,就遇到這個關於圖示的問題。

由於原先各個應用都是獨立部署,所以專案中就直接參照了 iconfont 中的字型,命名也都叫 iconfont,一旦將這些元件組合到一起,命名衝突之外,字型中的 unicode 也會衝突。

問題二:icon 圖示庫沒交接

由於 icon 圖示庫都是各個應用的前端開發者維護的,他們都在自己的使用者名稱下建立專案, iconfont 圖示庫在 git 倉庫之外,在人員變動的情況下,圖示庫的許可權往往會忘記交接。

問題三: iconfont 維護

正巧遇到 iconfont 維護,到目前為止雖然可以使用,但是想要上傳新的圖示還是不行。

如何解決?

問題一:全域性替換

最簡單的方式是各個應用全域性替換加字首。

- <span class="iconfont icon-xxx"></span>
+ <span class="appAiconfont appAicon-xxx"></span>

這樣做當然沒問題,但是到低程式碼平臺那邊就會載入 n 個字型檔案,並且都是包含整個應用的字型,這就失去了使用 iconfont 的優勢。

問題二:要回許可權

雖然我們可以要回離職人員 iconfont 中專案的許可權,短期可以解決專案上圖示使用的問題,但是這個問題還是會有存在的可能。

問題三:力所不及

iconfont 目前也遇到了較大的問題,到目前為止還無法上傳檔案,對於我們這些 iconfont 的使用者來說只有等待。

最終方案:使用 svg 代替 iconfont

使用 svg 的優勢

  • 完全離線化使用,不需要從 CDN 下載字型檔案,圖示不會因為網路問題呈現方塊,也無需字型檔案本地部署。
  • 沒有 unicode,不會因為抽離元件而造成圖示衝突
  • 在低端裝置上 SVG 有更好的清晰度。
  • 支援多色圖示。
  • svg 可以支援動畫

目前流行的元件庫已經都使用了 svg 代理字型圖示,比如 ant-design、Material-UI 等

將參照的 iconfont 轉變為本地 svg

我們可以手動一個一個從 iconfont 圖示庫中下載 svg,但這樣做未免有些過於麻煩。

在 iconfont 字型樣式中,css 包含了這樣一個路徑,或者我們可以在專案 css 中直接找到這段程式碼,然後下載這個 svg。 開啟 svg 會看到如下程式碼

一個 glyph 元素定義了 SVG 字型中的一個獨立的字形,所以我們可以通過一個 node 指令碼將這裡面的獨立字形轉變 svg

直接上程式碼

const cheerio= require("cheerio")
const fs= require("fs")
const path= require("path")
fs.readFile(path.join(__dirname,'./iconfont.svg'), 'utf8', function(err, data) {
    if (err) throw err;
    //console.log(data)
        const $=cheerio.load(data)
        $('glyph').each((index,item)=>{
            const svgStr=`<svg  fill="currentColor" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128">
    <path d="${item.attribs.d}"></path>
</svg>`
        fs.writeFile(path.join(__dirname,`./svg/${item.attribs['glyph-name']}.svg`),svgStr,(err,data)=>{
            if (err) throw err;
        })
    });
});

cheerio 是一個 nodejs 下類似 jquery api, 主要是利用 cheerio 將字串中的 d glyph-name 寫到一個 svg 檔案中。 iconfont 中的字型圖示大家都是 1024 所以,設定viewBox="0 0 1024 1024"

看下效果

這下,可以不用問離職人員要 iconfont 許可權了。

svg 轉為 React Component

在 webpack 中我們可以使用一個 叫 svgr 的 loader,它可以將 SVG 轉換為一個隨時可用的 React 元件。

首先使用 npm 安裝 @svgr/webpack

npm install @svgr/webpack --save-dev

然後在 webpack.config.js 中加入設定

const webpack = require('webpack');
module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
      {
        test: /.svg$/i,
        type: 'asset',
        resourceQuery: /url/, // *.svg?url
      },
      {
        test: /.svg$/i,
        issuer: /.[jt]sx?$/,
        resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
        use: ['@svgr/webpack'],
      },
    ],
  },
}

使用方式

import svg from './assets/file.svg?url'
import Svg from './assets/file.svg'
const App = () => {
  return (
    <div>
      <img src={svg} width="200" height="200" />
      <Svg width="200" height="200" viewBox="0 0 3500 3500" />
    </div>
  )
}

通過使用 ?url 區分是否使用 url 的方式參照。

svgr 官網可以的 palayround 可以實時預覽轉換後的程式碼

我們只需要啟動應用程式,Webpack 就會自動完成轉換任務,再不需要再擔心 SVG 了。你可以將 SVG 檔案放在 src/資料夾中的任何位置,並將它們作為 React 元件匯入使用。

以上就是本文全部內容,希望這篇文章對大家有所幫助,也可以參考我往期的文章或者在評論區交流你的想法和心得,歡迎一起探索前端。

以上就是Iconfont不能上傳如何維護Icon的詳細內容,更多關於Icon維護上傳Iconfont的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com