hightman
(Hightman)
October 20, 2010, 6:54am
1
扩展下载及说明页:http://www.yiiframework.com/extension/eclientscript/
它是核心类 CClientScript 的一个简要扩展,使其自动具备将多个SCRIPT或CSS文件合并成一个的能力,这将有助于节省HTTP连接,在正式上线时显得尤其重要,像YII新版主页也是采用了合并技术。
关于这个扩展,本来有找到一个类似的扩展了,但真正使用时发现BUG太多了,而无法容忍的是它的实现过于复杂,很多地方重复编码,而且其中的CACHE设计也不是很恰当。更为主要的是当一个WEB应用中不同的地方包含了不同的css和script后,它无法正确区分,而仅仅是统一一个文件名,还有就是如果本来CSS中带有相对路径的图片引用(url()语法),那么合并后将无法正确显示。
我这个扩展将这些问题都解决了,而且简化的大量的编码,尽可能的调用父类的方法,欢迎使用,有任何问题可在此跟贴。
使用这个扩展不必修改原有的任何代码,只需要在 config/main.php 中将 EClientScript 指定为 clientScript 组件所使用的类并增加合并属性即可,原来用法中的的 registerCssFile(), registerScriptFile()均不变。
已知的问题:
当您调用的css或script文件不在web应用的根目录之下的话,那么Eclientscript将不会合并它而是保留原来的调用方式,所以在这种情况下外部引用的文件可能和合并后的文件次序发生变化,当且仅当你的脚本恰恰依赖相应的加载顺序,那么可能会产生问题。举个例子,原有以下代码
<script src="/js/a.js"></script>
<script src="http://www.google.com/g.js "></script>
<script src="/js/b.js"></script>
经过合并后可能变成
<script src="http://www.google.com/g.js "></script>
<script src="/assets/script-0-xxxxx.js"></script> (a.js+b.js)
那么原本如果在 g.js 中的脚本依赖了 a.js ,合并后次序变掉了,就可能会出错,不过这种情况应当比较少。
DavidHHuan
(Davidhhuan)
December 12, 2010, 4:32pm
3
Hello, hightman.
你的插件很实际啊,不过哦,有个建议,
就是关于getLocalPath($url)
因为有时候会用到theme的嘛,然后嘛,那些css和js啊,可能会放到theme里面,形成这样的目录
| |~themes/
| | `~classic/
| | |+css/
| | |+images/
| | |+js/
| | `+views/
所以呢,想你在下一个版本里面加多个参数用来判断是否该文件是在theme里面的,比如说,这样
public $useTheme;
然后在getLocalPath里面作个判断然后处理
$baseUrl = $useTheme ? Yii::app()->theme->baseUrl . ‘/’ : Yii::app()->request->baseUrl . ‘/’;
hightman
(Hightman)
December 13, 2010, 8:59am
5
谢谢, 这个应当不需要加属性来判断,直接拿 Yii::app()->theme 即可判断了
已作修改,下一版本一起发布,相当于加入theme的URL和PATH检测~ 如有需要可以参照下面的代码先调整。
增加代码
/**
* @var local base path & url
*/
private $_baseUrlMap = array();
/**
* init
*/
public function init()
{
// request
$baseUrl = Yii::app()->request->baseUrl . '/';
$basePath = dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR;
$this->_baseUrlMap[$baseUrl] = $basePath;
// themes
if (Yii::app()->theme)
{
$basePath = Yii::app()->theme->basePath . DIRECTORY_SEPARATOR;
$baseUrl = Yii::app()->theme->baseUrl . '/';
$this->_baseUrlMap[$baseUrl] = $basePath;
}
parent::init();
}
修改 getLocalPath
/**
* Get realpath of published file via its url, refer to {link: CAssetManager}
* @return string local file path for this script or css url
*/
private function getLocalPath($url)
{
foreach ($this->_baseUrlMap as $baseUrl => $basePath)
{
if (!strncmp($url, $baseUrl, strlen($baseUrl)))
return $basePath . substr($url, strlen($baseUrl));
}
return false;
}
miles
(Cuiming2355 Cn)
March 5, 2011, 6:55am
7
我们在使用nginx_concat_module配合自定义的ClientScript实现js及css合并
Apache也有类似的module
合并后的效果在www.shenbian.com的源码头部查看
nginx_concat_module地址:http://code.taobao.org/project/view/59/