动态配置项目中的icon-font字体

116 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

动态生成iconfont的最新代码

为什么要做动态生成

很多公司会在iconfont上面创建项目。
维护自己公司项目中用到的字体图标。并不断的更新。
有的项目里面,项目名字会做特殊的处理。不会直接使用iconfont下载下来的文件。
如果每次iconfont变更。都需要开发去手动变更本地的代码的话。
维护成本就会变得很高。也会容易出错。

在iconfont项目的fontClass里有一个动态连接。但是链接不是固定的。
当在项目中编辑icon,链接就会变更。

在iconfont开源仓库的Issuse中也有相关的讨论。
有兴趣的同学可以移步查看

首先cdn地址不变肯定是不靠谱的:
首先缓存问题是个绕不过去的坎。 而且万一这个项目已经在线上使用了,你这突然更新下css,线上就出问题了。
所以 每次更新图标肯定得是新地址。 至于转发代理的问题,是这样的,我们不适合做。 如果用css,那么还是有缓存的问题 如果用js,那么你需要用js动态去请求一个接口返回当前最新的样式。这个接口不是cdn,如果我们开了影响太大。再有就是还得做好,线上线下的版本,得去配置,不能影响线上。总之是个很复杂的事情。
所以综上所属,还是每次更改图标修改下引用比较靠谱。 = =。

自己动手丰衣足食,花费半天时间来做一个动态生成iconfont的小工具。从此摆脱手动修改。

动态生成iconfont代码的工具详解

  • 首先在package.json中scripts中添加以下命令。
    "gen:font": "node ./build/index.js"
  • 在根目录创建build目录。build目录下创建index.js
  • 在项目中安装以下依赖包。注意inquirer和slash的版本。
    "inquirer": "^8.2.5",
    "npmlog": "^7.0.1",
    "request": "^2.88.2",
    "slash": "^3.0.0"
  • 使用inquirer来实现命令模板的交互。

让用户手动输入iconfont的连接。连接拷贝方式见下图。 image.png

让用户手动输入iconfont的前缀。包括本地字体图标文件的名字。每个class的前缀。

inquirer
  .prompt([
    {
      type: 'input',
      name: 'question',
      message: 'Please input the iconFont link',
    },
    {
      type: 'input',
      name: 'iconName',
      message: 'Please input the iconFont name',
    },
  ])
  .then((answers) => {
    IconName = answers.iconName || IconName
    handleCssLink(answers)
  })
  .catch((error) => {
    console.log(error)
  })
  • 通过http.get的方式获取用户输入的css连接里面的内容。
function handleCssLink({ question }) {
  checkoutValid(question)
  question = /^https{0,1}:\/\//.test(question) ? question : 'http:' + question
  http.get(question, (res) => {
    res.setEncoding('utf8')
    var Data = ''
    res
      .on('data', function (data) {
        Data += data
      })
      .on('end', function () {
        handleCssData(Data)
        handleFontFile(Data)
      })
  })
}
  • 根据拿到的css内容替换css里面的前缀。
  • 根据拿到的css内容里面的字体文件地址。下载字体文件输出到指定的目录。并修改字体文件的文件名。
function handleCssData(Data) {
  let str
  str = Data.replace(/font-family: "iconfont"/g, `font-family:${IconName}`)
    .replace('.iconfont', `.${IconName}`)
    .replace(/\.icon-/g, `.${IconName}-`)
    .replace(/\/\/at\.alicdn\.com.*font_.*\./, `./fonts/${IconName}.`)
    .replace(/\/\/at\.alicdn\.com.*font_.*\./, `./fonts/${IconName}.`)
    .replace(/\/\/at\.alicdn\.com.*font_.*\./, `./fonts/${IconName}.`)
  execChmod(moveToPath)
  fs.writeFile(moveToPath, str, function (error) {
    if (error) {
      throw error
    }
    log.success('dynamic-iconfont', '拷贝css文件成功')
  })
}

  • 注意本地文件可能没有读写权限。需要手动给目录权限
function execChmod(path) {
  const execFilter = path.replace(/(.*)\/{1}.*$/, '$1')
  const execPath = `sudo chmod 777 ${execFilter}`
  execSync(execPath)
}

以下是使用过程交互命令和输入。因为涉及到改写目录的读写。会要求输入电脑的密码。按照提示输入密码回车即可。

image.png

试用说明

如果你也遇到和我一样的问题。可以直接异步git项目。点这里跳转dynamic-iconfont项目github地址

如果本文对你有用。欢迎点赞收藏~ 也可以在评论区留下你的脚印。

今天就到这里了 👋🏻👋🏻👋🏻