LoginSignup
45
40

More than 5 years have passed since last update.

gulp でJS, CSS, イメージファイルのキャッシュ問題を回避する

Posted at

キャッシュ問題について

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>

これで、もうキャッシュは怖くない!!

サンプルは下記に置いてます。

yutackall/gulp-rev-sample

45
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
40