阿江 2017-10-08 17:20:26 7126次浏览 0条回复 2 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-structure-assets.html

本文主题:资源(Assets)

Yii中的资源(Assets)是指将被网页引用的文件,它可以是CSS文件、JavaScript文件、一个图片或视频文件等。资源位于网站可访问目录,并由Web服务器直接提供的。

使用编程方式来管理资源是更好的方式,例如,当你在网页中使用yii\jui\DatePicker小部件,它将自动包含所需的CSS和JavaScript文件,而不是要求你去手动找到并包含它们。当你升级小部件到一个新版本时,它将怎么使用资源的新版本。在本教程中,我们将描述Yii提供的强大的资源管理功能。

1、Asset Bundles(资源集)

Yii以资源集(asset bundle)为单位对资源进行管理,一个资源集是位于同一个目录中的资源的集合。当你在视图中注册一个资源集时,它会将渲染的文件中所有的CSS和JavaScript文件放到资源集中去。

2、Defining Asset Bundles(定义资源集)

资源集被定义为继承自yii\web\AssetBundle的PHP类,资源集的名称就是对应的PHP类名全称,没有前导反斜杠。一个资源集类可以被自动加载,它通常定义了资源的位置,包含哪些CSS和JavaScript文件,这些资源依赖于哪些资源。

以下代码定义了基础模板中使用到的主要资源集:

<?php
namespace app\assets;
use yii\web\AssetBundle;
class AppAsset entends AssetBundle{
	public $basePath='@webroot';
	public $baseUrl='@web';//空
	public $css=[
		'css/site.css',
	];
	public $js=[];
	public $depends=[
		'yii\ewb\YiiAsset',
		'yii\bootstrap\BootstrapAsset',
	];
}

//查看webroot和web D:\phpwork\news\controllers\SiteController.php

    public function actionIndex()
    {
        echo "<br><br><br><br><br>@webroot:".Yii::getAlias('@webroot').":AA";
        echo "<br>@web:".Yii::getAlias('@web').":AA";
        /*
		http://localhost:8085/
        @webroot:D:/phpwork/news/web:AA
        @web::AA
        */
        return $this->render('index');
    }

上面的AppAsset类定义了@webroot目录下的资源文件,对应的网站访问路径URL是@web;这个资源集包含了一个CSS文件css/site.css,没有JavaScript文件;资源集依赖于两个其他资源集:yii\web\YiiAsset和yii\bootstrap\BootstrapAssets,关于yii\web\AssetBundle的属性详细描述如下: 1、sourcePath,定义资源集的根目录。如果此根目录非Web可访问,此属性应被设置;否则,你应设置basePath和baseUrl属性。这里可以使用路径别名(Path aliases)。

http://www.yiiframework.com/doc-2.0/yii-web-assetbundle.html#$sourcePath-detail

2、basePath:定义一个Web可访问目录,此目录将是资源集包含资源文件的地方。当你定义了sourcePath属性时,资源管理器将发布此资源集中的资源到Web方式访问的目录,并相应的覆盖此属性。如果你的资源文件已存放于Web可访问目录且不需要进行资源发布,你应设置此属性。此处可以使用路径别名。 3、baseUrl:定义与basePath相对应的URL,与basePath相似,如果你定义了sourcePath属性,资源管理器将发布资源并覆盖此属性。此处可以使用路径别名。 4、js:资源集中包含的JavaScript文件列表数组。注意目录分隔符只能使用斜杠"/"。每个JavaScript文件可以被定义为以下两种格式之一:

1)一个表示本地JavaScript文件的相对路径(如js/main.js),文件的实际路径将在相对路径前添加yii\web\AssetManager::$basePath ,文件的实际URL可以则是在相对路径前添加yii\web\AssetManager::$baseUrl 。
2)一个表示外部JavaScript文件的绝对URL,例如: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

5、css:资源集中包含的CSS文件列表数组。数组中的文件格式与js的相同。 6、depends:资源集依赖的资源集列表数组。 7、jsOptions:调用yii\web\View::registerJsFile()方法注册资源集中的每一个JavaScript文件时所需的参数由此定义。 8、cssOptions:调用yii\web\View::registerCssFile()方法注册资源集中的每一个CSS文件时所需的参数由此定义。 9、publicOptions:调用yii\web\AssetManager::publish()方法发布资源的源文件时所需的参数由此定义。当你定义了sourcePath属性时才会使用此属性。

