サーバにRailsのプロジェクトをデプロイしてアセットプリコンパイルをした時に少し躓いたので備忘録程度に残しておく。
コマンドなどはRails Asset Pipelineがうまくいかないときの問題の切り分けかたを参考にさせていただきました。
環境
- centos-6.7
- Rails4.2.1
何が起きたのか
[hoge@huga project_dir]$ rake assets:precompile RAILS_ENV=production
...
rake aborted!
ExecJS::ProgramError: Unexpected token: punc ()) (line: 18, col: 1, pos: 347)
Error
at new JS_Parse_Error (<eval>:2659:11936)
at js_error (<eval>:2659:12155)
at croak (<eval>:2659:20622)
at token_error (<eval>:2659:20759)
at unexpected (<eval>:2659:20847)
at semicolon (<eval>:2659:21320)
at simple_statement (<eval>:2659:24179)
at <eval>:2659:22067
at <eval>:2659:21493
at <eval>:2660:1595new JS_Parse_Error ((execjs):2659:11936)
とエラーが出た。
ExecJS::ProgramError: Unexpected token: punc ()) (line: 18, col: 1, pos: 347)
とあるので、どこかのファイルの18行目(line: 18)によくわからない")"が入っているよう。
bootswatchかbootstrapzeroか何かのテンプレートを使っていたので、jsのファイルも大量にあり、どのファイルがエラーを起こしているか分からない状態。
どのファイルか分からない
$ rake assets:precompile RAILS_ENV=production
上のコマンドを叩くとプリコンパイルされたファイルが順番に出力されるのだが、エラー出た時にスペル間違えたかなとか考えて上のコマンドを複数回叩いてしまうと、既にプリコンパイルが通ったファイルは出てこなくなってしまうので、どのファイルでエラーが吐き出されたか分からなくなってしまう。
確認方法
$ rake assets:clobber RAILS_ENV=production
上のコマンドで一度プリコンパイル済みのファイルを消す。
そのうえで、
$ rake assets:precompile RAILS_ENV=production
を再度実行すると、再び順番にファイルが表示されるので、改めて確認できる。
例
[hoge@huga project_dir]# rake assets:clobber RAILS_ENV=production
I, [2016-03-13T11:17:21.016229 #15048] INFO -- : Removed /path/to/project_dir/public/assets
rm -rf /path/to/project_dir/tmp/cache/assets
[hoge@huga project_dir]# rake assets:precompile RAILS_ENV=production
I, [2016-03-13T11:17:44.155293 #15050] INFO -- : Writing /path/to/project_dir/public/assets/bootstrap-6f46133c56bb1d0c175c4aa13a4b92eaf1698d0099f9f7883e02cc46.css
I, [2016-03-13T11:17:44.460988 #15050] INFO -- : Writing /path/to/project_dir/public/assets/main-dda09b290fa83f87fb61c84141abe63649f04a5631ee4c13961f.css
(省略)
I, [2016-03-13T11:17:47.325617 #15050] INFO -- : Writing /path/to/project_dir/public/assets/retina-2a5fee7353499948abdb51cfab12b599fa47d.js
I, [2016-03-13T11:17:47.398177 #15050] INFO -- : Writing /path/to/project_dir/public/assets/jquery.easing.1.3-710024002e0292a08d24791d0e0186db6f8ba68e74025c89b3bf2.js
I, [2016-03-13T11:17:47.466105 #15050] INFO -- : Writing /path/to/project_dir/public/assets/smoothscroll-a8b941cc3911cf557ca8e2cd17ad3ddd144f128752be16144c.js
rake aborted!
ExecJS::ProgramError: Unexpected token: punc ()) (line: 18, col: 1, pos: 347)
(以下省略)
上の場合では、smoothscroll.jsの後のファイルのプリコンパイルでエラーが出ていることがわかる。
プリコンパイルするファイルの順番
先ほどの例で、smoothscroll.jsの後のファイルのプリコンパイルで失敗していることがわかった。しかし肝心のsmoothscroll.jsの後のファイルが何かわかっていない。
確認方法
rails consoleで以下のコマンドを叩くことで調べることができる
[hoge@huga project_dir]# rails c -e production
Loading production environment (Rails 4.2.1)
2.2.1 :001 > Rails.application.config.assets.precompile
例
[hoge@huga project_dir]# rails c -e production
Loading production environment (Rails 4.2.1)
2.2.1 :001 > Rails.application.config.assets.precompile
=> [#<Proc:0x000000037963e8@/usr/local/rvm/gems/ruby-2.2.1/gems/sprockets-rails-2.3.3/lib/sprockets/railtie.rb:60 (lambda)>, /(?:\/|\\|\A)application\.(css|js)$/, "admin/*.css", "admin/*.js", "bootstrap.css", "main.css",(省略), "retina.js", "jquery.easing.1.3.js", "smoothscroll.js", "jquery-func.js", (省略)]
Rails.application.config.assets.precompileで得られるファイルの順にプリコンパイルされるようなので、smoothscroll.jsの後のjquery-func.jsでエラーが出ていることがわかる。
ファイルの中身
jquery-func.jsを見てみると
!function($) {
(省略)
});
もともとのエラー
ExecJS::ProgramError: Unexpected token: punc ()) (line: 18, col: 1, pos: 347)
によると18行目に不要な")"があると言うことだったが、このjquery-func.jsの最終行が18行目であり、セミコロン直前の")"がいらなかった。これを消してprecompileしたらエラーは消えた。
結局自前で用意したファイルだった。