キャッシュ問題について
Web ページの高速化のため、キャッシュを利用して高速化等を行ったりしますが、公開した JS,CSS 等に問題があったときに、それらを修正し、
即座に反映させたいがキャッシュにより、それが反映されないといったことが度々起こります。
これは、キャッシュにより、改めてデプロイした最新の CSS,JS 等が読み込まれ無いことで起こっている現象で、
これを回避するために、Rails であれば Asset Pipeline という機能があり、具体的には読み込む JS, CSS のファイル名にハッシュ値を追加し、デプロイ時にそれを実行することで、読み込む JS, CSS を制御しています。
今回はこれを gulp の task で実現したいと思います。
使用する node_module
-
gulp-rev
各ファイルに対して、ファイル名にハッシュ値を付与するモジュール
変換したファイル名の manifest ファイルの吐き出しまで行う
例) app.js -> app-ffd7597286.js
-
gulp-rev-replace
gulp-rev で吐き出した manifest ファイルを元に、記載されている対応によって、ファイル名を書き換えてくれるモジュール
ディレクトリ / ファイル構成
src/
|-- images/
| |-- favicon.ico
|-- javascripts/
| |-- app.coffee
|-- stylesheets/
| |-- app.sass
|-- views/
|-- index.jade
gulpfile.coffee
node_modules/
pakage.json
public/ # build 後のディレクトリ
|-- assets/
|-- index.html
実際のコード
gulpfile(CoffeeScript) に下記コードを記載します。
gulpfile.coffee
gulp = require 'gulp'
del = require 'del'
sequence = require 'run-sequence'
coffee = require 'gulp-coffee'
jade = require 'gulp-jade'
rev = require 'gulp-rev'
revReplace = require 'gulp-rev-replace'
sass = require 'gulp-sass'
basePath = 'src/'
baseDestPath = 'public/'
paths =
html:
src: basePath + 'views/*.jade'
dest: baseDestPath
js:
src: basePath + 'javascripts/**/*.coffee'
dest: baseDestPath + 'assets/'
css:
src: basePath + 'stylesheets/**/*.sass'
dest: baseDestPath + 'assets/'
img:
src: basePath + 'images/**/*'
dest: baseDestPath + 'assets/'
rev:
src: baseDestPath + 'assets/**/*.+(js|css|png|gif|jpg|jpeg|svg|woff|ico)'
dest: baseDestPath + 'assets/'
manifestFileName: 'hoge-manifest.json'
rev_replace:
src: baseDestPath + '**/*.+(html|css|js)'
dest: baseDestPath
gulp.task 'default', ['build']
gulp.task 'build', (cb) ->
sequence 'clean', 'coffee', 'sass', 'image', 'jade', 'rev', 'rev:replace', cb
gulp.task 'clean', (cb) ->
del(["#{baseDestPath}/*"], cb)
gulp.task 'coffee', (f) =>
gulp.src paths.js.src
.pipe coffee()
.pipe gulp.dest paths.js.dest
gulp.task 'jade', (f) ->
gulp.src paths.html.src
.pipe jade()
.pipe gulp.dest paths.html.dest
gulp.task 'image', (f) ->
gulp.src paths.img.src
.pipe gulp.dest paths.img.dest
gulp.task 'sass', (f) ->
gulp.src paths.css.src
.pipe sass()
.pipe gulp.dest paths.css.dest
gulp.task 'rev', (f) ->
gulp.src paths.rev.src # (2)
.pipe rev() # (3)
.pipe gulp.dest paths.rev.dest # (4)
.pipe rev.manifest(paths.rev.manifestFileName) # (5)
.pipe gulp.dest paths.rev.dest # (6)
gulp.task 'rev:replace', (f) ->
manifest = gulp.src paths.rev.manifestFileName # (7)
gulp.src paths.rev_replace.src # (8)
.pipe revReplace manifest: manifest # (9)
.pipe gulp.dest paths.rev_replace.dest # (10)
コードの説明
- (1)
使用するモジュールの読み込み
- (2)
対象のファイルを記載 js,cs 等、キャッシュされたくないファイルを指定 - (3)
rev()
でファイル名にハッシュ値を付与 - (4)
ハッシュ値を付与したファイルの出力先を指定 - (5)
該当のファイル名とハッシュ値を付与したファイル名の対応を JSON で生成。
標準で出力されるファイル名は、「rev-manifest.json」で、(3) のrev()
の第一引数にファイル名を指定することで
任意の名前で生成することが可能(rev('hoge-manifest.json')
)
hoge-manifest.json
{
"app.css": "app-d41d8cd98f.css",
"app.js": "app-34208c3063.js",
"favicon.ico": "favicon-58c242b34b.ico"
}
- (6)
(5) で生成した manifest ファイルの出力先を指定
- (7)
manifest ファイルの読込
- (8)
書き換え対象のファイル名を指定
- (9)
manifest ファイルを指定して、対象のファイル内を書き換え
- (10)
書き換え後のファイルの出力先を指定
実行後のソース
index.jade
doctype html
html
head
meta(charset="utf-8")
title gulp-rev-sample
link(rel='shortcut icon', href='assets/favicon.ico')
link(rel='stylesheet', href='assets/app.css')
body
script(src='assets/app.js')
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>gulp-rev-sample</title>
<link rel="shortcut icon" href="assets/favicon-58c242b34b.ico">
<link rel="stylesheet" href="./assets/app-d41d8cd98f.css"/>
</head>
<body>
<script src="./assets/app-34208c3063.js"></script>
</body>
</html>
これで、もうキャッシュは怖くない!!
サンプルは下記に置いてます。