Asset Locations(资源位置)

根据资源的位置可以归类如下: 1、源资源:资源文件与PHP源代码混在一起,不能被Web直接访问。为了能够在网页中使用源资源,它们将被拷贝到一个Web目录,并转为所谓的已发布资源。这个过程被称为资源发布(asset publishing)。 2、发布的资源:资源文件位于Web目录,这样可以被Web直接访问。 3、外部资源:资源文件位于另一个Web服务器上,与你的Web应用所在的服务器不同位置。

当定义了一个资源集类时,如果你定义了sourcePath属性,就意味着使用相对路径的资源都将被视为源资源。如果你没有定义此属性,这些资源将被视为已发布资源(此时你应该定义basePath和baseUrl来让Yii知道它们在哪里)。 推荐将属于应用的资源都存放到一个Web目录中以避免不必要的资源发布处理,这也是前例中AppAsset为什么定义basePath而不是sourcePath的原因。 对于Yii的扩展,因为它们的资源与代码在一起,都在非Web可访问目录中,因此为他们定义资源集时,你必须定义sourcePath属性。 注意:不要使用@webroot/assets作为源路径,此目录是资源管理器(asset manager)将源资源转为资源文件时的默认存储目录,此目录中的任何内容都被视为临时文件,被视为可移动的。

Asset Dependencies(资源依赖)

当一个Web页面中包含多个CSS或JavaScript文件时,它们遵循特定顺序以避免出现严重的问题,例如,如果你在页面中使用jQuery UI小部件,你应确保jQuery脚本文件在jQuery UI脚本文件之前被包含进来,我们称这种顺序为资源依赖。

资源依赖主要是通过yii\web\AssetBundle::$depends 属性来定义,在AppAsset示例中,资源集依赖于另外两个资源集:yii\web\YiiAsset和yii\bootstrap\bootstrapAsset,也就是说AppAsset中的CSS和JavaScript文件将在两个依赖的资源集之后被包含进来。

资源依赖是可传递的,也就是说如果资源A依赖于B,B依赖C,A将会依赖C。

Asset Options(资源选项)

你可以定义cssOptions和jsOptions属性为页面包含CSS和JavaScript文件指定自定义的方式,当视图包含CSS和JavaScript文件时,将调用yii\web\View::registerCssFile()和yii\web\View::reggisterJsFile()方法,这些属性值也将分别被传递进来。

注意:你在一个资源集类中设置的选项将被应用到资源集的每一个CSS/JavaScript文件。如果你要为不同的文件设置不同的选项,你应创建单独的资源集,并在每个资源集中使用各自的选项。

例如,为IE9及更低的版本包含不同的CSS文件,你可以使用以下的选项:

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

这将导致资源集中的CSS文件使用以下HTML标签包含进来:

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

要使用包含生成的CSS连接标签,可以配置cssOptions如下:

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

要在头信息中包含一个JavaScript文件(默认情况下,JavaScript文件被包含在主体部分(body section)的最后),使用以下选项:

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

默认情况下,当一个资源集被发布时,所有定义在yii\web\AssetBundle::$sourcePath 目录中的的内容都将被发布。你可以通过定义publishOptions属性来自定义此行为。例如,要发布yii\web\AssetBundle::$sourcePath 的一个或几个子目录,你可以在资源集类中如下定义:

namespace app\assets;
use yii\web\AssetBundle;
class FontAwesomeAsset extends AssetBundle{
	public $sourcePath='@bower/font-awesome';
	public $css=[
		'css/font-awesome.min.css',
	];
	public $publishOptions=[
		'only'=>[
			'fonts/',
			'css/',
		],
	];
}

上例中为fontawesome包定义了一个资源集,通过定义only发布属性,只有fonts和css子目录将被发布。

Bower and NPM Assets(Bower和NPM资源)

