Rails 有段时间没写 Rails,看着 7 出了,自己试了试,引入 Font-awesome 遇到点问题。

wdrsam · 2022年05月31日 · 最后由 Rei 回复于 2022年06月03日 · 1026 次阅读

有段时间没写 Rails,看着 7 都出了,自己试了试,遇到点问题。

{
  "name": "app",
  "private": "true",
  "dependencies": {
    "@fortawesome/fontawesome-free": "^6.1.1",
    "@hotwired/stimulus": "^3.0.1",
    "@hotwired/turbo-rails": "^7.1.3",
    "@popperjs/core": "^2.11.5",
    "bootstrap": "^5.1.3",
    "bootstrap-icons": "^1.8.3",
    "esbuild": "^0.14.42",
    "sass": "^1.52.1",
    "sortable": "^2.0.0"
  },
  "scripts": {
    "build:css": "sass app/assets/stylesheets/application.scss app/assets/builds/application.css --no-source-map --load-path=node_modules",
    "build": "esbuild app/javascript/application.js --bundle --outdir=app/assets/builds"
  }
}

application.scss 里 @import '@fortawesome/fontawesome-free/css/all';

在 builds 里也确确实实看到样式被编译进去,但 Web 上并不生效。用 CDN 的话就没问题。应该是我字体没引入的原因吧?应该把字体引入进去呢?

也许:

gem "font-awesome-rails", "~> 4.7"
# or
gem "font_awesome5_rails", "~> 1.5"

用 gem 的方法更简单。

不过,感觉没必要,引入整个 css,这么大的文件,就为了几个 icon?,还不如直接用 helper 吧。

把这个 https://github.com/FortAwesome/Font-Awesome 用 helper 包装一下吧。

类似这个:

<%= fa6_icon("brands-alipay") %>
<%= fa6_icon("regular-bell") %>
<%= fa6_icon("solid-anchor") %>
<%= fa6_icon("brands-alipay", title: "font awesome icon") %>
<%= fa6_icon("brands-alipay", title: "font awesome icon", size: 30) %>
<%= fa6_icon("brands-alipay", title: "font awesome icon", class: "text-grey-500") %>
<%= fa6_icon("brands-alipay", class: "text-red-500", aria: { label: "user-icon" }) %>
xianyuit 回复

Gem 的方式我试过。仍然没有正常输出我想要的。 而且,通过 Gemfile 的方式,我没法在 application.scss 里 import,

 Error: Can't find stylesheet to import.
12:41:58 css.1  |   ╷
12:41:58 css.1  | 4 │ @import "font-awesome";
12:41:58 css.1  |   │         ^^^^^^^^^^^^^^
12:41:58 css.1  |   ╵
12:41:58 css.1  |   app/assets/stylesheets/application.scss 4:9  root stylesheet

helper 方法的输出内容是没问题的。

感觉你还不太懂 assets pipeline 的,你用了 sass 静态文件的方式肯定用不了呀,

你去 layout 里:

<%= stylesheet_link_tag "admin", "data-turbo-track": "reload" %>

然后再创建个 admin.css

在里面去 import

xianyuit 回复

我的 application.scss 里是引入了 @import 'bootstrap/scss/bootstrap'; @import 'bootstrap-icons/font/bootstrap-icons'; 这两个,bootstrap 样式和 icons 都能正常使用。

而且我按你说的试了下,还是不行。我加了个 custom.css,并且在 manifest.js 里也引入了

/= link custom.css

build 的时候也没有任何报错,但就是没有显示对应的 icon。

我看了下 builds 里的 css,像 fa-flip 这种 class 的样式,它都是编译好进去了的。但就是没生效,也没任何报错呢?

我是新起的项目,带的参数是 css=bootstrap

wdrsam 回复

layout 里要处理,引入 custom.css

<%= stylesheet_link_tag "custom", "data-turbo-track": "reload" %>

xianyuit 回复

