Rails Assetの管理についてまとめる

# Assetの管理
Assetとは、Webアプリケーションの直接のレスポンス以外の構成要素のことを指します。Javascript、CSS、画像などがこれにあたります。Asset Pipelineを使うことでこのAssetを簡単に利用出来るようになります。

# Asset Pipeline の役割

1. アセットファイルのパスの管理
2. アセットのコンパイル 
3. アセットの依存関係の整理

これは、Sprocketsの機能によります。

## 1. アセットファイルのパスの管理
assetsの中のパスの管理をします。

```
/assets/javascript/hoge.js
/assets/stylesheet/poge.css
```
 というファイルを

```
/assets/hoge.js
/assets/poge.css
```

のように1つのディレクトリで管理されているかのようにアクセスさせてくれます。

## 2. アセットのコンパイル
Javascript、CSSを使う代わりに、CoffeeScript、SCSSを使うことも多いと思います。Sprocketsの機能でCoffeeScriptとSCSSをコンパイルしてくれます。このように、ファイルを変換し適切な形式に変換して返却してくれる機能をAsset Pipelineと表します。

必要となるgemは以下です。

```rb
gem 'sprockets'
gem 'coffee_script'
gem 'therubyracer'
gem 'scss'
```

### sprockets
Asset Pipelineの基盤の機能を提供してくれます。
### coffee_script scss
それぞれCoffeeScript、scssを使うためです。
### therubyracer
JavascriptをRubyで実行できる環境を用意してくれます。これはCoffeeScriptのコンパイルに必要になります。

## 3. アセットの依存関係の整理

Asset間の依存関係を整理します。Sprocketsは依存関係を管理するために独自の構文を持っています。これをディレクティブといいます。以下のような形式です。ディレクティブは他のファイルに影響を与えないためにコメントアウトの形式で記述します。このようにしてファイルの読み込み順序を管理します。

```app/assets/javascript/application.js
//= require jquery
//= require jquery_ujs
//= require_tree .
```

Railsのアプリケーションでは複数のCSS、Javascriptを1ファイルにまとめて提供することが主流となっています。それはファイルが複数存在すればリクエストの数が増えてページの読み込みが遅くなるからです。
ディレクティブを使ってアプリケーションの内の依存関係をまとめて提供するための仲介になるファイルを「マニフェストファイル」と呼び、デフォルトでは application.js、application.css になります。


# Asset Pipelineを制御する

## develpment/production の挙動の設定

設定は ```/config/environments/```のファイルに記述します。
以下のような感じにassets関係のセットをすることになるかと思います。(以下ほぼデフォルトなので。勿論適宜変更して使う。)

```rb:/config/environments/production.rb
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
# config.assets.debug = false
```

```rb:/config/environments/development.rb
# config.assets.js_compressor = nil
# config.assets.css_compressor = nil
# config.assets.compile = true
config.assets.digest = false
config.assets.debug = true
```

## config.assets.js_compressor
Javascriptの圧縮ライブラリの設定。productionではuglifierというgemを利用しているが nilの設定にして無効にすることも出来る。
以下default。

|development|production|
|:--:|:--:|
|nil|:uglifier|

## config.assets.css_compressor
CSSの圧縮ライブラリの設定。
以下default。

|development|production|
|:--:|:--:|
|nil|:uglifier|

## config.assets.compile
動的にcompileするか。trueだとprecompileしていないファイルを動的にコンパイルするのでproductionではfalseが良さそう。
以下default。

|development|production|
|:--:|:--:|
|true|false|

### config.assets.digest
digest付与を有効にするかどうか。pipelineを通した後のファイルにつく数字をつけるかどうかです。付けてあげるとキャッシュに残っているものも変更を加えることが出来るのでproductionではtrueが良さそう。
以下default。

|development|production|
|:--:|:--:|
|false|true|

### config.assets.debug
debugするか。これをfalseにするとファイルが統合される
以下default。

|development|production|
|:--:|:--:|
|true|false|

## プリコンパイルのファイルの設定

```config/initializers/asset.rb``` でprecompileするファイルを設定出来る。

```rb:config/initializers/asset.rb
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += %w( *.js *application.css)
```

>application.js, application.css, and all non-JS/CSS in app/assets folder are already added.

application.js, application.css と他のJS/CSSファイル以外のassetがデフォルトではprecompile対象になります。追加したいときは上記コードのように追記します。

# Asset Pipelineの流れ

## production

下記設定の場合。

```rb:/config/environments/production.rb
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
# config.assets.debug = false
```

1. assetにあるソースコードをコンパイル( coffee -> js、 scss -> css )
2. コンパイルしたソースコードを統合 (複数のファイルのコードをまとめる）
 - このあたりはマニフェストファイルの記述等による。
3. ファイルを圧縮する（uglifier、sass)
4. ファイルにダイジェストを付与する（ファイル名につくハッシュ)

これでブラウザに送られる。

ちなみに、画像はダイジェスト付与してブラウザへ。


## development

対して、下記設定の場合。

```rb:/config/environments/development.rb
# config.assets.js_compressor = nil
# config.assets.css_compressor = nil
# config.assets.compile = true
config.assets.digest = false
config.assets.debug = true
```


1. assetにあるソースコードをコンパイル( coffee -> js、 scss -> css )

これだけでブラウザへ送られる。