大多数JavaScript/CSS包都是通过Bower和NPM来管理的,如果你的应用或扩展使用了这样的包,推荐你按以下步骤来管理库中的资源: 1、修改应用或扩展的composer.json文件,在require处列出包,你应使用bower-asset/PackageName(Bower包)或npm-asset/PackageName(NPM包)来指定到库。 2、创建资源集类,并列出你将要在应用或扩展中使用的JavaScript/CSS文件。你应定义sourcePath属性为@bower/PackageName或@npm/PackageName。这是因为Composer将在此别名对应的目录中安装Bower或NPM包。

注意:一些包可能将它们的发布文件放在子目录中,此时,你应定义子目录为sourcePath的值,例如:yii\web\JqueryAsset使用@bower/jquery/dist,而不是@bower/jquery。

3、Using Asset Bundles(使用资源集)

要使用一个资源集,需要在视图中调用yii\web\AssetBundle::register()方法来注册它。例如,在视图模板中你需要注册一个资源集,代码如下:

use app\assets\AppAsset;
AppAsset::register($this);//$this是指视图对象

信息:yii\web\AssetBundle::register()方法返回一个资源集对象包含了发布资源集的信息,如basePath或baseUrl。

如果你要在其他地方注册资源集,你应提供必需的视图对象,例如,要在一个小部件类中注册一个资源集,你应使用$this->view来获取视图对象。 当资源集注册到一个视图中时,Yii在后台会注册它所依赖的所有资源集。如果一个资源集是非Web可访问的,它将被发布到一个Web目录中。随后,当视图渲染一个页面时,它将为注册资源集中列出的CSS和JavaScript文件生成和

Dynamic Asset Bundles(动态资源集)

作为一个常规PHP类,资源集可以承受一些与其相关的外部逻辑,也可以动态调整它的内部参数。例如:你可以使用som sophisticated JavaScript库,它以单独文件的方式提供了国际化包,每个包支持一种语言。要使用库的翻译工作正常进行,需要添加特定的'.js'到你的页面中。可以通过重写yii\web\AssetBundle::init()方法来实现它:

namespace app\assets;
use yii\web\AssetBundle;
use Yii;
class SophisticatedAssetBundle extends AssetBundle{
	public $sourcePath='/path/to/sophisticated/src';
	public $js=[
		'sophisticated.js'	//一直被调用的文件
	];
	public function init(){
		parent::init();
		$this->js[]='i18n/'.Yii::$app->language.'.js';//添加的动态文件
	}
}

通过yii\web\AssetBundle::register()返回的实例也可以调整特定的资源集,例如:

use app\assets\SophisticateAssetBundle;
use Yii;
$bundle=SophisticatedAssetBundle::register(Yii::$app->view);
$bundle->js[]='i18n/'.Yii::$app->language.'.js';//添加的动态文件

注意:尽管动态调整资源集是被支持的,但它是一个不好的实践,因为它可能导致不可预期的效果,所以应尽量避免使用它。

Customizing Asset Bundles(自定义资源集)

Yii通过名为assetManager的应用组件来管理资源集,此组件继承自yii\web\AssetManager。通过配置yii\web\AssetManager::$bundles 属性,可以自定义资源集的行为。例如,yii\web\JqueryAsset资源集默认使用已安装的jquery Bower包中的jquery.js文件。要提高可用性和性能,你可以使用Google提供的版本。通过在应用配置中设置assetManager即可实现,代码如下:

return [
    // ...
    'components' => [
        'assetManager' => [
            'bundles' => [
                'yii\web\JqueryAsset' => [
                    'sourcePath' => null,   // do not publish the bundle
                    'js' => [
                        '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
                    ]
                ],
            ],
        ],
    ],
];

你可以通过yii\web\AssetManager::$bundles 配置多个资源集。数组键名是资源集的类名(没有前导反斜杠),键值是对应的配置数组。

小贴士:你可以条件选择使用资源集中的哪些资源,下例将展示在开发环境中使用jquery.js,其他情况下使用jquery.min.js:

'yii\web\JqueryAsset'=>[
	'js'=>[
		YII_ENV_DEV?'jquery.js':'jquery.min.js'
	]
],

