• No results found

ASSETS 125 You can list the asset les in extended syntax in the css and js properties

In document yii2-guide.en.pdf (Page 131-135)

Application Structure

3.11. ASSETS 125 You can list the asset les in extended syntax in the css and js properties

of an asset bundle. For example,

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', } ];

When you register such an asset bundle with a view, the asset manager will automatically run the pre-processor tools to convert assets in recognized extended syntax into CSS/JavaScript. When the view nally renders a page, it will include the CSS/JavaScript les in the page, instead of the original assets in extended syntax.

Yii uses the le name extensions to identify which extended syntax an asset is in. By default it recognizes the following syntax and le name ex-tensions:

• LESS27:.less

• SCSS28:.scss

• Stylus29: .styl

• CoeeScript30: .coffee

• TypeScript31: .ts

Yii relies on the installed pre-processor tools to convert assets. For example, to use LESS32 you should install thelessc pre-processor command.

You can customize the pre-processor commands and the supported ex-tended syntax by conguring yii\web\AssetManager::$converter like the following:

126 CHAPTER 3. APPLICATION STRUCTURE

'less' => ['css', 'lessc {from} {to} --no-color'], 'ts' => ['js', 'tsc --out {to} {from}'],

], ], ], ],

];

In the above, we specify the supported extended syntax via the yii\web

\AssetConverter::$commands property. The array keys are the le exten-sion names (without leading dot), and the array values are the resulting asset

le extension names and the commands for performing the asset conversion.

The tokens{from}and{to}in the commands will be replaced with the source asset le paths and the target asset le paths.

Info: There are other ways of working with assets in extended syntax, besides the one described above. For example, you can use build tools such as grunt33 to monitor and automatically convert assets in extended syntax. In this case, you should list the resulting CSS/JavaScript les in asset bundles rather than the original les.

3.11.6 Combining and Compressing Assets

A Web page can include many CSS and/or JavaScript les. To reduce the number of HTTP requests and the overall download size of these les, a common practice is to combine and compress multiple CSS/JavaScript les into one or very few les, and then include these compressed les instead of the original ones in the Web pages.

Info: Combining and compressing assets is usually needed when an application is in production mode. In development mode, using the original CSS/JavaScript les is often more convenient for debugging purposes.

In the following, we introduce an approach to combine and compress asset

les without the need to modify your existing application code.

1. Find all the asset bundles in your application that you plan to combine and compress.

2. Divide these bundles into one or a few groups. Note that each bundle can only belong to a single group.

3. Combine/compress the CSS les in each group into a single le. Do this similarly for the JavaScript les.

33http://gruntjs.com/

3.11. ASSETS 127 4. Dene a new asset bundle for each group:

• Set the css and js properties to be the combined CSS and JavaScript

les, respectively.

• Customize the asset bundles in each group by setting their css and js properties to be empty, and setting their depends property to be the new asset bundle created for the group.

Using this approach, when you register an asset bundle in a view, it causes the automatic registration of the new asset bundle for the group that the original bundle belongs to. And as a result, the combined/compressed asset

les are included in the page, instead of the original ones.

An Example

Let's use an example to further explain the above approach.

Assume your application has two pages, X and Y. Page X uses asset bundles A, B and C, while Page Y uses asset bundles B, C and D.

You have two ways to divide these asset bundles. One is to use a single group to include all asset bundles, the other is to put A in Group X, D in Group Y, and (B, C) in Group S. Which one is better? It depends.

The rst way has the advantage that both pages share the same combined CSS and JavaScript les, which makes HTTP caching more eective. On the other hand, because the single group contains all bundles, the size of the combined CSS and JavaScript les will be bigger and thus increase the initial le transmission time. For simplicity in this example, we will use the

rst way, i.e., use a single group to contain all bundles.

Info: Dividing asset bundles into groups is not trivial task. It usually requires analysis about the real world trac data of var-ious assets on dierent pages. At the beginning, you may start with a single group for simplicity.

Use existing tools (e.g. Closure Compiler34, YUI Compressor35) to combine and compress CSS and JavaScript les in all the bundles. Note that the les should be combined in the order that satises the dependencies among the bundles. For example, if Bundle A depends on B which depends on both C and D, then you should list the asset les starting from C and D, followed by B and nally A.

After combining and compressing, we get one CSS le and one JavaScript

le. Assume they are named asall-xyz.cssandall-xyz.js, wherexyzstands for a timestamp or a hash that is used to make the le name unique to avoid HTTP caching problems.

34https://developers.google.com/closure/compiler/

35https://github.com/yui/yuicompressor/

128 CHAPTER 3. APPLICATION STRUCTURE We are at the last step now. Congure the asset manager as follows in the application conguration:

As explained in the Customizing Asset Bundles subsection, the above cong-uration changes the default behavior of each bundle. In particular, Bundle A, B, C and D no longer have any asset les. They now all depend on theall bundle which contains the combinedall-xyz.cssandall-xyz.jsles.

Consequently, for Page X, instead of including the original source les from Bundle A, B and C, only these two combined les will be included; the same thing happens to Page Y.

There is one nal trick to make the above approach work more smoothly.

Instead of directly modifying the application conguration le, you may put the bundle customization array in a separate le and conditionally include this le in the application conguration. For example,

return [

'components' => [ 'assetManager' => [

'bundles' => require(__DIR__ . '/' . (YII_ENV_PROD ? 'assets-prod.php' : 'assets-dev.php')),

], ]; ],

That is, the asset bundle conguration array is saved inassets-prod.php for production mode, andassets-dev.php for non-production mode.

Using the asset Command

Yii provides a console command namedassetto automate the approach that we just described.

3.11. ASSETS 129

In document yii2-guide.en.pdf (Page 131-135)