Middlemanのasset_hashで超柔軟にアセットファイルの交換が可能

middleman

アセットファイルを交換しても古いファイルが使われてしまう問題

WEBサイトを運営していて、画像やCSSやJavaScriptなどのアセットファイルを交換しても、ユーザが以前も訪問していた場合、古いファイルが使われてしまうことがります。

画像を修正したのに、修正前のものが表示されたり、古いJavaScriptが動いてしまってバグの原因になってしまうといったことになり兼ねません。

ブラウザは一定期間各サイトのアセットファイルを保存していて、htmlから呼ばれているファイルでキャッシュ内を探して、ある場合はネットからダウンロードせずに、そのキャッシュにあるものを使うからです。

Middlemanではasset_hashという機能でこの問題を解決できる!

現時点で、ブラウザのデベロッパーツールなどで本サイトのロゴの部分のhtmlを見ると以下の様になっています。

1
<img src="/images/logo-225f64b5.png">

この部分のソースファイルはslimで書かれていて下のようになっています。

1
= image_tag "logo.png"

ソースではlogo.pngというファイル名で指定しているだけなのに、最終的に出力されるhtmlではlogo-225f64b5.pngとなっています。

これはasset_hashという機能で自動的にファイルの内容からhash値を算出して(上の例では225f64b5)、それを名前の後ろにつけているためです。もちろんhtml内のファイル名だけでなく、実際のファイル名も変えてbuildしています。(source内にあるファイルはそのままです。)

この仕組みによって、ファイルが新しくなった場合には、Middlemanは違う値をファイル名に付与することになります。キャッシュ内には存在しないファイル名になるため、ブラウザは必ず新しいファイルをダウンロードして使ってくれます。

使い方

config.rbで有効にする

以下を追加するだけで有効になります。

1
activate :asset_hash

アセットを参照するメソッドで自動的に有効になる

上記の設定をすれば、image_tagstylesheet_link_tagjavascript_include_tagなどのアセットを参照するメソッドで有効になります。

Markdownの記事内でも、下のように画像を使う構文でも有効になっています。

1
![サンプル画像](sample.png)

ただ、記事内で使う場合は注意することがあります。うまくいかない場合はこちらの記事を参考にしてみてください。

middleman-blogで記事毎に画像を管理する方法

development環境では使わない方がよさそう

middleman serverがおかしくなることがある

ローカルのPCでmiddleman serverを起動している時に、asset_hashが有効になっていると、新しい画像ファイルを追加した際などに下のようなエラーが発生して、middleman serverの挙動がおかしくなってしまうことがあります。そうなると、全ての画像が表示されなかったり、source内のファイルを変更しても反映されなかったりします。そうなった場合は、middleman serverを再起動すれば直ります。

1
E, [2015-11-23T14:55:30.617479 #43881] ERROR -- : exception while processing events: articles/2015-11/23-bourbon-neat-how-to-make-visual-grid-responsive/images/screenshot.png should be in the sitemap! Backtrace:

エラーの全量ログはこちら

asset_hashを最初に導入する時にはdevlopment環境で動かしながら試すのはいいですが、確実に動作することがわかったらdevelopment環境ではオフにしbuild時のみに動作するようにするのが良いです。

build時のみに有効にするには

config.rbでasset_hashを有効にする部分を下のようにbuild時のみ動く部分に移動します。

1
2
3
4
5
configure :build do
  ...
  activate :asset_hash
  ...
end

まとめ

いかがでしたでしょうか?Middlemanではasset_hash機能のおかげで、どんどんアセットを変更しても大丈夫です。サイトで色々実験的なことが気兼ねなくできそうですね。

参照

一意の名前のアセットファイル

羊毛や小麦