Help us understand the problem. What is going on with this article?

RailsアプリのAMP対応をSassで快適に

More than 3 years have passed since last update.

AMPとは

AMP(Accelerated Mobile Pages)はモバイルでのウェブページ表示を高速化する手法です。Googleが強く推奨しており、2016年10月よりGoogleのモバイル検索結果の表示にAMPが使用されるようになりました。
高速化のため、AMPページで用いられるHTMLには独自のプロパティや制限があります。cssに関しても、外部ファイルを読み込めない等の制限があります。

RailsでAMP対応する際の問題

AMPでは外部ファイルを読み込めないので、cssをheadタグ内のstyleタグに書かなければなりません。すなわち、ビュー内でcssをrenderする必要があります。しかし、アセットパイプラインにはそんな仕組みはありません。File.readでcssファイルを読み込んでビューに書き出すといった方法はすぐに考え付きますが、これではコンパイルが必要なSassは使えません。

RailsのビューでSassをrenderする

ではどうやってRailsのビューでSassをrenderするか。答えはSassのgemを直接使うです。なかなか使う機会はないと思いますが、Sassのgemはファイル読込・プリコンパイル・圧縮を一括で行ってくれるスグレモノです。しかも、ワンライナーで書けます!(以下のサンプルでは見やすくするために改行を入れてあります)
 以下にサンプルを示します。プリコンパイルと圧縮の処理はヘルパーにまとめ、それをビューで呼び出す形にしています。

/app/helpers/application_helper.rb
def render_css(path)
  raw Sass::Engine.for_file("#{Rails.root}/app/assets/stylesheets/#{path}", {
    load_paths: ["#{Rails.root}/app/assets/stylesheets"],
    style: :compressed
  }).to_css
end

/app/views/abc/amp.html.slim
style amp-custom=true
  = render_css('abc/amp.sass')

通常のstylesheet_link_tagと同様に使えるようにパス周りを工夫しています。拡張子は必須ですが、Sass::Engine.for_fileが拡張子でフォーマットを判断してくれるので、scssやcssの場合も対応できます。

簡単な解説

Sass::Engine.for_file

Sass::Engine.for_file(filename, options)は、第一引数にコンパイルしたいファイルのパス、第二引数にコンパイルのオプションをとります。このメソッドはファイルパスに対応したSass::Engineのインスタンスを生成して返します。このインスタンスはto_cssrenderといったメソッドを持っており、これらを呼び出すことでコンパイル結果のcssを取得できます。

Sass::Engine.for_fileのオプション

 load_pathsでSassの@importの基準パスを指定できます。上のサンプルでは"#{Rails.root}/app/assets/stylesheets"を指定して、通常のアセットパイプラインと同様に@importを使えるようにしています。また、styleにcompressedを指定することで圧縮が有効になります。

render_cssの戻り値

前述のto_cssの結果をそのまま返してしまうと、ビューでcssがhtmlエスケープされてしまいます。
それを防ぐためにrawメソッドを用い、その戻り値を返すようにしています。

まとめ

たった一行のヘルパーで、AMPページをSassで快適に実装できるようになります。これからAMPに関わる方々のお役に立てれば幸いです。

出典

https://www.ampproject.org/learn/about-amp/
https://japan.googleblog.com/2016/10/amp-1.html
http://sass-lang.com/documentation/Sass/Engine.html

niba1122
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away