你可以设置一个或多个资源集无效,在配置中将相应名称的资源集设置为false即可。当你在页面中注册一个被禁用的资源集时,它所依赖的资源集也不会被注册,在视图渲染的页面中也不会包含任何资源,例如,要禁用yii\web\JqueryAsset,你可以使用以下配置:

return [
	'components'=>[
		'assetManager'=>[
			'bundles'=>[
				'yii\web\JqueryAsset'=>false,
			],
		],
	],
];

你也可以设置yii\web\AssetManager::$bundles 为false来禁用所有的资源集。

记住通过yii\web\AssetManager::$bundles 所做的自定义设置只有当创建资源集时才会被应用,例如,在对象构造状态。这样,在此后所做的任何修改都将覆盖建立在yii\web\AssetManager::$bundles 级的映射。特别的:在yii\web\AssetBundle::init()方法中所做的调整或覆盖注册的资源集对象,将优先覆盖掉AssetManager的配置。下面是这样一个实例:通过yii\web\AssetManager::$bundles 设置的映射将无效:

// Program source code:
namespace app\assets;
use yii\web\AssetBundle;
use Yii;
class LanguageAssetBundle extends AssetBundle
{
    // ...
    public function init()
    {
        parent::init();
        $this->baseUrl = '@web/i18n/' . Yii::$app->language; // can NOT be handled by `AssetManager`!
    }
}
// ...
$bundle = \app\assets\LargeFileAssetBundle::register(Yii::$app->view);
$bundle->baseUrl = YII_DEBUG ? '@web/large-files': '@web/large-files/minified'; // can NOT be handled by `AssetManager`!
// Application config :
return [
    // ...
    'components' => [
        'assetManager' => [
            'bundles' => [
                'app\assets\LanguageAssetBundle' => [
                    'baseUrl' => 'http://some.cdn.com/files/i18n/en' // makes NO effect!
                ],
                'app\assets\LargeFileAssetBundle' => [
                    'baseUrl' => 'http://some.cdn.com/files/large-files' // makes NO effect!
                ],
            ],
        ],
    ],
];
Asset Mapping(资源映射)

有时你可能需要修复在多个资源集中使用的不正确或不兼容的资源文件路径。例如,资源集A使用jquery.min.js版本是1.11.1,资源集B使用jquery.js版本是2.1.1。与使用自定义资源集修复这个问题相比,一个更简便的方法是使用资源映射,将不正确的资源集映射到希望的路径上。配置yii\web\AssetManager:;$assetMap 属性可实现此目标,代码如下:

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

assetMap的键名是你要修复的资源名,键值是希望指向的资源路径。当你为视图注册一个资源集时,在css和js数组中相关联的每个资源集文件都会使用此映射进行检测。如果任何一个键名与资源的最末部分相同,对应的值将替换资源,并为视图注册,例如,资源文件my/path/to/jquery.js与键名jquery.js相匹配。 注意:仅使用相对路径定义的资源提供资源映射。目标资源路径可以是绝对路径或yii\web\AssetManager::$basePath 的相对路径。

Asset Publishing(资源发布)

如前所述,如果一个资源集位于非Web可访问的目录中,当资源集为一个视图注册时,它的资源集将被拷贝到一个Web目录中。这个处理过程被称为资源发布,是由asset manager自动完成的。

默认情况下,资源集被发布到@webroot/assets目录下,对应的URL是@web/assets。可以通过配置basePath和baseUrl来自定义它们的位置。

不使用资源发行中的文件拷贝方法,如果操作系统和Web服务器支持,你可以考虑使用软连接。此特性可以通过设置linkAssets为true来生效。

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

使用上面的配置,当资源被发布时,资源管理器将为资源集的源路径创建一个软连接。这个方法比拷贝要迅速的多,也能确保发布的资源始终是最新的。

Cache Busting(缓存击碎)

对于运行在生产模式的Web应用,为资源和其他静态素材开启HTTP缓存是常规作法。这种作法的缺点是当你修改一个资源并部署到生产环境时,因为HTTP缓存的原因,用户端可能还在使用旧版本。要克服此缺点,你可以使用缓存击碎特性,此特性是2.0.3版本时引入进来的,配置yii\web\AssetManager如下:

return [
	'component'	=>[
		'assetManager'=>[
			'appendTimeStamp'=>true,
		],
	],
];

