SinatraでAsset Pipelineするならsinatra-asset-pipelineが便利


Sinatraで作るような簡単なWebアプリでも、SassやCoffeeScriptを使ったりCSS・JSを圧縮したいときはよくある。そのときは[sinatra-asset-pipeline](https://github.com/kalasjocke/sinatra-asset-pipeline)が便利。

最初は[sinatra-assetpack](https://github.com/rstacruz/sinatra-assetpack)を試したが、

- パイプラインシステムが独自実装であるため記述が独特
- Herokuへのデプロイ(precompile)がうまくできなかった

ので[sinatra-asset-pipeline](https://github.com/kalasjocke/sinatra-asset-pipeline)に切り替えた。こちらの利点は、

- Sprocketsを使っており、使い慣れたRailsと同じように利用できる
  - Railsと同様Herokuにデプロイしたら`rake assets:precompile`が走り、
    圧縮された静的ファイルを配信可能
- ほぼSprocketsのラッパーなのでライブラリが薄い
  - 挙動を把握しやすい
  - Sprocketsを直接使う方法にもすぐ移行可能


## 使用方法
[README](https://github.com/kalasjocke/sinatra-asset-pipeline)の通りにやればすぐ動く。CSS・JavaScriptの読込設定もRailsと同じなので楽ちん

自分は以下のように設定した。

```ruby:Gemfile
source 'https://rubygems.org'
source 'https://rails-assets.org'

gem 'sinatra', require: 'sinatra/base'
# Bundlerで自動requireできるように
gem 'sinatra-asset-pipeline', require: 'sinatra/asset_pipeline'
# JavaScriptの圧縮に必要
gem 'uglifier'

gem 'compass'

# Rails Assets
gem 'rails-assets-normalize.css'
```

[Rails Assets](https://rails-assets.org/)に[Rails以外からも使いやすくする変更](https://github.com/rails-assets/rails-assets/issues/128)が入っていたので、Rails Assetsからも読み込めるようにした。

```ruby:app.rb
ENV['RACK_ENV'] ||= 'development'
require 'bundler/setup'
# `Bundler.require`で自動requireする
Bundler.require(:default, ENV['RACK_ENV'])

class App < Sinatra::Base
  configure do
    # Railsのデフォルトに合わせ、application.js/cssが生成されるように設定
    set :assets_precompile, %w(application.js application.css *.png *.jpg *.svg *.eot *.ttf *.woff)
    # CSS・JSを圧縮する
    set :assets_css_compressor, :sass
    set :assets_js_compressor, :uglifier
    register Sinatra::AssetPipeline

    # Rails Assetsに対応
    if defined?(RailsAssets)
      RailsAssets.load_paths.each { |path| settings.sprockets.append_path(path) }
    end
  end

  get '/' do
    erb :index
  end
end
```

ビューヘルパーは[sprockets-helpers](https://github.com/petebrowne/sprockets-helpers)が提供している。

```erb:views/layout.erb
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>test</title>
    <%= stylesheet_tag 'application' %>
  </head>
  <body>

<%= yield %>

    <%= javascript_tag 'application' %>
  </body>
</html>
```

デフォルトでは`assets`、`vendor/assets`以下のフォルダがアセットの保存パスとして扱われる。

```
mkdir -p assets/js assets/css assets/img
```

あとはRailsと同様、application.js/cssに[Sprockets](https://github.com/sstephenson/sprockets)の読込設定を書いていけばいい。

```javascript:assets/js/application.js
// 例)
//= require jquery
//= require_tree .
```

```sass:assets/css/application.css.sass
// 例)
@import compass
@import variables
@import mixins
@import normalize
@import main
```


Rakeタスクを定義しておけばHerokuへのデプロイ時に自動で`rake assets:precompile`が走る。

```ruby:Rakefile
require_relative 'app'

require 'sinatra/asset_pipeline/task'
Sinatra::AssetPipeline::Task.define! App
```

```
$ git push heroku master
...
-----> Ruby app detected
-----> Compiling Ruby/Rack
-----> Using Ruby version: ruby-2.1.3
-----> Installing dependencies using 1.6.3
...
-----> Precompiling assets
       Running: rake assets:precompile
       Asset precompilation completed (10.53s)

-----> Discovering process types
       Procfile declares types -> web
       Default types for Ruby  -> console, rake

-----> Compressing... done, 23.3MB
-----> Launching... done, v30
       http://***.herokuapp.com/ deployed to Heroku
```