使用字体和纱线的Rails资产管道 [英] Rails asset pipeline working with fonts and yarn

查看:73
本文介绍了使用字体和纱线的Rails资产管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个现有的rails应用程序,正在其中一个单独的分支上实施yarn来管理供应商资产.我的应用程序堆栈是:

I have an existing rails application where I am working on a separate branch to implement yarn for managing my vendor assets. My app stack is:

  • ruby​​-2.4.0
  • 导轨5.1.4
  • 节点9.4.0
  • 纱线1.3.2

安装yarn之后,我运行yarn init,它在项目根目录中生成了package.json.添加一些软件包后,它看起来像:

After installing yarn, I ran yarn init and it generated a package.json in the project root. After a few packages added, it looks like:

# package.json

{
  "name": "my-project-name",
  "version": "1.0.0",
  "private": true,
  "repository": "my-repo",
  "author": "me",
  "license": "MIT",
  "dependencies": {
    "bootstrap": "3",
    "font-awesome": "^4.7.0",
    "jquery": "^3.3.1",
    "jquery-backstretch": "^2.1.16",
    "jquery-ujs": "^1.2.2",
    "waypoints": "^4.0.1"
  }
}

我在app/assets下创建了两个文件,用于包含node_modules中的样式表和javascript:

I created under app/assets a couple of files for including stylesheets and javascripts from node_modules:

# app/assets/javascripts/node_modules.js
//= require jquery
//= require jquery-ujs
//= require bootstrap/dist/js/bootstrap.min.js
//= require waypoints
//= require jquery-backstretch

# app/assets/stylesheets/font_path_overwrite.scss
$fa-font-path: "font-awesome/fonts/";

# app/assets/stylesheets/node_modules.css.scss
/*
 *= require bootstrap/dist/css/bootstrap.min.css
 *= require font_path_overwrite
 *= require font-awesome/scss/font-awesome
*/

我也更改了:

# config/initializers/assets.rb
# ...
Rails.application.config.assets.paths << Rails.root.join('node_modules')

Rails.application.config.assets.precompile += %w(*.js *.scss)
Rails.application.config.assets.precompile += %w(*.png *.woff2 *.woff *.ttf *.eot *.jpg *.gif *.svg *.ico)

# Rakefile
# ...
Rake::Task['assets:precompile'].enhance [:js_deps_install]
task :js_deps_install do
  sh 'yarn install'
end

根据 SO-43170792 ,我添加了新的

heroku buildpacks:set heroku/ruby
heroku buildpacks:add --index 1 heroku/nodejs

在我的临时环境中,我部署了这些更改,然后突然意识到奇怪的事情正在发生我的资产预编译node_modules/文件夹:虽然对于js和css文件来说一切似乎都可以正常工作,但是我在字体(尤其是font-awesome的字体)方面遇到了一些问题.

In my staging environment I deployed these changes and I suddenly realized that something strange is happening with my assets precompilation node_modules/ folder: whilst everything seems to work fine for js and css files, I am having some issues with fonts (especially font-awesome's fonts).

在网络检查器中调试文件assets/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0,因为该文件已被预编译并且并非仅复制到其中:

Debugging in the network inspector the file assets/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0 is not found since it was precompiled and not just copied into:

public/assets/font-awesome/fonts/fontawesome-webfont- [hash] .ttf

public/assets/font-awesome/fonts/fontawesome-webfont-[hash].ttf

我了解为什么会遇到这种情况(这与

I understand why I am facing this situation (which is very similar to this unaswered question from two months ago).

我正在寻找一个干净的解决方案或明智的解决方法(例如,创建一个中间件以将普通的.ttf请求重定向到Rails投诉哈希版本,并将答案缓存x个小时.您有什么建议吗?

I am looking for a clean solution or smart workaround (e.g. create a middleware to redirect the plain .ttf request to the rails complaint hashed version and cache the answer for x hours. Would you have any suggestion?

推荐答案

我猜经过几次尝试,我找到了最干净的解决方案:

I guess I found the cleanest solution after a few attempts:

尝试1:Sass和覆盖字体目录

我在app/assets/stylesheets目录中对sass模块进行了相当广泛的重构.这里有几个例子:

I did a pretty extensive refactoring of sass modules in app/assets/stylesheets directory. Here a couple of examples:

对于字体

// sass_font_awesome.scss
$fa-font-path: "font-awesome/fonts";
@import 'font-awesome/scss/font-awesome';
@font-face {
  font-family: 'FontAwesome';
  src: asset-url('#{$fa-font-path}/fontawesome-webfont.eot');
  src: asset-url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix') format('embedded-opentype'),
    asset-url('#{$fa-font-path}/fontawesome-webfont.woff2') format('woff2'),
    asset-url('#{$fa-font-path}/fontawesome-webfont.woff') format('woff'),
    asset-url('#{$fa-font-path}/fontawesome-webfont.ttf') format('truetype'),
    asset-url('#{$fa-font-path}/fontawesome-webfont.svg?#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

对于图像

// sass_multiselect.scss
$ms-img-path: 'multiselect/js/img';
@import 'multiselect/css/multi-select';
.ms-container{
  background: transparent asset-url('#{$ms-img-path}/switch.png') no-repeat 50% 50%;
  width: 370px;
}

当预编译node_modules文件夹时,这种方法仍然无效.实际上,所有节点cli脚本在Ugflifier的语法方面都有一些问题.

This approach was still breaking when node_modules folder was precompiled. Actually all the node cli scripts had some issues in terms of syntax for Ugflifier.

尝试2:安装Webpack并创建一个app/javascripts/pack/application.sass

@import '~font-awesome/scss/font-awesome'
@import '~multiselect/css/multi-select'

相对路径仍然存在一些问题.我在 webpacker文档中找到了解决方案,并将其添加到我的以下加载程序:

I was still facing some issues with relative paths. I found the solution in webpacker documentation adding to my config/webpacker/environment.js the following loader:

// webpack/environment.js
const { environment } = require('@rails/webpacker')

// resolve-url-loader must be used before sass-loader
environment.loaders.get('sass').use.splice(-1, 0, {
  loader: 'resolve-url-loader',
  options: {
    attempts: 1
  }
});

解决方案:最简单的方法

我终于发现了webpacker gem的默认行为,这非常简单:

I finally found out the default behaviour of webpacker gem and it was very easy:

// app/javascripts/packs/styles.js
import 'font-awesome/scss/font-awesome.scss';
import 'multiselect/css/multi-select.css';

这可以编译为捆绑的styles.css,而无需任何其他加载程序.

This compile to a bundled styles.css without needing any additional loader.

我花了很多时间弄清楚它,希望对您也有帮助!

It took me quite a lot time to figure it out and I hope it will be helpful to you too!

这篇关于使用字体和纱线的Rails资产管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