structure-assets.md 43.4 KB
Newer Older
1 2 3
アセット
========

4 5 6 7 8
Yii では、アセットは、ウェブページで参照できるファイルを意味します。
アセットは CSS ファイルであったり、JavaScript ファイルであったり、画像やビデオのファイルであったりします。
アセットはウェブでアクセス可能なディレクトリに配置され、ウェブサーバによって直接に提供されます。

たいていの場合、アセットはプログラム的に管理する方が望ましいものです。
9
例えば、ページの中で [[yii\jui\DatePicker]] ウィジェットを使うとき、このウィジェットは必要な CSS と JavaScript のファイルを自動的にインクルードします。
10
あなたに対して、手作業で必要なファイルを探してインクルードするように要求したりはしません。
11
そして、このウィジェットを新しいバージョンにアップグレードしたときは、自動的に新しいバージョンのアセットファイルが使用されるようになります。
12 13 14
このチュートリアルでは、Yii によって提供される強力なアセット管理機能について説明します。


15
## アセットバンドル <span id="asset-bundles"></span>
16

17 18
Yii はアセットを *アセットバンドル* を単位として管理します。アセットバンドルは、簡単に言えば、あるディレクトリの下に集められた一群のアセットです。
[ビュー](structure-views.md) の中でアセットバンドルを登録すると、バンドルの中の CSS や JavaScript のファイルがレンダリングされるウェブページに挿入されます。
19 20


21
## アセットバンドルを定義する <span id="defining-asset-bundles"></span>
22

23 24 25 26
アセットバンドルは [[yii\web\AssetBundle]] から拡張された PHP クラスとして定義されます。
バンドルの名前は、対応する PHP クラスの完全修飾名 (先頭のバックスラッシュを除く) です。
アセットバンドルクラスは [オートロード可能](concept-autoloading.md) でなければなりません。
アセットバンドルクラスは、通常、アセットがどこに置かれているか、バンドルがどういう CSS や JavaScript のファイルを含んでいるか、そして、バンドルが他のバンドルにどのように依存しているかを定義します。
27

28
以下のコードは [ベーシックアプリケーションテンプレート](start-installation.md) によって使用されているメインのアセットバンドルを定義するものです。
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

```php
<?php

namespace app\assets;

use yii\web\AssetBundle;

class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.css',
    ];
    public $js = [
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}
```

53 54 55
上の `AppAsset` クラスは、アセットファイルが `@webroot` ディレクトリの下に配置されており、それが URL `@web` に対応することを定義しています。
バンドルは一つだけ CSS ファイル `css/site.css` を含み、JavaScript ファイルは含みません。
バンドルは、他の二つのバンドル、すなわち [[yii\web\YiiAsset]] と [[yii\bootstrap\BootstrapAsset]] に依存しています。
56 57 58
以下、[[yii\web\AssetBundle]] のプロパティに関して、更に詳細に説明します。

* [[yii\web\AssetBundle::sourcePath|sourcePath]]: このバンドルのアセットファイルを含むルートディレクトリを指定します。
59
  ルートディレクトリがウェブからアクセス可能でない場合に、このプロパティをセットしなければなりません。
60
  そうでない場合は、代りに、[[yii\web\AssetBundle::basePath|basePath]] と [[yii\web\AssetBundle::baseUrl|baseUrl]] のプロパティをセットしなければなりません。
61 62
  [パスエイリアス](concept-aliases.md) をここで使うことが出来ます。