如上操作后,每个发行资源的URL都会在其后添加修改的时间戳。例如,yii.js的URL可能是 /assets/5515a87c/yii.js?v=1423448645,参数v是yii.js最后修改的时间戳。现在如果你修改了一个资源,它的URL仍会改变,这样客户端就会去查找最新的版本。

4、Commonly Used Asset Bundles(常用资源包)

Yii核心代码中已经定义了一些资源集,其中,以下资源集是经常被引用到你的应用或扩展代码中的:

yii\web\YiiAsset:它主要包括yii.js文件,此文件实现了模块中的JavaScript代码组织机制。它还为data-method和data-confirm提供支持,以及其他特性。关于yii.js的更多信息可以在Client Scripts章节中找到:
	http://www.yiiframework.com/doc-2.0/guide-output-client-scripts.html#yii.js
yii\web\JqueryAsset:它包括从jQuery Bower包中获取的jquery.js文件
yii\bootstrap\BootstrapAsset:它包括从Twitter Bootstrap framework获取的CSS文件
yii\bootstrap\BootstrapPluginAsset:它包括从Twitter Bootstrap frameworks获取的支持Bootstrap JavaScript插件的JS文件。
yii\jui\JuiAsset:它包括从jQuery UI库中获取的CSS和JavaScript文件。

如果你的代码依赖于jQuery、jQuery UI或Bootstrap,你可以使用这些预定的资源集,而不用创建你自己的版本。如果默认设置无法满足你的要求,你可以自定义,请参考后面的Customizing Asset Bundle章节。

5、Asset Conversion(资源转换)

相比与直接编写CSS、JavaScript代码,开发者常编写一些扩展格式,并用特定工具将它们转为CSS/JavaScript。例如,对于CSS代码,你可以使用LESS或SCSS;对于JavaScript你可以使用TypeScript。 你可以在资源集的css和js属性中以扩展格式列出资源文件,例如:

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

当你为视图注册了这样一个资源集时,资源管理器将自动运行预处理工具将识别的扩展格式资源转换为CSS/JavaScript。 当视图最后渲染页面时,它将包含CSS/JavaScript文件到网页中,而不是扩展格式的源资源。 Yii使用扩展文件名来识别资源的扩展格式,默认识别以下格式和扩展文件名:

LESS .less
SCSS .scss
Stylus .styl
CoffeeScript .coffee
TypeScript .ts

Yii依靠已安装的预处理器工具来转换资源。例如要使用LESS你应安装lessc预处理器命令。 你可以配置yii\web\AssetManager::$converter 来自定义预处理器命令和支持的扩展格式,格式如下:

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 属性定义了支持的扩展格式。数组键名是文件扩展名(没有前导点.),键值是结果资源文件扩展名,以及执行资源转换的命令。命令中的标签{form}和{to}将被替换为源资源文件路径和目标资源文件路径。

信息:使用扩展格式的资源除了上面提到的,还有一些其他方法。例如,你可以使用构建工具如grunt查看和自动转换扩展格式资源。在这种情况下,你应在资源集中列出CSS/JavaScript结果文件,而不是原始文件。

6、Combining and Compressing Assets(合并和压缩资源)

一个网页可以包含很多CSS和JavaScript文件,为了减少HTTP请求次数和这些文件的总下载量,一个常用的方法是合并和压缩多个CSS/JavaScript文件到一个或很少的几个文件中,然后在网页中加载这些压缩文件,而不是原始文件。

信息:当应用在生产模式时,合并和压缩资源通常是必须的。在开发模式,为了便于调试使用CSS/JavaScript的原始文件更常见些。

接下来,我们将介绍一个无需修改现存的应用代码就能合并和压缩资源文件的方法:

1、在应用中查找要合并和压缩的所有资源集。
2、将这些资源集分为一组或数组,注意每个资源集只能属于一组。
3、合并、压缩每组中的CSS文件到一个文件中,JavaScript文件也是如此操作。
4、为每组定义一个新资源集:
	1)将合并的CSS和JavaScript文件逐个添加到css和js属性中。
	2)将每组资源集的css和js属性设置为空,将它们的depends属性设置为各组创建的新资源集。