我用了 2 种方式尝试

  1. yarn add @fortawesome/fontawesome-free
  2. Gemfile 里添加 gem "font-awesome-rails"

  3. 如我上面所说,添加后,Rails 也将 node_modules 里的内容 build 好放到了 builds 里的 application.css 里,能够搜到相关的 css。但样式在页面上始终不生效。我用同样的方式添加了 bootstrap 和 bootstrap-icon,css 和 icon 都是生效的。

  4. 用 Gem 的方式通过静态文件引入。layouts 里 <%= stylesheet_link_tag "custom", "data-turbo-track": "reload" %>

manifest.js 里 //= link_tree ../builds //= link custom.css

custom.css 里 @import "font-awesome";

1 和 2 尝试,都没有报错,文件都正常 build。

其中 2 里面,网页代码里里我也看到了有 且 source 里的 assets 也有 4 项

application.js application.css custom.css fontawesome

其中 fontawesome 里有内容 /*!

但就是没有看到对应的字体样式。。。

7 楼 已删除
xianyuit 回复

谢谢,确实这样可以解决这个问题。只是我有点不明白我 1 和 2 的做法不成功的原因到底是啥,字体没有引入么。。。我只想的到这一个原因了

编辑:行不通,看 18 楼。


因为 sass 不处理引用的资源(字体或者图片),这还需要 assets pipeline 处理。

如果 assets pipeline 用的是 sprocket,那么可以在 manifest.js 里面添加设置:

//= link_tree ../../../node_modules/@fortawesome/fontawesome-free/webfonts

注意这个路径是否匹配你的安装路径。设置这个后,sprocket 会把这个 webfonts 目录下的资源加入 pipeline,并且替换 css 里面用 url() 引用的资源地址(加上 digest)。

如果还有问题可以参考这个 issue https://github.com/rails/cssbundling-rails/issues/22#issuecomment-1030735501

Rei 回复

编辑:行不通,看 18 楼。


我看了下 fontawesome 的源码,也许要加上 fa-font-path 变量,从 scss 编译。

因为 fa-font-path 默认是相对路径 '../webfonts',上面的 link_tree 已经进入了 webfonts 这个目录。

$fa-font-path: '';

// You probably already include the core styles
@import "./fontawesome/scss/fontawesome.scss";

// For Duotones you need both of these files
@import "./fontawesome/scss/duotone.scss";
@import "./fontawesome/scss/_duotone-icons.scss";

// You can include all the other styles the same as before
@import "./fontawesome/scss/solid.scss";
@import "./fontawesome/scss/brands.scss";
wdrsam 回复

1 和 2 的方法,如果你要用 rails 的方式 assets pipeline 的话,把 Rails.application.config.assets.paths << Rails.root.join("node_modules") 添加到 config/initializers/assets.rb 里,然后去 import 那些静态文件

wdrsam 回复

最终还是建议别引入字体文件了,太鸡儿大了,就为了用几个 icon。。

14 楼 已删除

yarn add 后,在 application.js 里引入 import "@fortawesome/fontawesome-free/css/all" 就可以了。

wdrsam 关闭了讨论。 06月02日 08:59
wdrsam 重新开启了讨论。 06月02日 08:59

验证过的方法:

在 config/initializers/assets.rb 加入:

Rails.application.config.assets.paths << Rails.root.join('node_modules/@fortawesome/fontawesome-free/webfonts')

在 application.sass.scss 加入:

$fa-font-path: ".";

@import "@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "@fortawesome/fontawesome-free/scss/solid.scss";

其他不用改,包括 manifest.json。

Rei 回复

恩,我就是加到 assets 里就可以了。只是我觉得那些 gem,或者是用 svg 也可以。

Rei 回复

确实这样就可以了。😃 😃 😃

Rei 回复

写了一篇日志记录解决的原理 https://geeknote.net/Rei/posts/1222

需要 登录 后方可回复, 如果你还没有账号请 注册新账号