Railsアセットパイプラインでのフォントの使用


345

私のScssファイルでいくつかのフォントを次のように構成しています:

@font-face {
  font-family: 'Icomoon';
  src: asset-url('icoMoon.eot?#iefix', font) format('embedded-opentype'),
       asset-url('icoMoon.woff', font) format('woff'),
       asset-url('icoMoon.ttf', font)  format('truetype'),
       asset-url('icoMoon.svg#Icomoon', font) format('svg');
}

実際のフォントファイルは/ app / assets / fonts /に保存されています

config.assets.paths << Rails.root.join("app", "assets", "fonts")application.rbファイルに追加しました

コンパイルCSSソースは次のとおりです。

@font-face {
  font-family: 'Icomoon';
  src: url(/assets/icoMoon.eot?#iefix) format("embedded-opentype"), url(/assets/icoMoon.woff) format("woff"), url(/assets/icoMoon.ttf) format("truetype"), url(/assets/icoMoon.svg#Icomoon) format("svg");
}

しかし、アプリを実行すると、フォントファイルが見つかりません。ログ:

2012-06-05 23:21:17 +0100配信されたアセット/icoMoon.ttf-404が見つかりません(13ms)

アセットパイプラインがフォントファイルを/ assetsだけにフラット化しないのはなぜですか?

アイデアはありますか?

敬具、ニール

追加情報:

rails consoleでアセットパスとassetprecompileを確認すると、次のようになります。

1.9.2p320 :001 > y Rails.application.config.assets.precompile
---
- !ruby/object:Proc {}
- !ruby/regexp /(?:\/|\\|\A)application\.(css|js)$/
- .svg
- .eot
- .woff
- .ttf
=> nil



1.9.2p320 :002 > y Rails.application.config.assets.paths
---
- /Users/neiltonge/code/neiltonge/app/assets/fonts
- /Users/neiltonge/code/neiltonge/app/assets/images
- /Users/neiltonge/code/neiltonge/app/assets/javascripts
- /Users/neiltonge/code/neiltonge/app/assets/stylesheets
- /Users/neiltonge/code/neiltonge/vendor/assets/images
- /Users/neiltonge/code/neiltonge/vendor/assets/javascripts
- /Users/neiltonge/code/neiltonge/vendor/assets/stylesheets
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/jquery-rails-2.0.0/vendor/assets/javascripts
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/coffee-rails-3.2.1/lib/assets/javascripts
- /Users/neiltonge/.rvm/gems/ruby-1.9.2-p320@neiltonge/gems/bourbon-1.3.0/app/assets/stylesheets
- !ruby/object:Pathname
  path: /Users/neiltonge/code/neiltonge/app/assets/fonts
 => nil

3
あなたは持っているfont-urlのRailsでSCSSでヘルパーを。
Hauleth

残念ながら、それによる違いはありません。したがって、私の質問はまだ残っています
rctneil

私はこの問題を診断して解決する一般的な方法をstackoverflow.com/a/40898227/1197775に書いた。
サイト

回答:


651
  1. あなたのRailsのバージョンが間にある場合> 3.1.0< 4、これらのフォルダのいずれかであなたのフォントを配置します。

    • app/assets/fonts
    • lib/assets/fonts
    • vendor/assets/fonts


    Railsバージョンの> 4場合、フォントをフォルダーに配置する必要があり app/assets/fontsます。

    注:これらの指定されたフォルダーの外にフォントを配置するには、次の構成を使用します。

    config.assets.precompile << /\.(?:svg|eot|woff|ttf)\z/

    Railsバージョンの> 4.2場合、この構成をに追加することをお勧めしますconfig/initializers/assets.rb

    ただし、config/application.rbまたはに追加することもできますconfig/production.rb

  2. CSSファイルでフォントを宣言します。

    @font-face {
      font-family: 'Icomoon';
      src:url('icomoon.eot');
      src:url('icomoon.eot?#iefix') format('embedded-opentype'),
        url('icomoon.svg#icomoon') format('svg'),
        url('icomoon.woff') format('woff'),
        url('icomoon.ttf') format('truetype');
      font-weight: normal;
      font-style: normal;
    }

    フォントの名前が宣言のURL部分とまったく同じであることを確認してください。大文字と句読点が重要です。この場合、フォントの名前はでなければなりませんicomoon

  3. RailsでSass以下を使用している場合> 3.1.0(CSSファイルに.scssまたは.less拡張子がある)、url(...)フォント宣言のをに変更しfont-url(...)ます。

    それ以外の場合は、CSSファイルに拡張子.css.erbを付け、フォント宣言をにしますurl('<%= asset_path(...) %>')

    Railsを使用している場合は> 3.2.1、のfont_path(...)代わりに使用できますasset_path(...)。このヘルパーはまったく同じことを行いますが、より明確です。

  4. 最後に、font-familyパーツで宣言したようにCSSでフォントを使用します。大文字で宣言されている場合は、次のように使用できます。

    font-family: 'Icomoon';

36
サーバーを再起動しましたか?
愛鷹

9
@NadeemYasinコメントをありがとう、私は同じ問題を抱えていました。ファイル名にはハイフンが含まれており、削除すると、ここで提案されたソリューションが機能しました。
tsega 2013

35
config.assets.precompile += %w( .svg .eot .woff .ttf )実際には間違っています。完全なアセット名と一致するものをプリコンパイルするために追加する必要があります。正規表現は私のために働きました:config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Sunny

2
まあ、それは今私のために機能する方法です。したがって、そのコード行はまったく必要ないか、この構成を設定する方法はRailsのバージョン(またはその他)に依存します。@ジムは、ステップ2で構成を削除する必要があると既に言っていたので、ここで何か不足しているかもしれません。アセットパイプラインでフォントを使用する方が簡単なはずです。
愛鷹2013

3
ステップ2は削除する必要があります。Railsガイドによると、config.assets.pathsはSprocketsの参照用であり、ここでは関係ありません。config.assets.precompileためにも役に立たない「ファイルをコンパイルするためのデフォルトマッチャはapplication.js、application.cssと含まれ、すべての非JS / CSSファイルアプリ/資産フォルダから(これは自動的にすべての画像アセットが含まれます)」(参照ここ
エリック・L.を

38

ここでひねりがあります:

あなたには、すべてのフォントを配置する必要がありapp/assets/fonts/、彼らのようにWILLデフォルト-それらが押されてプリコンパイルされますによってステージングと生産にプリコンパイルますHerokuの

フォントに置かれたファイルvendor/assetsになるしないで、彼らは上で失敗します-デフォルトでは、ステージングまたは生産にプリコンパイルされHerokuのソース!

@ plapier、thoughtbot / bourbon

ベンダーフォントをに入れるvendor/assets/fonts 方が、に入れるよりもずっと意味があると私は強く信じていますapp/assets/fonts。これらの2行の追加構成により、これは私(Rails 4)でうまく機能しました。

app.config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts')  
app.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/

@ jhilden、thoughtbot / bourbon

私もそれをテストしましたrails 4.0.0。実際には、最後の1行で、vendorフォルダーからフォントを安全にプリコンパイルできます。それを理解するのに数時間かかりました。それが誰かを助けることを願っています。


2
+ 1edgeguides.rubyonrails.org/…はアセットパイプラインのレイアウトを説明し、これがどのように機能するかを理解するのに役立ちます。2014年7月4日のように正しい
ザカリーMoshansky

これらの両方が必要ですか?app.config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts') app.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/別の回答についてのコメントは、後者が両方を処理すると言っています。
ahnbizcad 2015

Rails 4.2以降のランドでも、app/assetsスプロケットやフレンドへの入力は出力として処理されると思いますがpublic/assetsvendor/assetsアセットを変更せずにデプロイする場合にも役立ちます。どちらにも用途があります。ベンダリングの規約全体は、何も起こらないことが保証されていることを前提としていvendor/*ます。(はい、vendor/pluginsコード保管、クローズドソースのマニア前宝石時代で悪用され、人々はバージョン管理されていないjsをvendor/assets/javascriptspre-

2
不思議に思う人のために; これを投入config/initializers/assets.rb
TJビドル

23

フォントの移動を追跡したくない場合:

# Adding Webfonts to the Asset Pipeline
config.assets.precompile << Proc.new { |path|
  if path =~ /\.(eot|svg|ttf|woff)\z/
    true
  end
}

1
これが最善の解決策だと思います。フォントを作成しない限り、フォントは/ app / assets / fontsではなく、/ vendor / assets / fontsに属している可能性があります。このアプローチは両方に対して解決しますが、上記は解決しません
Casey

5
@Casey:このソリューションでは、ベンダー/アセット内にフォントを配置できます。@Nathan Colgate:これは次のように簡略化できます。– 2013config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
サニー

@サニー-わかった、だからこそ、受け入れられた答えよりも優れていると思う
ケーシー

2
また、あなたは、\ Zを使用して正規表現を終了する必要が- stackoverflow.com/questions/577653/...
ケーシー

1
Railsがフォントファイルに追加するハッシュをどのように扱いますか?
James McMahon

21

font-url@ font-faceブロックで使用する必要があります。url

@font-face {
font-family: 'Inconsolata';
src:font-url('Inconsolata-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}

あなたが言及したように、application.rbのこの行と同様に( app/assets/fonts

config.assets.paths << Rails.root.join("app", "assets", "fonts")

また、プロダクションのプリコンパイルを有効にする必要があります
ahnbizcad

まったく新しいrails 4.2アプリでは、両方にsrc: url(someFont.ttf)あり、src: font-url(someFont.ttf)ファイルをに持っているときに機能しましたapp/assets/fonts。私が持っている.scssデフォルトでは拡張子を。config.assets.pathsに追加する必要はありませんでした。
ダニー

9

ここで、アセットパイプラインでフォントを使用するための私のアプローチ:

1)すべてのフォントファイルをの下app/assets/fonts/に配置しfontsます。実際には、フォルダー名の下に配置することに制限はありません。任意のサブフォルダ名を付けることができます。例:app/assets/abcまたはapp/assets/anotherfonts。しかし、私はあなたがapp/assets/fonts/より良いフォルダ構造のためにそれを置くことを強くお勧めします。

2)あなたのsassファイルから、sassヘルパーfont-pathを使用してこのようなフォントアセットをリクエストします

@font-face {
    font-family: 'FontAwesome';
    src: url(font-path('fontawesome-webfont.eot') + '?v=4.4.0');
    src: url(font-path('fontawesome-webfont.eot') + '?#iefix&v=4.4.0') format('embedded-opentype'),
         url(font-path('fontawesome-webfont.woff2') + '?v=4.4.0') format('woff2'),
         url(font-path('fontawesome-webfont.woff') + '?v=4.4.0') format('woff'),
         url(font-path('fontawesome-webfont.ttf') + '?v=4.4.0') format('truetype'),
         url(font-path('fontawesome-webfont.svg') + '?v=4.4.0#fontawesomeregular') format('svg');
    font-weight: normal;
    font-style: normal;
}

3)bundle exec rake assets:precompileローカルマシンから実行し、application.cssの結果を確認します。次のようなものが表示されます。

@font-face {
    font-family: 'FontAwesome';
    src: url("/assets/fontawesome-webfont-d4f5a99224154f2a808e42a441ddc9248ffe78b7a4083684ce159270b30b912a.eot" "?v=4.4.0");
    src: url("/assets/fontawesome-webfont-d4f5a99224154f2a808e42a441ddc9248ffe78b7a4083684ce159270b30b912a.eot" "?#iefix&v=4.4.0") format("embedded-opentype"), url("/assets/fontawesome-webfont-3c4a1bb7ce3234407184f0d80cc4dec075e4ad616b44dcc5778e1cfb1bc24019.woff2" "?v=4.4.0") format("woff2"), url("/assets/fontawesome-webfont-a7c7e4930090e038a280fd61d88f0dc03dad4aeaedbd8c9be3dd9aa4c3b6f8d1.woff" "?v=4.4.0") format("woff"), url("/assets/fontawesome-webfont-1b7f3de49d68b01f415574ebb82e6110a1d09cda2071ad8451bdb5124131a292.ttf" "?v=4.4.0") format("truetype"), url("/assets/fontawesome-webfont-7414288c272f6cc10304aa18e89bf24fb30f40afd644623f425c2c3d71fbe06a.svg" "?v=4.4.0#fontawesomeregular") format("svg");
    font-weight: normal;
    font-style: normal;
}

アセットパイプラインのしくみについて詳しく知りたい場合は、次のシンプルなガイドにアクセスしてください。https//designcode.commandrun.com/rails-asset-pipeline-simple-guide-830e2e666f6c#.6lejlayk2


5

Rails 4.2(ruby 2.2.3を使用)でこの問題が発生し、font-awesome _paths.scssパーシャルを編集して$fa-font-path、先頭のスラッシュへの参照を削除し、先頭のスラッシュを削除する必要がありました。以下が壊れていました:

@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');
  font-weight: normal;
  font-style: normal;
}

そして次の作品:

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

別の方法としては、補間さ$fa-font-pathれた後のスラッシュを削除$fa-font-pathし、空の文字列または(必要に応じて)スラッシュが続くサブディレクトリとして定義します。

アセットを再コンパイルし、必要に応じてサーバーを再起動することを忘れないでください。たとえば、乗客のセットアップでは:

prompt> rake assets:clean; rake assets:clobber
prompt> RAILS_ENV=production RAILS_GROUPS=assets rake assets:precompile
prompt> service passenger restart

次に、ブラウザをリロードします。


5

Rails 4.2を使用していますが、フッタブルアイコンを表示できませんでした。折りたたまれた行の(+)と小さな期待どおりの並べ替え矢印の代わりに、小さなボックスが表示されていました。ここで情報を検討した後、コードに1つの簡単な変更を加えました。CSSのフォントディレクトリを削除します。つまり、次のようにすべてのcssエントリを変更します。

src:url('fonts/footable.eot');

このように見えるように:

src:url('footable.eot');

動いた。Rails 4.2はすでにフォントディレクトリを想定しているので、cssコードで再度指定すると、フォントファイルが見つかりません。お役に立てれば。


3

最近、Rails 3アプリをRails 4にアップグレードしたときに、同様の問題が発生しました。私のフォントはRails 4+のように適切に機能していませんでしたapp/assets/fonts。フォントをディレクトリに保存することのみが許可されています。しかし、私のRails 3アプリのフォント構成は異なりました。ですから、Rails 4以降でもフォントが以外の場所にある場合でも機能するようにアプリを構成する必要がありましたapp/assets/fonts。私はいくつかの解決策を試しましたが、愚かではないダイジェストアセットの gem を見つけた後、それがとても簡単になりました。

次の行をGemfileに追加して、このgemを追加します。

gem 'non-stupid-digest-assets'

次に実行します:

bundle install

最後に、config / initializers / non_digest_assets.rbファイルに次の行を追加します。

NonStupidDigestAssets.whitelist = [ /\.(?:svg|eot|woff|ttf)$/ ]

それでおしまい。これは私の問題をうまく解決しました。これが私のような同様の問題に遭遇した人を助けることを願っています。


3

これは、Herokuで動作するRails 5.2でカスタムフォントを提供する方法を示すレポです。さらに進んで、https://www.webpagetest.org/に従って、フォントの提供を可能な限り高速に最適化します

https://github.com/nzoschke/edgecors

はじめに、上記の回答から作品を選びました。Rails 5.2以降の場合、追加のアセットパイプライン構成は必要ありません。

アセットパイプラインとSCSS

  • フォントを配置する app/assets/fonts
  • 置き@font-faceSCSSファイルで宣言をし、使用してfont-urlヘルパーを

からapp/assets/stylesheets/welcome.scss

@font-face {
  font-family: 'Inconsolata';
  src: font-url('Inconsolata-Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}

body {
  font-family: "Inconsolata";
  font-weight: bold;
}

CORSを使用してCDNから提供する

私はHeroku Edgeアドオンで追加されたCloudFrontを使用しています。

最初に、CDNプレフィックスとデフォルトCache-Controlヘッダーを構成しますproduction.rb

Rails.application.configure do
  # e.g. https://d1unsc88mkka3m.cloudfront.net
  config.action_controller.asset_host = ENV["EDGE_URL"]

  config.public_file_server.headers = {
    'Cache-Control' => 'public, max-age=31536000'
  }
end

herokuapp.com URLからCDN URLにフォントにアクセスしようとすると、ブラウザーでCORSエラーが発生します。

「でのフォントへのアクセスhttps://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf」原点から「https://edgecors.herokuapp.com」がCORSポリシーによってブロックされました:いいえ「アクセス制御-許可します-Origin 'ヘッダーが要求されたリソースに存在します。edgecors.herokuapp.com/ GET https://d1unsc88mkka3m.cloudfront.net/assets/Inconsolata-Regular.ttf net :: ERR_FAILED

したがって、HerokuからCDN URLへのフォントへのアクセスを許可するようにCORSを構成します。

module EdgeCors
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    config.middleware.insert_after ActionDispatch::Static, Rack::Deflater

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins %w[
          http://edgecors.herokuapp.com
          https://edgecors.herokuapp.com
        ]
        resource "*", headers: :any, methods: [:get, :post, :options]
      end
    end
  end
end

gzipフォントアセットの提供

アセットパイプラインは.ttf.gzファイルを作成しますが、提供しません。このモンキーパッチは、アセットパイプラインのgzipホワイトリストをブラックリストに変更します。

require 'action_dispatch/middleware/static'

ActionDispatch::FileHandler.class_eval do
  private

    def gzip_file_path(path)
      return false if ['image/png', 'image/jpeg', 'image/gif'].include? content_type(path)
      gzip_path = "#{path}.gz"
      if File.exist?(File.join(@root, ::Rack::Utils.unescape_path(gzip_path)))
        gzip_path
      else
        false
      end
    end
end

最終的な結果は、app/assets/fonts長期間有効なCloudFrontキャッシュから提供されるカスタムフォントファイルです。


2

私の場合、元の質問はasset-url単純なurlcssプロパティの代わりに結果なしで使用していました。asset-url結局、Herokuで使用することになりました。さらに、/assets/fontsフォルダーにフォントを設定し、asset-url('font.eot')サブフォルダーやその他の構成を追加せずに呼び出します。


1

scaffolds.css.scssというファイルがある場合、他のファイルで実行しているすべてのカスタム処理を上書きする可能性があります。そのファイルをコメントアウトしたところ、突然すべてが機能しました。そのファイルに重要なものがない場合は、単に削除することもできます!


-7

app / assets / fontsフォルダー内にフォントを配置し、アプリがapplication.rbにコードの記述を使用するときにオートロードパスを設定します

config.assets.paths << Rails.root.join( "app"、 "assets"、 "fonts") および

次に、CSSで次のコードを使用します。

@ font-face {

 font-family: 'icomoon';
 src: asset-url('icomoon.eot');
 src: asset-url('icomoon.eot') format('embedded-opentype'),
      asset-url('icomoon.woff') format('woff'),
      asset-url('icomoon.ttf') format('truetype'),
      asset-url('icomoon.svg') format('svg');
 font-weight: normal;
 font-style: normal;

}

試してみる。

ありがとう


これは既存の回答にどのように追加されますか?
cimmanon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.