使用此方法,当你为视图注册一个资源集时,它将为原始资源集所属的组自动注册新资源集。这样,合并、压缩的资源文件就被包含到了文件中,而不是原始文件。

An Example(一个例子)

让我们用一个例子来说明上面这个方法。

假设你的应用有两个页面:X和Y。X使用的资源集有A、B和C,Y使用的资源集是B、C和D。

你有两种方法去分割这些资源集,一种是将所有的资源集包含到一个组中,另一种方法是将A放在X组中,D放在Y组中,B、C放到S组中。哪一种更好些?要看情况。第一种方法的优点是两个页面都使用了同一个合并的CSS和JavaScript文件,这样HTTP缓存更有效。另一方面,因为在一组中包含了所有的资源集,合并的CSS和JavaScript文件要大一些,会增加初次文件传输的时间。在本例中为了简化,我们使用第一种方法,也就是使用一组去包含所有的资源集。

信息:分割资源集到组是个琐碎的任务,它需要分析在不同页面中不同资源的真实流量。开始时为了简化,你可以使用一个组。

使用已有的工具(如Closure Compiler,YUI Compressor),去合并和压缩CSS和JavaScript文件到资源集中。文件的合并顺序与资源集中的依赖关系相符,例如,资源集A依赖于B,B依赖于C和D,你应列出资源文件的顺序是:C、D、B、A。

在合并和压缩之后,我们将获取一个CSS文件和一个JavaScript文件,假设它们的名称是all-xyz.css和all-xyz.js,xyz是一个时间戳或一个哈希码,以使此文件名是唯一的从而避免HTTP缓存问题。

我们现在是最后一步了,在应用配置中配置asset manager如下:

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

正如前面Customizing Asset Bundles章节所说的,上述配置更改了每个资源集的默认行为。特别是资源集A、B、C和D不再拥有任何资源文件,它们都依赖于资源集all,all中包含了合并的all-xyz.css和all-xyz.js文件。因此,对于页面X,也不再是从资源集A、B和C中包含原始的源文件了,而是仅包含两个合并的文件:all-xyz.css和all-xyz.js;页面Y也是如此。 这里有一个诀窍可以让此方法运行的更平滑。无需直接修改应用配置文件,你可以将资源集自定义数组放在一个单独文件中,然后在应用配置中条件包含此文件即可。例如:

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

也就是说,针对生产模式的资源集配置数组存放在assets-prod.php,非生产模式的存放在assets-dev.php。

注意:这种资源合并机制是基于yii\web\AssetManager::$bundless 覆盖注册资源集属性的。不管怎样,如前所述,此种特性并不会覆盖资源集调整,也就是会在yii\web\AssetBundle::init()方法中或在资源集注册后执行。在资源合并过程中,你应避免使用这种动态资源集。

Using the asset Command(使用asset命令)

Yii提供了一个控制台命令asset去自动化我们上面描述的这个方法。

要使用此命令,你首先应创建一个配置文件去描述哪些资源集将被合并,以及它们将被怎样分组。你可以使用asset/template子命令去生成一个模板,然后修改它以符合你的需要: yii asset/template assets.php

此命令将在当前目录下生成一个名为assets.php的文件,此文件的内容大致如下:

<?php
/**
 * 控制台命令yii asset的配置文件
 * 注意,在控制台环境中,一些路径别名如'@webroot'和'@web'不存在
 * 请定义这些不存在的路径别名
 */
return [
	// 针对JavaScript文件压缩的调整命令/回调(Adjust command/callback)
    'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to}',
	// 针对CSS文件压缩的调整命令/回调
    'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}',
	// 是否在压缩后删除源资源
    'deleteSource' => false,
	// 要压缩的资源集列表
    'bundles' => [
        // 'yii\web\YiiAsset',
        // 'yii\web\JqueryAsset',
    ],
	// 要压缩输出的资源集(资源分组)
    'targets' => [
        'all' => [
            'class' => 'yii\web\AssetBundle',
            'basePath' => '@webroot/assets',
            'baseUrl' => '@web/assets',
            'js' => 'js/all-{hash}.js',
            'css' => 'css/all-{hash}.css',
        ],
    ],
	//资源管理器配置
    'assetManager' => [
    ],
];

