読者です 読者をやめる 読者になる 読者になる

AngularJSで$templateCacheを使ってまとめたテンプレートJSの中のCSSファイルや画像ファイルのリンクにhashをつける

grunt-filerevを使って、CSSファイルや画像ファイルにhashがbuild時につくようにしている場合に、grunt-angular-templatesを使う場合はどうするか

generator-angularで作ったAngularJSプロジェクトのbuildタスクではgrunt-useminの処理中、grunt-filerevの処理が入って、CSSファイルや画像ファイル、JSファイルにhashがつく。 要するにRailsのAssett Pipelineで処理したときによくみるあれと同様。

こんなやつ

index.html

<link rel="stylesheet" href="styles/main.b1c3621e.css">
<script src="scripts/scripts.a241652b.js">

grunt-angular-templatesを入れて何も考えずに素直にタスクに組み入れると、テンプレートキャッシュの中に画像などへの参照があった場合に、当然、このhashを付与する流れに入っていないので、hashが付与されないリンクのままでbuildされ、リンク切れという事になってしまう。

↓useminでのgrunt-filerevを考慮せずタスクに追加

#Gruntfile.coffee
 
#...省略...
 # 追加
 grunt.loadNpmTasks("grunt-angular-templates")

 #...省略...
   # 追加
    ngtemplates:
      gambaApp:
        cwd: "<%= yeoman.app %>"
        src: "templates/*.html"
        dest: ".tmp/scripts/templates.js"
        options:
          collapseWhitespace: true
          conservativeCollapse: true
          collapseBooleanAttributes: true
          removeCommentsFromCDATA: true
          removeOptionalTags: true
          usemin: "scripts/scripts.js"

 #...省略...

  grunt.registerTask "build", [
    "clean:dist"
    "wiredep"
    "useminPrepare"
    "ngtemplates"     #<- 追加
    "concurrent:dist"
    "autoprefixer"
    "concat"
    "ngAnnotate"
    "copy:dist"
    "cdnify"
    "cssmin"
    "uglify"
    "filerev"
    "usemin"
    "htmlmin"
  ]

index.html

   <!-- build:js({.tmp,app}) scripts/scripts.js -->
   <script src="scripts/app.js"></script>
  <script src="scripts/templates.js"></script>
  <!- 追加↑ -->

ので、useminタスクに以下のように追加した。

#Gruntfile.coffee

  # Performs rewrites based on filerev and the useminPrepare configuration
    usemin:
      js: ["<%= yeoman.dist %>/scripts/scripts*.js"] #<- 追加
      html: ["<%= yeoman.dist %>/{,*/}*.html"]
      css: ["<%= yeoman.dist %>/styles/{,*/}*.css"]
      options:
        assetsDirs: [
          "<%= yeoman.dist %>"
          "<%= yeoman.dist %>/images"
        ]
       # patternsを追加して、画像のリンクにhashがつくようにする
        patterns:
          js: [
            [/(hogefuga\.jpg)/g, "Replacing reference to hogefuga.jpg"]
          ]

自分で一からGruntfileでタスクを準備していった場合は、こういった部分も考慮にいれて使うパッケージを検討、タスクの順番や構成を組むだろうが、あとから追加していこうとすると、最初から色々用意したあったタスクやnpmのパッケージとの兼ね合いで若干面倒。
色々なnpmを使って、タスクをカスタマイズしまくるような場合はgenerator-angularなどを使用せず、面倒でも一からタスクを吟味して組んでいった方が幸せになれるかもしれない。