Heroku字体资产不起作用
Posted
技术标签:
【中文标题】Heroku字体资产不起作用【英文标题】:Heroku font assets not working 【发布时间】:2013-10-19 20:29:39 【问题描述】:在app/assets/fonts
中放置字体
添加
Add the fonts path
config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
Precompile additional assets
config.assets.precompile += %w( .svg .eot .woff .ttf )
在 production.rb 和 development.rb 中
css 中链接的字体如:
@font-face
font-family: 'Icomoon';
src:url('/assets/icomoon.eot');
src:url('/assets/icomoon.eot?#iefix') format('embedded-opentype'),
url('/assets/icomoon.svg#icomoon') format('svg'),
url('/assets/icomoon.woff') format('woff'),
url('/assets/icomoon.ttf') format('truetype');
font-weight: normal;
font-style: normal;
似乎在开发中工作。但是在HEROKU中似乎不起作用。它找不到 /assets/icomoon.eot 。
此链接中的解决方案似乎不起作用
Using fonts with Rails asset pipeline
【问题讨论】:
您是否尝试过使用asset_url('assets/icomoon.eot'
等。请注意,在使用asset_url
时,您应该不有前导斜杠。
No 似乎不起作用。
【参考方案1】:
尝试从所有字体路径中删除 /assets/
。
@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;
如果scaffolds.css
在assets/stylesheets
中,请尝试删除它。
【讨论】:
这不起作用。我只是暂时将字体上传到S3。 @sarvesh 小心使用 s3 上的字体(即使存储桶被命名为子域),您需要打开 CORS 才能使它们在跨域的 firefox 中工作。 【参考方案2】:其实我只是尝试了comment中提出的解决方案,效果很好。似乎您只需要更改预编译指令的正则表达式,Heroku 就可以正确找到资产。
即将config.assets.precompile += %w( .svg .eot .woff .ttf )
更改为config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
。
编辑:根据 Heroku 的文档,在运行 assets:precompile
rake 任务时可能还需要添加 RAILS_ENV=production
。
【讨论】:
出于好奇,为什么是?:
而不是更简单的/\.(svg|eot|woff|tff)$/
?: 是所以 () 的内容不会被捕获。两者都是一样的,唯一的区别是没有?:匹配字符串的值会存放在这里$~[1]
您的编辑拯救了我的夜晚!我正在运行 assets:precompile 没有 prod env 并且我的 CSS 文件没有拾取指纹 FONT 文件。【参考方案3】:
鉴于收到此答案的 cmets(以及不必要的反对票),我已将我的答案修改如下:
Rails 现在似乎已经创建了一种方法来处理资产文件夹中的字体。它是called font-path
,工作方式如下:
如果您将自定义字体添加到 /assets/fonts 文件夹,您可以使用
font-path
助手来访问其中的文件。然后可以使用 使用font-path
助手在您的样式表和其他资产中:
|-app/
|---assets/
|-----fonts/
|-----images/
|-----javascripts/
|-----stylesheets/
@font-face
font-family:'icofonts';
src:font-url('icofonts.eot');
src:font-url('icofonts.eot?#iefix') format('embedded-opentype'),
...
这适用于预编译资产(Heroku 无论如何都会这样做)和静态资产。如果您想要实现此目的的 pre-Rails 4 方式,请参考我的以下回答:
我们在 Heroku 上使用了字体:http://firststop.herokuapp.com(仍在演示中)
这是我们的 CSS:
#assets/application.css
/*-- Akagi Font --*/
@font-face
font-family: 'akagi';
src: url('fonts/akagi-th-webfont.eot'),
src: url('fonts/akagi-th-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/akagi-th-webfont.woff') format('woff'),
url('fonts/akagi-th-webfont.ttf') format('truetype'),
url('fonts/akagi-th-webfont.svg#akagithin') format('svg');
font-weight: 300;
font-style: normal;
@font-face
font-family: 'akagi';
src: url('fonts/akagi-bk-webfont.eot');
src: url('fonts/akagi-bk-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/akagi-bk-webfont.woff') format('woff'),
url('fonts/akagi-bk-webfont.ttf') format('truetype'),
url('fonts/akagi-bk-webfont.svg#akagibook') format('svg');
font-weight: 400;
font-style: normal;
@font-face
font-family: 'akagi';
src: url('fonts/akagi-sb-webfont.eot');
src: url('fonts/akagi-sb-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/akagi-sb-webfont.woff') format('woff'),
url('fonts/akagi-sb-webfont.ttf') format('truetype'),
url('fonts/akagi-sb-webfont.svg#akagisemibold') format('svg');
font-weight: 500;
font-style: normal;
我们将字体放入/stylesheets/fonts folder
我们只是做标准的预编译字体的东西来让所有的 CSS 都在 Heroku 上工作,而且它可以工作。我怀疑你的路径不正确。也许尝试将您的字体目录移动到您的 /assets/stylesheets 文件夹中 :)
【讨论】:
我会假设这是可行的,因为它似乎是最彻底的答案。 :p 我必须把赏金给别人,享受吧! :-d 哦,好吧 :) 是的,我应该提到 RAILS_ENV=production 的东西 这适用于旧版本的 Rails,但它不使用资产管道,并且它可能根本不适用于 Rails 4 版本,因为您使用的是文件的静态版本,这Rails 4 进行了重大更改。要利用资产管道的优势并确保与新版本的 Rails 兼容,您需要使用资产管道帮助程序 - 如果您需要参考点,请参阅我的回答。 这不是问题的解决方案。所有这一切都是将文件放入公共文件夹并允许 nginx/static 服务器提供文件。虽然这会起作用,但它完全忽略了使用资产管道的意义,正如上面提到的 Aaron,它建议以一种对 Rails 不友好的方式解决问题。 你和亚伦都错了。预编译时,资产管道将文件放入公用文件夹中。 Heroku 本身recommends you use what I've recommended。您要做的是加载预编译的“指纹”资产,这些资产只能使用各种路径助手访问。这适用于我们的生产,我相信您的测试已经找到了类似的结果【参考方案4】:如果您使用常规的旧 css 而不是资产管道助手来定位您的资产,则字体等资产将用于开发而不是生产。 Rails 4 对资产管道添加了重大更改,以鼓励人们正确使用它,而不是使用引用资产的旧 css 方法。
要解决此问题,您需要使用新的资产管道助手来指向字体的指纹缓存版本。而不是url
(不使用资产管道),您需要使用font-url
(确实使用它)。为此,您可能必须使用 Sass 或在样式表中嵌入 ERB。
示例(使用 SCSS):
@font-face
font-family: 'Icomoon';
src: font-url("/assets/icomoon.eot");
src: font-url("/assets/icomoon.eot?#iefix") format("embedded-opentype"), font-url("/assets/icomoon.svg#icomoon") format("svg"), font-url("/assets/icomoon.woff") format("woff"), font-url("/assets/icomoon.ttf") format("truetype");
font-weight: normal;
font-style: normal;
请看这里:http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
【讨论】:
谢谢,也为我工作。不过,请确保将其放入.css.scss
文件中 - 我试图将其放入 application.css
时被抓到了,但这是可以理解的。
我在 Rails 4.2 上试过这个,它适用于 Heroku。甚至不必添加此代码:config.assets.precompile += %w( .svg .eot .woff .ttf )
【参考方案5】:
-
将您的 .css 文件重命名为 .css.erb
将所有
url('/assets/icomoon.eot')
替换为url(<%= asset_path 'icomoon.eot' %>)
等。
您可以通过将 css 文件转换为 SASS/SCSS 并使用 font-url()
助手而不是 url()
来获得相同的结果。
我已经在 Rails 4 中尝试过,即使没有您添加到 production.rb/application.rb 的位,它也可以工作。
【讨论】:
这也是需要的,但是你不需要使用<%= asset_path … %>
。您可以只使用 SASS 指令asset-path(…)
【参考方案6】:
您不需要在config.assets.paths
中包含/assets/fonts/
目录。根据文档,app/assets
、lib/assets
或 vendor/assets
中包含的所有目录都会自动加载。
http://guides.rubyonrails.org/asset_pipeline.html#asset-organization
管道资产可以放置在三个位置之一的应用程序中:
app/assets
、lib/assets
或vendor/assets
。[...]
除了标准的
assets/*
路径之外,还可以在config/application.rb
中将其他(完全限定的)路径添加到管道中。
config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
尝试在控制台中运行Rails.application.class.config.assets.paths
,您将看到/assets
中所有目录的数组。如果您添加另一个目录并重新启动控制台,它将自动包含在数组中,并且内容将作为资产提供。
您甚至不需要 config.assets.precompile += %w( .svg .eot .woff .ttf )
,因为所有非 js-css 文件都已通过默认匹配器 Proc 包含在内。
http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
编译文件的默认匹配器包括 application.js、application.css 和所有非 JS/CSS 文件(这将自动包括所有图像资产):
[ Proc.new |path| !%w(.js .css).include?(File.extname(path)) , /application.(css|js)$/ ]
尝试只在app/assets/
中添加字体目录,将所有配置保留为默认配置,然后在heroku 上部署您的应用。
【讨论】:
这对我有帮助。另外,对于font-url
,我删除了所有添加的路径。 src: font-url('Something.otf')
【参考方案7】:
我通过结合使用所有答案和 cmets 解决了这个问题。我的示例使用 Foundation 图标字体。
在您的 application.rb
文件中添加以下内容:
config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
将您的 application.css
文件重命名为 application.css.scss
并使用 font-url
和 asset-path
指令:
@font-face
font-family: "foundation-icons";
src: font-url( asset-path("foundation-icons.eot") );
src: font-url( asset-path("foundation-icons.eot?#iefix") ) format("embedded-opentype"),
font-url( asset-path("foundation-icons.woff") ) format("woff"),
font-url( asset-path("foundation-icons.ttf") ) format("truetype"),
font-url( asset-path("foundation-icons.svg#fontcustom") ) format("svg");
font-weight: normal;
font-style: normal;
【讨论】:
【参考方案8】:导轨 4
# config/application.rb
config.assets.paths << Rails.root.join("app", "assets", "fonts")
config.assets.precompile += %w(.svg .eot .woff .ttf)
# app/assets/stylesheets/foundation-icons.css.scss
@font-face
font-family: "foundation-icons";
src: asset-url("foundation-icons.eot");
src: asset-url("foundation-icons.eot?#iefix") format("embedded-opentype"),
asset-url("foundation-icons.woff") format("woff"),
asset-url("foundation-icons.ttf") format("truetype"),
asset-url("foundation-icons.svg#fontcustom") format("svg");
font-weight: normal;
font-style: normal;
【讨论】:
【参考方案9】:您实际上不必更改预编译正则表达式或资产路径。 尝试运行 rake assets:在提交到 Heroku 之前在生产模式下预编译。
rake assets:precompile RAILS_ENV=production
并确保使用 asset_path
辅助方法在 css 文件中引用您的资产。
喜欢:
src: font-url('<%= asset_path("foundation-icons.eot")%>');
【讨论】:
【参考方案10】:在尝试了上述所有方法后,没有一个对我有用,但这就是我解决字体问题的方法。如果字体在开发模式下工作,那么只需执行
config.assets.compile = true
在
config\environments\production.rb
【讨论】:
【参考方案11】:有两种方法可以解决此问题。
-
您可以直接将您的字体文件放在公共目录中,并在 CSS 文件中添加路径,例如 /fonts/font-name
在 config/initializers/assets.rb 文件中添加 Rails.application.config.assets.compile = true 行
【讨论】:
以上是关于Heroku字体资产不起作用的主要内容,如果未能解决你的问题,请参考以下文章