* [[yii\web\AssetBundle::basePath|basePath]]: このバンドルのアセットファイルを含むウェブからアクセス可能なディレクトリを指定します。
63
  [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティをセットした場合は、[アセットマネージャ](#asset-manager) がバンドルに含まれるファイルをウェブからアクセス可能なディレクトリに発行して、その結果、このプロパティを上書きします。
64
  アセットファイルが既にウェブからアクセス可能なディレクトリにあり、アセットの発行が必要でない場合に、このプロパティをセットしなければなりません。
65 66
  [パスエイリアス](concept-aliases.md) をここで使うことが出来ます。
* [[yii\web\AssetBundle::baseUrl|baseUrl]]: [[yii\web\AssetBundle::basePath|basePath]] ディレクトリに対応する URL を指定します。
67
  [[yii\web\AssetBundle::basePath|basePath]] と同じように、[[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティをセットした場合は、[アセットマネージャ](#asset-manager) がアセットを発行して、その結果、このプロパティを上書きします。
68
  [パスエイリアス](concept-aliases.md) をここで使うことが出来ます。
69
* [[yii\web\AssetBundle::js|js]]: このバンドルに含まれる JavaScript ファイルをリストする配列です。
70
  ディレクトリの区切りとしてフォワードスラッシュ "/" だけを使わなければならないことに注意してください。
71 72 73 74 75
  それぞれの JavaScript ファイルは、以下の二つの形式のどちらかによって指定することが出来ます。
  - ローカルの JavaScript ファイルを表す相対パス (例えば `js/main.js`)。
    実際のファイルのパスは、この相対パスの前に [[yii\web\AssetManager::basePath]] を付けることによって決定されます。
    また、実際の URL は、この相対パスの前に [[yii\web\AssetManager::baseUrl]] を付けることによって決定されます。
  - 外部の JavaScript ファイルを表す絶対 URL。
76
    例えば、`http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js``//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` など。
77 78
* [[yii\web\AssetBundle::css|css]]: このバンドルに含まれる CSS ファイルをリストする配列です。
  この配列の形式は、[[yii\web\AssetBundle::js|js]] の形式と同じです。
79 80
* [[yii\web\AssetBundle::depends|depends]]: このバンドルが依存しているアセットバンドルの名前をリストする配列です
   (バンドルの依存関係については、すぐ後で説明します)。
81 82
* [[yii\web\AssetBundle::jsOptions|jsOptions]]: このバンドルにある *全て* の JavaScript ファイルについて、それを登録するときに呼ばれる [[yii\web\View::registerJsFile()]] メソッドに渡されるオプションを指定します。
* [[yii\web\AssetBundle::publishOptions|publishOptions]]: ソースのアセットファイルをウェブディレクトリに発行するときに呼ばれる [[yii\web\AssetManager::publish()]] メソッドに渡されるオプションを指定します。
83 84 85
  これは [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定した場合にだけ使用されます。


86
### アセットの配置場所 <span id="asset-locations"></span>
87

88
アセットは、配置場所を基準にして、次のように分類することが出来ます。
89 90 91 92 93 94 95

* ソースアセット: アセットファイルは、ウェブ経由で直接にアクセスすることが出来ない PHP ソースコードと一緒に配置されています。
  ページの中でソースアセットを使用するためには、ウェブディレクトリにコピーして、いわゆる発行されたアセットに変換しなければなりません。
  このプロセスは、すぐ後で詳しく説明しますが、*アセット発行* と呼ばれます。
* 発行されたアセット: アセットファイルはウェブディレクトリに配置されており、したがってウェブ経由で直接にアクセスすることが出来ます。
* 外部アセット: アセットファイルは、あなたのウェブアプリケーションをホストしているのとは別のウェブサーバ上に配置されています。

96 97 98
アセットバンドルクラスを定義するときに、[[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定した場合は、相対パスを使ってリストに挙げられたアセットは全てソースアセットであると見なされます。
このプロパティを指定しなかった場合は、アセットは発行されたアセットであることになります
(したがって、[[yii\web\AssetBundle::basePath|basePath]] と [[yii\web\AssetBundle::baseUrl|baseUrl]] を指定して、アセットがどこに配置されているかを Yii に知らせなければなりません)。
99 100

アプリケーションに属するアセットは、不要なアセット発行プロセスを避けるために、ウェブディレクトリに置くことが推奨されます。
101
前述の例において `AppAsset`[[yii\web\AssetBundle::sourcePath|sourcePath]] ではなく [[yii\web\AssetBundle::basePath|basePath]] を指定しているのは、これが理由です。
102

103
[エクステンション](structure-extensions.md) の場合は、アセットがソースコードと一緒にウェブからアクセス出来ないディレクトリに配置されているため、アセットバンドルクラスを定義するときには [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティを指定しなければなりません。
104 105

> Note|注意: `@webroot/assets` を [[yii\web\AssetBundle::sourcePath|ソースパス]] として使ってはいけません。
106
  このディレクトリは、デフォルトでは、[[yii\web\AssetManager|アセットマネージャ]] がソースの配置場所から発行されたアセットファイルを保存する場所として使われます。
107
  このディレクトリの中のファイルはすべて一時的なものと見なされており、削除されることがあります。
108 109


110
### アセットの依存関係 <span id="asset-dependencies"></span>
111

112 113
ウェブページに複数の CSS や JavaScript ファイルをインクルードするときは、オーバーライドの問題を避けるために、一定の順序に従わなければなりません。
例えば、ウェブページで jQuery UI ウィジェットを使おうとするときは、jQuery JavaScript ファイルが jQuery UI JavaScript ファイルより前にインクルードされることを保証しなければなりません。
114 115
このような順序付けをアセット間の依存関係と呼びます。

116 117 118
アセットの依存関係は、主として、[[yii\web\AssetBundle::depends]] プロパティによって指定されます。
`AppAsset` の例では、このアセットバンドルは他の二つのアセットバンドル、すなわち、[[yii\web\YiiAsset]] と [[yii\bootstrap\BootstrapAsset]] に依存しています。
このことは、`AppAsset` の CSS と JavaScript ファイルが、依存している二つのアセットバンドルにあるファイルの *後に* インクルードされることを意味します。
119 120 121 122

アセットの依存関係は中継されます。つまり、バンドル A が B に依存し、B が C に依存していると、A は C にも依存していることになります。


123
### アセットのオプション <span id="asset-options"></span>
124

125 126
[[yii\web\AssetBundle::cssOptions|cssOptions]] および [[yii\web\AssetBundle::jsOptions|jsOptions]] のプロパティを指定して、CSS と JavaScript ファイルがページにインクルードされる方法をカスタマイズすることが出来ます。
これらのプロパティの値は、[ビュー](structure-views.md) が CSS と JavaScript ファイルをインクルードするために、[[yii\web\View::registerCssFile()]] および [[yii\web\View::registerJsFile()]] メソッドを呼ぶときに、それぞれ、オプションとして引き渡されます。
127 128

> Note|注意: バンドルクラスでセットしたオプションは、バンドルの中の *全て* の CSS/JavaScript ファイルに適用されます。
129
  いろいろなファイルに別々のオプションを使用したい場合は、別々のアセットバンドルを作成して、個々のバンドルの中では、一組のオプションを使うようにしなければなりません。
130

131
例えば、IE9 以下のブラウザに対して CSS ファイルを条件的にインクルードするために、次のオプションを使うことが出来ます。
132 133 134 135 136

```php
public $cssOptions = ['condition' => 'lte IE9'];
```

137
こうすると、バンドルの中の CSS ファイルは下記の HTML タグを使ってインクルードされるようになります。
138 139 140 141 142 143 144

```html
<!--[if lte IE9]>
<link rel="stylesheet" href="path/to/foo.css">
<![endif]-->
```

145
生成された CSS のリンクタグを `<noscript>` の中に包むためには、次のように `cssOptions` を構成することが出来ます。
146 147 148 149 150 151

```php
public $cssOptions = ['noscript' => true];
```

JavaScript ファイルをページの head セクションにインクルードするためには、次のオプションを使います
152
(デフォルトでは、JavaScript ファイルは body セクションの最後にインクルードされます)。
153 154 155 156 157

```php
public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
```

158
デフォルトでは、アセットバンドルが発行されるときは、[[yii\web\AssetBundle::sourcePath]] で指定されたディレクトリの中にある全てのコンテントが発行されます。
159 160
[[yii\web\AssetBundle::publishOptions|publishOptions]] プロパティを構成することによって、この振る舞いをカスタマイズすることが出来ます。
例えば、[[yii\web\AssetBundle::sourcePath]] の一個または数個のサブディレクトリだけを発行するために、アセットバンドルクラスの中で下記のようにすることが出来ます。
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

```php
<?php
namespace app\assets;

use yii\web\AssetBundle;

class FontAwesomeAsset extends AssetBundle 
{
    public $sourcePath = '@bower/font-awesome'; 
    public $css = [ 
        'css/font-awesome.min.css', 
    ]; 
    
    public function init()
    {
        parent::init();
        $this->publishOptions['beforeCopy'] = function ($from, $to) {
            $dirname = basename(dirname($from));
            return $dirname === 'fonts' || $dirname === 'css';
        };
    }
}  
```

186 187
上記の例は、["fontawesome" パッケージ](http://fontawesome.io/) のためのアセットバンドルを定義するものです。
`beforeCopy` という発行オプションを指定して、`fonts``css` サブディレクトリだけが発行されるようにしています。
188 189


190
### Bower と NPM のアセット <span id="bower-npm-assets"></span>
191 192

ほとんどの JavaScript/CSS パッケージは、[Bower](http://bower.io/) および/または [NPM](https://www.npmjs.org/) によって管理されています。
193
あなたのアプリケーションやエクステンションがそのようなパッケージを使っている場合は、以下のステップに従って、ライブラリの中のアセットを管理することが推奨されます。
194 195

1. アプリケーションまたはエクステンションの `composer.json` ファイルを修正して、パッケージを `require` のエントリに入れます。
196
   ライブラリを参照するのに、`bower-asset/PackageName` (Bower パッケージ) または `npm-asset/PackageName` (NPM パッケージ) を使わなければなりません。
197 198 199 200
2. アセットバンドルクラスを作成して、アプリケーションまたはエクステンションで使う予定の JavaScript/CSS ファイルをリストに挙げます。
   [[yii\web\AssetBundle::sourcePath|sourcePath]] プロパティは、`@bower/PackageName` または `@npm/PackageName` としなければなりません。
   これは、Composer が Bower または NPM パッケージを、このエイリアスに対応するディレクトリにインストールするためです。

201 202 203
> Note|注意: パッケージの中には、全ての配布ファイルをサブディレクトリに置くものがあります。
  その場合には、そのサブディレクトリを [[yii\web\AssetBundle::sourcePath|sourcePath]] の値として指定しなければなりません。
  例えば、[[yii\web\JqueryAsset]] は `@bower/jquery` ではなく `@bower/jquery/dist` を使います。
204 205


206
## アセットバンドルを使う <span id="using-asset-bundles"></span>
207

208 209
アセットバンドルを使うためには、[[yii\web\AssetBundle::register()]] メソッドを呼んでアセットバンドルを [ビュー](structure-views.md) に登録します。
例えば、次のようにしてビューテンプレートの中でアセットバンドルを登録することが出来ます。
210 211 212 213 214 215

```php
use app\assets\AppAsset;
AppAsset::register($this);  // $this はビューオブジェクトを表す
```

216
> Info|情報: [[yii\web\AssetBundle::register()]] メソッドは、[[yii\web\AssetBundle::basePath|basePath]] や [[yii\web\AssetBundle::baseUrl|baseUrl]] など、発行されたアセットに関する情報を含むアセットバンドルオブジェクトを返します。
217

218 219
他の場所でアセットバンドルを登録しようとするときは、必要とされるビューオブジェクトを提供しなければなりません。
例えば、[ウィジェット](structure-widgets.md) クラスの中でアセットバンドルを登録するためには、`$this->view` によってビューオブジェクトを取得することが出来ます。
220

221 222 223 224
アセットバンドルがビューに登録されるとき、舞台裏では、依存している全てのアセットバンドルが Yii によって登録されます。
そして、アセットバンドルがウェブからはアクセス出来ないディレクトリに配置されている場合は、アセットバンドルがウェブディレクトリに発行されます。
その後、ビューがページをレンダリングするときに、登録されたバンドルのリストに挙げられている CSS と JavaScript ファイルのための `<link>` タグと `<script>` タグが生成されます。
これらのタグの順序は、登録されたバンドル間の依存関係、および、[[yii\web\AssetBundle::css]] と [[yii\web\AssetBundle::js] のプロパティのリストに挙げられたアセットの順序によって決定されます。
225 226


227
### アセットバンドルをカスタマイズする <span id="customizing-asset-bundles"></span>
228

229
Yii は、[[yii\web\AssetManager]] によって実装されている `assetManager` という名前のアプリケーションコンポーネントを通じてアセットバンドルを管理します。
230
[[yii\web\AssetManager::bundles]] プロパティを構成することによって、アセットバンドルの振る舞いをカスタマイズすることが出来ます。
231 232 233
例えば、デフォルトの [[yii\web\JqueryAsset]] アセットバンドルはインストールされた jQuery の Bower パッケージにある `jquery.js` ファイルを使用します。
あなたは、可用性とパフォーマンスを向上させるために、Google によってホストされたバージョンを使いたいと思うかも知れません。
次のように、アプリケーションの構成情報で `assetManager` を構成することによって、それが達成できます。
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252

```php
return [
    // ...
    'components' => [
        'assetManager' => [
            'bundles' => [
                'yii\web\JqueryAsset' => [
                    'sourcePath' => null,   // バンドルを発行しない
                    'js' => [
                        '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
                    ]
                ],
            ],
        ],
    ],
];
```

253 254
複数のアセットバンドルも同様に [[yii\web\AssetManager::bundles]] によって構成することが出来ます。
配列のキーは、アセットバンドルのクラス名 (最初のバックスラッシュを除く) とし、配列の値は、対応する [構成情報配列](concept-configurations.md) とします。
255

256 257
> Tip|ヒント: アセットバンドルの中で使うアセットを条件的に選択することが出来ます。
> 次の例は、開発環境では `jquery.js` を使い、そうでなければ `jquery.min.js` を使う方法を示すものです。
258 259 260 261 262 263 264 265 266 267
>
> ```php
> 'yii\web\JqueryAsset' => [
>     'js' => [
>         YII_ENV_DEV ? 'jquery.js' : 'jquery.min.js'
>     ]
> ],
> ```

無効にしたいアセットバンドルの名前に `false` を結びつけることによって、一つまたは複数のアセットバンドルを無効にすることが出来ます。
268 269 270
無効にされたアセットバンドルをビューに登録した場合は、依存するバンドルは一つも登録されません。
また、ビューがページをレンダリングするときも、バンドルの中のアセットは一つもインクルードされません。
例えば、[[yii\web\JqueryAsset]] を無効化するために、次の構成情報を使用することが出来ます。
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

```php
return [
    // ...
    'components' => [
        'assetManager' => [
            'bundles' => [
                'yii\web\JqueryAsset' => false,
            ],
        ],
    ],
];
```
[[yii\web\AssetManager::bundles]] を `false` にセットすることによって、*全て* のバンドルを無効にすることも出来ます。


287
### アセットマッピング <span id="asset-mapping"></span>
288 289

時として、複数のアセットバンドルで使われている 正しくない/互換でない アセットファイルパスを「修正」したい場合があります。
290 291 292
例えば、バンドル A がバージョン 1.11.1 の `jquery.min.js` を使い、バンドル B がバージョン 2.1.1 の `jquery.js` を使っているような場合です。
それぞれのバンドルをカスタマイズすることで問題を修正することも出来ますが、それよりも簡単な方法は、*アセットマップ* 機能を使って、正しくないアセットを望ましいアセットに割り付けることです。
そうするためには、以下のように [[yii\web\AssetManager::assetMap]] プロパティを構成します。
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307

```php
return [
    // ...
    'components' => [
        'assetManager' => [
            'assetMap' => [
                'jquery.js' => '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
            ],
        ],
    ],
];
```

[[yii\web\AssetManager::assetMap|assetMap]] のキーは修正したいアセットの名前であり、値は望ましいアセットのパスです。
308 309 310
アセットバンドルをビューに登録するとき、[[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] の配列に含まれるすべてのアセットファイルの相対パスがこのマップと突き合わせて調べられます。
キーのどれかがアセットファイルのパス (利用できる場合は、[[yii\web\AssetBundle::sourcePath]] が前置されます) の最後の部分と一致した場合は、対応する値によってアセットが置き換えられ、ビューに登録されます。
例えば、`my/path/to/jquery.js` というアセットファイルは `jquery.js` というキーにマッチします。
311

312 313
> Note|注意: 相対パスを使って指定されたアセットだけがアセットマッピングの対象になります。
  そして、置き換える側のアセットのパスは、絶対 URL であるか、[[yii\web\AssetManager::basePath]] からの相対パスであるかの、どちらかでなければなりません。
314 315


316
### アセット発行 <span id="asset-publishing"></span>
317

318 319
既に述べたように、アセットバンドルがウェブからアクセス出来ないディレクトリに配置されている場合は、バンドルがビューに登録されるときに、アセットがウェブディレクトリにコピーされます。
このプロセスは *アセット発行* と呼ばれ、[[yii\web\AssetManager|アセットマネージャ]] によって自動的に実行されます。
320

321
デフォルトでは、アセットが発行されるディレクトリは `@webroot/assets` であり、`@web/assets` という URL に対応するものです。
322
この場所は、[[yii\web\AssetManager::basePath|basePath]] と [[yii\web\AssetManager::baseUrl|baseUrl]] のプロパティを構成してカスタマイズすることが出来ます。
323 324

ファイルをコピーすることでアセットを発行する代りに、OS とウェブサーバが許容するなら、シンボリックリンクを使うことを考慮しても良いでしょう。
325
この機能は [[yii\web\AssetManager::linkAssets|linkAssets]] を true にセットすることで有効にすることが出来ます。
326 327 328 329 330 331 332 333 334 335 336 337

```php
return [
    // ...
    'components' => [
        'assetManager' => [
            'linkAssets' => true,
        ],
    ],
];
```

338 339
上記の構成によって、アセットマネージャはアセットバンドルを発行するときにソースパスへのシンボリックリンクを作成するようになります。
この方がファイルのコピーより速く、また、発行されたアセットが常に最新であることを保証することも出来ます。
340 341


342
## よく使われるアセットバンドル <span id="common-asset-bundles"></span>
343

344 345
コアの Yii コードは多くのアセットバンドルを定義しています。
その中で、下記のバンドルはよく使われるものであり、あなたのアプリケーションやエクステンションのコードでも参照することが出来るものです。
346

347
- [[yii\web\YiiAsset]]: 主として `yii.js` ファイルをインクルードするためのバンドルです。
348
  このファイルはモジュール化された JavaScript のコードを編成するメカニズムを実装しています。
349
  また、`data-method``data-confirm` の属性に対する特別なサポートや、その他の有用な機能を提供します。
350 351
- [[yii\web\JqueryAsset]]: jQuery の bower パッケージから `jquery.js` ファイルをインクルードします。
- [[yii\bootstrap\BootstrapAsset]]: Twitter Bootstrap フレームワークから CSS ファイルをインクルードします。
352
- [[yii\bootstrap\BootstrapPluginAsset]]: Bootstrap JavaScript プラグインをサポートするために、Twitter Bootstrap フレームワークから JavaScript ファイルをインクルードします。
353 354
- [[yii\jui\JuiAsset]]: jQuery UI ライブラリから CSS と JavaScript のファイルをインクルードします。

355 356
あなたのコードが、jQuery や jQuery UI または Bootstrap に依存する場合は、自分自身のバージョンを作るのではなく、これらの定義済みのアセットバンドルを使用すべきです。
これらのバンドルのデフォルトの設定があなたの必要を満たさない時は、[アセットバンドルをカスタマイズする](#customizing-asset-bundles) の項で説明したように、それをカスタマイズすることが出来ます。
357 358


359
## アセット変換 <span id="asset-conversion"></span>
360

361 362 363
直接に CSS および/または JavaScript のコードを書く代りに、何らかの拡張構文を使って書いたものを特別なツールを使って CSS/JavaScript に変換する、ということを開発者はしばしば行います。
例えば、CSS コードのためには、[LESS](http://lesscss.org/)[SCSS](http://sass-lang.com/) を使うことが出来ます。
また、JavaScript のためには、[TypeScript](http://www.typescriptlang.org/) を使うことが出来ます。
364

365 366
拡張構文を使ったアセットファイルをアセットバンドルの中の [[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のリストに挙げることが出来ます。
例えば、
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385

```php
class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.less',
    ];
    public $js = [
        'js/site.ts',
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}
```

386 387
このようなアセットバンドルをビューに登録すると、[[yii\web\AssetManager|アセットマネージャ]] が自動的にプリプロセッサツールを走らせて、認識できた拡張構文のアセットを CSS/JavaScript に変換します。
最終的にビューがページをレンダリングするときには、ビューは元の拡張構文のアセットではなく、変換後の CSS/JavaScript ファイルをページにインクルードします。
388 389 390 391 392 393 394 395 396

Yii はファイル名の拡張子を使って、アセットが使っている拡張構文を識別します。デフォルトでは、下記の構文とファイル名拡張子を認識します。

- [LESS](http://lesscss.org/): `.less`
- [SCSS](http://sass-lang.com/): `.scss`
- [Stylus](http://learnboost.github.io/stylus/): `.styl`
- [CoffeeScript](http://coffeescript.org/): `.coffee`
- [TypeScript](http://www.typescriptlang.org/): `.ts`

397 398
Yii はインストールされたプリプロセッサツールに頼ってアセットを変換します。
例えば、[LESS](http://lesscss.org/) を使うためには、`lessc` プリプロセッサコマンドをインストールしなければなりません。
399

400
下記のように [[yii\web\AssetManager::converter]] を構成することで、プリプロセッサコマンドとサポートされる拡張構文をカスタマイズすることが出来ます。
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418

```php
return [
    'components' => [
        'assetManager' => [
            'converter' => [
                'class' => 'yii\web\AssetConverter',
                'commands' => [
                    'less' => ['css', 'lessc {from} {to} --no-color'],
                    'ts' => ['js', 'tsc --out {to} {from}'],
                ],
            ],
        ],
    ],
];
```

上記においては、サポートされる拡張構文が [[yii\web\AssetConverter::commands]] プロパティによって定義されています。
419 420
配列のキーはファイルの拡張子 (先頭のドットは省く) であり、配列の値は結果として作られるアセットファイルの拡張子とアセット変換を実行するためのコマンドです。
コマンドの中の `{from}``{to}` のトークンは、ソースのアセットファイルのパスとターゲットのアセットファイルのパスに置き換えられます。
421

422 423 424
> Info|情報: 上記で説明した方法の他にも、拡張構文のアセットを扱う方法はあります。
  例えば、[grunt](http://gruntjs.com/) のようなビルドツールを使って、拡張構文のアセットをモニターし、自動的に変換することが出来ます。
  この場合は、元のファイルではなく、結果として作られる CSS/JavaScript ファイルをアセットバンドルのリストに挙げなければなりません。
425 426


427
## アセットを結合して圧縮する <span id="combining-compressing-assets"></span>
428

429 430 431
ウェブページは数多くの CSS および/または JavaScript ファイルをインクルードすることがあり得ます。
HTTP リクエストの数とこれらのファイルの全体としてのダウンロードサイズを削減するためによく用いられる方法は、複数の CSS/JavaScript ファイルを結合して圧縮し、一つまたはごく少数のファイルにまとめることです。
そして、ウェブページでは元のファイルをインクルードする代りに、圧縮されたファイルをインクルードする訳です。
432
 
433
> Info|情報: アセットの結合と圧縮は、通常はアプリケーションが本番モードにある場合に必要になります。
434
  開発モードにおいては、たいていは元の CSS/JavaScript ファイルを使う方がデバッグのために好都合です。
435 436 437 438 439 440

次に、既存のアプリケーションコードを修正する必要なしに、アセットファイルを結合して圧縮する方法を紹介します。

1. アプリケーションの中で、結合して圧縮する予定のアセットバンドルを全て探し出す。
2. これらのバンドルを一個か数個のグループにまとめる。どのバンドルも一つのグループにしか属することが出来ないことに注意。
3. 各グループの CSS ファイルを一つのファイルに結合/圧縮する。JavaScript ファイルに対しても同様にこれを行う。
441 442
4. 各グループに対して新しいアセットバンドルを定義する。
   * [[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のプロパティに、それぞれ、結合された CSS ファイルと JavaScript ファイルをセットする。
443
   * 各グループに属する元のアセットバンドルをカスタマイズして、[[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のプロパティを空にし、[[yii\web\AssetBundle::depends|depends]] プロパティにグループのために作られた新しいバンドルを指定する。
444

445 446
この方法を使うと、ビューでアセットバンドルを登録したときに、元のバンドルが属するグループのための新しいアセットバンドルが自動的に登録されるようになります。
そして、結果として、結合/圧縮されたアセットファイルが、元のファイルの代りに、ページにインクルードされます。
447 448


449
### 一例 <span id="example"></span>
450 451 452

上記の方法をさらに説明するために一つの例を挙げましょう。

453 454
あなたのアプリケーションが二つのページ、X と Y を持つと仮定します。
ページ X はアセットバンドル A、B、C を使用し、ページ Y はアセットバンドル B、C、D を使用します。
455 456

これらのアセットバンドルを分割する方法は二つあります。一つは単一のグループを使用して全てのアセットバンドルを含める方法です。
457 458 459 460
もう一つは、A をグループ X に入れ、D をグループ Y に入れ、そして、B と C をグループ S に入れる方法です。どちらが良いでしょう? 場合によります。
最初の方法の利点は、二つのページが同一の結合された CSS と JavaScript のファイルを共有するため、HTTP キャッシュの効果が高くなることです。
その一方で、単一のグループが全てのバンドルを含むために、結合された CSS と JavaScript のファイルはより大きくなり、従って最初のファイル転送時間はより長くなります。
この例では話を簡単にするために、最初の方法、すなわち、全てのバンドルを含む単一のグループを使用することにします。
461

462 463 464
> Info|情報: アセットバンドルをグループに分けることは些細な仕事ではありません。
  通常、そのためには、いろいろなページのさまざまなアセットの現実世界での転送量を分析することが必要になります。
  とりあえず、最初は、簡単にするために、単一のグループから始めて良いでしょう。
465

466 467 468
既存のツール (例えば [Closure Compiler](https://developers.google.com/closure/compiler/)[YUI Compressor](https://github.com/yui/yuicompressor/)) を使って、全てのバンドルにある CSS と JavaScript のファイルを結合して圧縮します。
ファイルは、バンドル間の依存関係を満たす順序に従って結合しなければならないことに注意してください。
例えば、バンドル A が B に依存し、B が C と D の両方に依存している場合は、アセットファイルの結合順は、最初に C と D、次に B、そして最後に A としなければなりません。
469

470 471 472
結合と圧縮が完了すると、一つの CSS ファイルと一つの JavaScript ファイルが得られます。
それらは、`all-xyz.css` および `all-xyz.js` と命名されたとしましょう。
ここで `xyz` は、ファイル名をユニークにして HTTP キャッシュの問題を避けるために使用されるタイムスタンプまたはハッシュを表します。
473

474 475
いよいよ最終ステップです。
アプリケーションの構成情報の中で、[[yii\web\AssetManager|アセットマネージャ]] を次のように構成します。
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498

```php
return [
    'components' => [
        'assetManager' => [
            'bundles' => [
                'all' => [
                    'class' => 'yii\web\AssetBundle',
                    'basePath' => '@webroot/assets',
                    'baseUrl' => '@web/assets',
                    'css' => ['all-xyz.css'],
                    'js' => ['all-xyz.js'],
                ],
                'A' => ['css' => [], 'js' => [], 'depends' => ['all']],
                'B' => ['css' => [], 'js' => [], 'depends' => ['all']],
                'C' => ['css' => [], 'js' => [], 'depends' => ['all']],
                'D' => ['css' => [], 'js' => [], 'depends' => ['all']],
            ],
        ],
    ],
];
```

499 500 501 502 503
[アセットバンドルをカスタマイズする](#customizing-asset-bundles) の項で説明したように、上記の構成によって元のバンドルは全てデフォルトの振る舞いを変更されます。
具体的にいえば、バンドル A、B、C、D は、もはやアセットファイルを一つも持っていません。
この4つは、それぞれ、結合された `all-xyz.css``all-xyz.js` ファイルを持つ `all` バンドルに依存するようになりました。
結果として、ページ X では、バンドル A、B、C から元のソースファイルをインクルードする代りに、これら二つの結合されたファイルだけがインクルードされます。
同じことはページ Y でも起ります。
504

505 506 507
最後にもう一つ、上記の方法をさらにスムーズに運用するためのトリックがあります。
アプリケーションの構成情報ファイルを直接修正する代りに、バンドルのカスタマイズ用の配列を独立したファイルに置いて、条件によってそのファイルをアプリケーションの構成情報にインクルードすることが出来ます。
例えば、
508 509 510 511 512 513 514 515 516 517 518

```php
return [
    'components' => [
        'assetManager' => [
            'bundles' => require(__DIR__ . '/' . (YII_ENV_PROD ? 'assets-prod.php' : 'assets-dev.php')),  
        ],
    ],
];
```

519
つまり、アセットバンドルの構成情報配列は、本番モードのものは `assets-prod.php` に保存し、開発モードのものは `assets-dev.php` に保存するという訳です。
520 521


522
### `asset` コマンドを使う <span id="using-asset-command"></span>
523 524 525

Yii は、たった今説明した方法を自動化するための `asset` という名前のコンソールコマンドを提供しています。

526 527
このコマンドを使うためには、最初に構成情報ファイルを作成して、どのアセットバンドルが結合されるか、そして、それらがどのようにグループ化されるかを記述しなければなりません。
`asset/template` サブコマンドを使って最初にテンプレートを生成し、それをあなたの要求に合うように修正することが出来ます。
528 529 530 531 532

```
yii asset/template assets.php
```

533
上記のコマンドは、カレントディレクトリに `assets.php` というファイルを生成します。このファイルの内容は以下のようなものです。
534 535 536 537

```php
<?php
/**
538
 * "yii asset" コンソールコマンドのための構成情報ファイル
539
 * コンソール環境では、'@webroot' や '@web' のように、存在しないパスエイリアスがあり得ることに注意してください。
540 541 542
 * これらの欠落したパスエイリアスは手作業で定義してください。
 */
return [
543
    // JavaScript ファイルの圧縮のためのコマンド/コールバックを調整。
544
    'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to}',
545
    // CSS ファイルの圧縮のためのコマンド/コールバックを調整。
546
    'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}',
547
    // 圧縮するアセットバンドルのリスト。
548 549 550 551
    'bundles' => [
        // 'yii\web\YiiAsset',
        // 'yii\web\JqueryAsset',
    ],
552
    // 圧縮出力用のアセットバンドル。
553 554 555 556 557 558 559 560 561
    'targets' => [
        'all' => [
            'class' => 'yii\web\AssetBundle',
            'basePath' => '@webroot/assets',
            'baseUrl' => '@web/assets',
            'js' => 'js/all-{hash}.js',
            'css' => 'css/all-{hash}.css',
        ],
    ],
562
    // アセットマネージャの構成情報
563 564 565 566 567 568
    'assetManager' => [
    ],
];
```

このファイルを修正して、どのバンドルを結合するつもりであるかを `bundles` オプションで指定しなければなりません。
569 570
`targets` オプションでは、バンドルがどのようにグループに分割されるかを指定しなければなりません。
既に述べたように、一つまたは複数のグループを定義することが出来ます。
571

572
> Note|注意: パスエイリアス `@webroot` および `@web` はコンソールアプリケーションでは利用できませんので、これらは構成情報の中で明示的に定義しなければなりません。
573

574
JavaScript ファイルは結合され、圧縮されて `js/all-{hash}.js` に保存されます。ここで {hash} は、結果として作られたファイルのハッシュで置き換えられるものです。
575

576
`jsCompressor``cssCompressor` のオプションは、JavaScript と CSS の結合/圧縮を実行するコンソールコマンドまたは PHP コールバックを指定するものです。
577
デフォルトでは、Yii は JavaScript ファイルの結合に [Closure Compiler](https://developers.google.com/closure/compiler/) を使い、CSS ファイルの結合に [YUI Compressor](https://github.com/yui/yuicompressor/) を使用します。
578
あなたの好みのツールを使うためには、手作業でツールをインストールしたり、オプションを修正したりしなければなりません。
579

580
この構成情報ファイルを使い、`asset` コマンドを走らせて、アセットファイルを結合して圧縮し、同時に、新しいアセットバンドルの構成情報ファイル `assets-prod.php` を生成することが出来ます。
581 582 583 584 585
 
```
yii asset assets.php config/assets-prod.php
```

586
直前の項で説明したように、この生成された構成情報ファイルをアプリケーションの構成情報にインクルードすることが出来ます。
587 588 589


> Info|情報: `asset` コマンドを使うことは、アセットの結合・圧縮のプロセスを自動化する唯一の選択肢ではありません。
Nobuo Kihara committed
590
  優秀なタスク実行ツールである [grunt](http://gruntjs.com/) を使っても、同じ目的を達することが出来ます。