请求中的“开源节流”--用smasher来实时压缩前端代码(配合YUI Compressor)
首先,smasher是个什么东东,翻译过来是“粉碎者”的意思,- -!,它是使用PHP写成的一个小工具,可以直接放在线上,实时合并+压缩你的JS和CSS代码。
在一个比较依赖前端代码(比如说前端代码的人工代码量大于后端的人工代码量)的工程中,如何很好地部署前端代码,似乎也是前端们的一项很重要的工作。之前常用(包括现在)的部署工具是Apache Ant配合YUI Compressor来进行前端代码的压缩和部署,但是比较缺少灵活性。
smasher是一个比较轻灵的工具,点击这里进入它的github,和Apache Ant比较相似的是,它也是读取一个配置文件(其实可以根据不同的项目分布,编写不同的smasher入口文件,实例化不同的Smasher对象,再接受不同的参数(通过xml文件来配置),来合并压缩不同的文件(现在仅限于js+css)),然后通过一个入口文件来灵活地应用合并和压缩。为了更加详细的说明,看下原装的小例子吧:(在本地进行了适当的修改,可能和原装的例子有一些小差别,可以点击这里下载修改后的)
文件分布:
从下往上看,smasher_web.php是smasher小工具的入口文件,它可以通过get传值获取部分参数,并且读取本地配置文件smasher.xml。
smasher.php是smasher的主文件,定义了smasher工具类本身。
那个没有后缀名的smasher则是在php命令行下运行的文件(和smasher_web.php几乎完全相同)。
tmp文件夹作为存放临时文件的文件夹。
jars文件夹里面藏着yuicompressor.jar文件(需要本机配置好java运行环境)。
files里面则作为演示用的待压缩的源文件。
看下files文件夹:
对smasher整个结构有个小的认识就可以开始仔细地看看它是怎么实现的了,懂的原理,就能灵活运用,还能再此基础上开发出更加适合自己项目的工具。
smasher.xml
<?xml version="1.0" encoding="utf-8"?>
<smasher>
<!-- 设置缓存文件夹 -->
<temp_dir>tmp/</temp_dir>
<!-- 设置源文件路径 -->
<root_dir>files/</root_dir>
<!-- java bin -->
<java_bin>C:/WINDOWS/system32/java</java_bin>
<!-- YUI Compressor的路径 -->
<yuicompressor>jars/yuicompressor.jar</yuicompressor>
<!-- YUI 每一个group作为一个操作单位,拥有唯一的ID,可以再操作时指定压缩JS或者CSS-->
<group id="yui">
<!-- css -->
<file type="css" src="reset.css" />
<file type="css" src="fonts.css" />
<!-- js -->
<file type="js" src="yahoo.js" />
<file type="js" src="dom.js" />
<file type="js" src="event.js" />
</group>
<group id="test">
<!--涉及到Javascript预编译,先不涉及
<macro name="DEBUG" value="1" />
-->
<file type="js" src="test.js" />
</group>
</smasher>
上面是smasher的配置文件,需要关注的就是,每一个group可以看做是一个操作单位,它拥有一个唯一的groupid,group中有许多file节点,每一个file节点要标明自己是css文件,或是js文件,上面的四种路径的配置要符合主机的配置,才能运行无误。
smasher_web.php
<?php
//设置自定义的错误处理函数
set_exception_handler('handle_exception');
require 'smasher.php';
$options = array(
'conf' => 'smasher.xml',//目标配置文件
'type' => NULL,//文件类型(从url获得)
'group' => NULL,//设置xml中的目标操作组ID
'nominify' => false//不压缩
);
if (isset($_GET['conf'])) {
$options['conf'] = $_GET['conf'];
}
if (!isset($_GET['type'])) {
throw new Exception('No type specified');
} else {
$options['type'] = $_GET['type'];
}
if (!isset($_GET['group'])) {
throw new Exception('No group specified');
} else {
$options['group'] = $_GET['group'];
}
$minify = !isset($_GET['nominify']);
//实例化Smasher
$smasher = new Smasher($options['conf']);
if ($options['type'] === 'css') {
header('Content-Type: text/css');
echo $smasher->build_css($options['group'], !$options['nominify']);
} else if ($options['type'] === 'js') {
header('Content-Type: text/javascript');
echo $smasher->build_js($options['group'], !$options['nominify']);
} else {
throw new Exception('Invalid type: ' . $options['type']);
}
// -- Functions ---------------------------------------------------------------
function handle_exception(Exception $ex)
{
header('HTTP/1.0 404 Not Found');
header('Content-type: text/html');
echo '<html>',
'<head><title></title></head>',
'<body>',
'<h1>Smasher error</h1>',
'<p>', htmlentities($ex->getMessage()), '</p>',
'</body>',
'</html>';
exit;
}
上面说到了,smasher_web.php作为一个可以直接在浏览器中请求的入口文件,会接受两个参数:一个是type(取值为js/css),一个是group(取值要等于xml配置中的某一个groupid),否则就会报错。之后,smasher会读取响应group中的文件,合并,压缩,输出。我们的目的达到了。(可以下载源码,然后在本地请求:http://localhost/smasher/smasher_web.php?type=js&group=yui,就能看到实时压缩后的代码,它会将YUI group中的三个js文件合并压缩然后输出)
smasher.php的源码就不在页面上展现了,感兴趣的可以从上面给的两个链接中下载源码学习。
其实说到底,smasher最灵活的地方就在xml配置文件和入口文件上面,可以通过重写来为自己的项目量身定做一套更加合身的smasher套件。
(近期还会给smasher添加一个缓存机制,这样就不会一直麻烦服务器一直合来合去,压来压去的了,当然,可以配置它强制压缩(默认有缓存就不会再次压缩);还想给它再配上一个压缩引擎,默认的是YUI Compressor,再给它配上一个更霸道的Closure Compiler,就可以灵活选择压缩引擎了)




浙公网安备 33010602011771号