你应修改此文件并在bundles中定义要合并的资源集。在targets选项中你应定义资源集应如何去分组。你可以根据前面介绍的方法去定义一个或多个组。 注意:因为在控制台应用中@webroot和@web别名是无效的,你应在配置中显式定义它们。

//实例,为控制台定义别名: D:\phpwork\news\config\console.php

$config = [
    'aliases' => [
        '@webroot' => "@app/web",
        '@web' => '',
    ],
	...
],

//在控制台获取别名: D:\phpwork\news\commands\HelloController.php

    public function actionIndex($message = 'hello world')
    {
        echo $message . "\n";
        echo "app:".Yii::getAlias('@app')."\n";
        echo "web:".Yii::getAlias('@web')."\n";
        echo "webroot:".Yii::getAlias('@webroot')."\n";
    }

//使用控制台命令获取别名

d:\phpwork\news>yii hello
执行结果:
/*
hello world
app:D:\phpwork\news
web:
webroot:D:\phpwork\news/web
*/
d:\phpwork\news>

JavaScript文件被合并、压缩后写入到js/all-{hash}.js文件,{hash}在结果文件中将使用哈希码进行替换。

执行JavaScript和CSS合并、压缩操作时,针对控制台命令或PHP回调函数可以定义jsCompressor和cssCompressor选项。默认情况下,Yii合并JavaScript文件使用Closure Compiler,合并CSS文件使用YUI Composer。你可以手动安装这些工具,或者调整选项以使用你喜欢的工具。

使用配置文件,你可以运行asset命令合并和压缩资源文件,然后生成一个新的资源集配置文件assets-prod.php。

yii asset assets.php config/assets-prod.php

生成的配置文件能够被包含到应用配置中,将在最后一个章节中描述:

注意:当你通过yii\web\AssetManager::$bundles 或yii\web\AsssetManager::$assetMap 为应用自定义资源集,并要将这个自定义应用到压缩源文件时,你应在资源命令配置文件中将这些选项包含到assetManager部分。

注意:定义压缩源时,你应避免使用参数可能会动态调整的资源集(如在init()方法或注册后),因为它们在压缩后不能正常使用。

信息:使用asset命令不是自动化资源合并和压缩处理的唯一选择。你还可以使用优秀的任务执行工具grunt达到同样的目的。

Group Asset Bundles(资源集分组)

在最后一部分,我们已描述了如何去合并所有的资源集到一个单一文件中,以最小化对应用资源文件的HTTP请求。但在实践中这往往是不现实的。例如,假设你的应用有一个前端,还有一个后端,它们使用了各自的JavaScript和CSS文件。在这种情况下,将两部分的资源集合并到一处是行不通的,因为前端的资源集不能被后端的资源集被使用,当对一个前端页面的请求时发送后端的资源集也将造成对网络带宽的浪费。

为解决以上问题,你可以将资源集分成不同的组,并为每个组合并资源集,以下配置将展示如何分组资源集:

return [
	...
	//对输入资源集进行分组
	'targets'=>[
		'allShared'=>[
			'js'=>'js/all-shared-{hash}.js',
			'css'=>'css/all-shared-{hash}.css',
			'depends'=>[
				//包含前端和后端的所有共享资源
				'yii\web\YiiAsset',
				'app\assets\SharedAsset',
			],
		],
		'allBackEnd'=>[
			'js'=>'js/all-{hash}.js',
			'css'=>'css/all-{hash}.css',
			'depends'=>[
				//仅包含'backend'资源
				'app\assets\AdminAsset',
			],
		],
		'allFronEnd'=>[
			'js'=>'js/all-{hash}.js',
			'css'=>'css/all-{hash}.css',
			'depends'=>[],//包含所有的剩余资源
		],
	],
];

正如你所看到的,资源集被分为三组:allShared、allBackEnds和allFrontEnd,它们每一部分依赖一组资源集。例如,allBackEnd依赖app\assets\AdminAsset,当使用此配置运行asset命令时,它将遵照以上定义合并资源集。

信息:你可以将一个目标资源集的depends留空,这样,这个资源集将依赖于其他目标资源集未依赖的资源集。

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册