稍微折腾了一下 FontAwesome
By: Luke Fan
Tags: Frontend

作为一个将编程作为业余爱好的老程序员，折腾一下前端技术，实在是比较痛苦的过程。

前几天尝试着将老版本的ruby on rails程序升级上来的过程中学习了一下webpack和react。

然后就尝试着将jquery和bootstrap搞进去。于是参照了：@syutran 的 [新手问题 rails 6 boostrap 尝鲜](https://ruby-china.org/topics/38992) 中的代码。

唯一差别的是，将NavBar的部分，搞到了一个react的组件中，这个过程中需要将所有的class=替换成了className=，将tabindex替换成了tabIndex。没有问题。

后来发现里面有个问题，就是fontawesome的引用出错了，文档中也说了这个没搞明白，于是我就自己试验了一下。

这种字体图标，一共尝试了三种方式：

1、 直接从 [FontAwesome官网](https://fontawesome.com/)上注册，然后生成了一共kit的链接，在app/views/layouts/application.html.erb中做引用

可以直接通过<i>标记引用各种图标了

这种方式据说是最快的（有cdn在工作），不过好像免费方式的调用次数是有限制的，具体没看

2、 通过[font-awesome-sass](https://github.com/FortAwesome/font-awesome-sass) 这个gem来实现。

先在Gemfile中添加

```rb

gem ‘font-awesome-sass’, ‘~> 5.15.1’

```

做bundle install

然后修改app/assets/stylesheets/application.css

先将其改名为application.css.scss

然后添加

```rb

@import “font-awesome-sprockets”;

@import “font-awesome”;

```

<i>就可以工作了。

而且还可以通过icon这个函数，直接在erb文件中输出图标。

```rb

<%= icon(‘fas’, ‘flag’) %>

```

不过这个方法有一个讨厌的地方，也是最后我舍弃了这种方式的主要原因。

我将代码：

```rb

@import “font-awesome-sprockets”;

@import “font-awesome”;

```

添加到了app/javascript/styles/application.scss中，然后再/app/javascript/packs/application.js中引用

```js

import “../styles/application”

```

会报错，font-awesome-sprockets文件找不到，<i>也不工作。为了后面所有的前端代码都放在统一的地方app/assets里面不再添加代码，这种方式被舍弃了。

3、 使用[react-fontawesome](https://github.com/FortAwesome/react-fontawesome)

首先先读[官方文档](https://fontawesome.com/how-to-use/on-the-web/using-with/react)

作为免费用户，先添加各种免费库

```rb

yarn add @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-fontawesome

yarn add @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons

```

然后就是在React中直接用组件来显示图标，这个过程中有一个比较麻烦的就是任何图标在调用之前，先要去做import。

```js

import ReactDOM from ‘react-dom’

import { FontAwesomeIcon } from ‘@fortawesome/react-fontawesome’

import { faCoffee } from ‘@fortawesome/free-solid-svg-icons’

const element = <FontAwesomeIcon icon={faCoffee} />

ReactDOM.render(element, document.body)

```

稍微简单一点儿的方法是，先引用一堆，并加入到一个库中，然后再在不同的组件中调用

注册：

```js

import ReactDOM from ‘react-dom’

import { library } from ‘@fortawesome/fontawesome-svg-core’

import { fab } from ‘@fortawesome/free-brands-svg-icons’

import { faCheckSquare, faCoffee } from ‘@fortawesome/free-solid-svg-icons’

library.add(fab, faCheckSquare, faCoffee)

```

调用：

```js

import React from ‘react’

import { FontAwesomeIcon } from ‘@fortawesome/react-fontawesome’

export const Beverage = () => (

<div>

<FontAwesomeIcon icon=”check-square” />

Your <FontAwesomeIcon icon=”coffee” /> is hot and ready!

</div>

)

```

调用

```js

import React from ‘react’

import { FontAwesomeIcon } from ‘@fortawesome/react-fontawesome’

export const Showcase = () => (

<div>

<FontAwesomeIcon icon={[‘fab’, ‘apple’]} />

<FontAwesomeIcon icon={[‘fab’, ‘microsoft’]} />

<FontAwesomeIcon icon={[‘fab’, ‘google’]} />

<FontAwesomeIcon icon=”check-square” />

With Coffee Checked, these companies always know their coffee is hot and ready!

</div>

)

```

前面引用并加入到library中的fab是品牌图标库中的所有fab图标。引用一次之后，就都可以调用了。

这里面引用的格式我自己也有点儿晕，如果是直接import进来的图标，

比如 import { faCoffee } from ‘@fortawesome/free-solid-svg-icons’ ，那么调用的时候最好用 <FontAwesomeIcon icon={faCoffee} />

如果是在library里面add过的，直接用 <FontAwesomeIcon icon=”coffee” />也是可以的。

如果是一次引入了一堆的那种情况，则需要用<FontAwesomeIcon icon={[‘fab’, ‘apple’]} />来调用。

这里面还有一个问题，加载了这种方式之后，<i>是不工作的。

需要再加上一段代码：

```js

import { dom } from ‘@fortawesome/fontawesome-svg-core’

dom.watch()

```

才可以让<i>工作起来。不过我没太搞清楚这个代码的作用域是什么样的。并不是每次都灵。

最终，因为想要用新的rails6。各种前端的东西，准备交给react来搞定，所以选择了react-fontawesome的方式。

顺便说一下，我的react并不是直接上来就

```js

document.addEventListener(‘DOMContentLoaded’, () => {

ReactDOM.render(

<Hello name=”React” />,

document.body.appendChild(document.createElement(‘div’)),

)

})

```

生猛开干的。

而是使用了rails_react的gem包，然后在erb文件中写<%=react_component(“ComponentName”) %>的方式来搞的。

这种方式好像还可以服务端渲染，但是具体能够有什么差异，我也没太搞明白。