Конвейер ресурсов Rails, работающий со шрифтами и пряжей

У меня есть существующее приложение rails, в котором я работаю над отдельной ветвью для реализации yarn для управления активами поставщиков. Мой стек приложений:

  • рубин-2.4.0
  • рельсы 5.1.4
  • узел 9.4.0
  • пряжа 1.3.2

После установки пряжи я запустил yarn init, и он сгенерировал package.json в корне проекта. После добавления нескольких пакетов это выглядит так:

# 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 пару файлов для включения таблиц стилей и javascripts из 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).

При отладке в инспекторе сети файл assets/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0 не найден, так как он был предварительно скомпилирован, а не просто скопирован в:

общественность/активы/шрифт-awesome/шрифты/fontawesome-webfont-[хэш].ttf

Я понимаю, почему я сталкиваюсь с этой ситуацией (которая очень похожа на этот оставшийся без ответа вопрос двухмесячной давности).

Я ищу чистое решение или умный обходной путь (например, создать промежуточное программное обеспечение для перенаправления простого запроса .ttf в хешированную версию жалобы на рельсы и кэшировать ответ на x часов. У вас есть какие-либо предложения?


person mabe02    schedule 01.02.2018    source источник
comment
Одной из возможностей может быть переопределение @font-face в отдельном файле, как предлагается здесь github.com/ rails/rails/issues/31266#issuecomment-347652737, но это все еще выглядит тяжелым обходным путем   -  person mabe02    schedule 02.02.2018


Ответы (2)


Думаю, я нашел самое чистое решение после нескольких попыток:

Попытка 1: Sass и перезапись каталогов шрифтов

Я сделал довольно обширный рефакторинг модулей sass в каталоге app/assets/stylesheets. Вот пара примеров:

Для шрифтов

// 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 была предварительно скомпилирована. На самом деле все скрипты node cli имели некоторые проблемы с синтаксисом для Ugflifier.

Попытка 2. Установите Webpack и создайте файл app/javascripts/pack/application.sass.

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

Я все еще сталкивался с некоторыми проблемами с относительными путями. Я нашел решение в документации webpacker, добавив в свой config/webpacker/environment.js следующий загрузчик:

// 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 по умолчанию, и это было очень просто:

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

Это компилируется в связанный файл styles.css без необходимости в каком-либо дополнительном загрузчике.

Мне потребовалось довольно много времени, чтобы понять это, и я надеюсь, что это будет полезно и вам!

person mabe02    schedule 09.02.2018
comment
Я переопределяю @font-face, определенный в font-awesome. посмотри мой ответ - person Max Ivak; 13.03.2018

Я заставил это работать, переопределив пути шрифтов.

приложение.scss:

$fa-font-path:"font-awesome/fonts";

@import 'font-awesome/scss/font-awesome';

@font-face {
  font-family: 'FontAwesome';
  src: font-url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
  src: font-url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
  font-url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
  font-url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
  font-url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
  font-url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
  //  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
  font-weight: normal;
  font-style: normal;
}

Запустите rake assets:precompile, и вы должны увидеть файлы шрифтов в public/assets/font-awesome/fonts с переваренными именами файлов.

Скомпилированный CSS должен получить доступ к файлам шрифтов из ресурсов Rails:

@font-face{
   font-family:'FontAwesome';
   src:url(/assets/font-awesome/fonts/fontawesome-webfont-7bfcab6db99...979.eot?v=4.7.0)
person Max Ivak    schedule 09.03.2018
comment
У меня это работает с небольшим изменением. @Max Ivak добавил первый блок в application.scss, но я поместил этот блок кода в web/app/assets/stylesheets/font-awesome.scss, а затем мой web/app/assets/stylesheets/application.css получил строку *= require font-awesome. - person Pete; 20.06.2018