压缩javascript的工具很多,为什么我们要选Google Closure Compiler?

一千个读者有一千个哈姆雷特,没有最好的答案,在这里可以参考下面这篇分析

https://github.com/pandamicro/Javascript-Compressors-Analyse

----------------------------

在这里就只讨论Closure Compiler

首先最核心的代码,利用Closure Compiler在线工具和php自带的cURL库进行压缩。

Closure Compiler提供了3中压缩模式

ADVANCED_OPTIMIZATIONS    高级优化

SIMPLE_OPTIMIZATIONS      简单优化

WHITESPACE_ONLY           仅去除空白

我在这里选择了‘简单优化’模式。

为什么不选择高级优化?

高级优化有更高的压缩率,有更好的运行效率,为什么我不选择它?

因为高级优化有个致命的缺点,会对代码进行更彻底的修改(暴力修改),这种修改有可能会导致代码的不可用,而且很难被用户察觉到。

如果你对高级优化的压缩逻辑不是很熟悉,很难避免写出这种致命代码。

所以我这里还是以简单优化为例啦。

$params = array(
         'output_info'=>'compiled_code',
         'output_format'=>'text',
         'compilation_level'=>'SIMPLE_OPTIMIZATIONS',
         'js_code'=>urlencode($script)
         );
$ch = curl_init('http://closure-compiler.appspot.com/compile');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($params));
$output = curl_exec($ch);
curl_close($ch);

在开始之前检查输出文件是否可以写入

function prep_output_file(){
  if($this->options['output_file']) {
    if(file_exists($this->options['output_file']) and is_writeable($this->options['output_file'])){
       return true;
    }else{
       $dirname = dirname($this->options['output_file']);
       if (file_exists($dirname)) {
          if (is_writeable($dirname)) {
             touch($this->options['output_file']);
             chmod($this->options['output_file'], 0777);
             return true;
          }else{
             trigger_error("Directory not writable");
             return false;
          }
       }else{
            trigger_error("Directory does not exist");
            return false;
       }
    }
  }else{
     trigger_error("Missing output_file");
     return false;
  }
}

在压缩之前,通过判断时间来检查代码是否有改变

//$this->options['files'] 是一个存放javascript文件的数组
function check_changed(){
   if (file_exists($this->options['output_file'])) {
      $output_filemtime = filemtime($this->options['output_file']);
      foreach ($this->options['files'] as $js_file) {
         if ($output_filemtime < filemtime($js_file)){
            return true;
         }
      }
   } else {
      return true; // no file
   }
   return false;
}

添加单个javascript文件或文件夹中所有文件到数组$this->options['files']

function add_script($file){
 $file = "{$_SERVER['DOCUMENT_ROOT']}/".(ltrim($file, "/"));
  if (file_exists($file) and is_readable($file)) {
     $this->options['files'][] = $file;
  }else{
    trigger_error("Javascript file does not exist: $file");
  }
}

function add_directory($dir){
 $dir = "{$_SERVER['DOCUMENT_ROOT']}/".(ltrim($dir, "/"));
  if(file_exists($dir) and is_dir($dir)){
     foreach(new DirectoryIterator($dir) as $file_info) {
	if($file_info->isDot() or $file_info->isDir()) continue;
	if(strtolower($file_info->getExtension()) == "js") {
	   $this->options['files'][] = $file_info->getRealPath();
	}
     }
  }else{
     trigger_error("Directory does not exist");
  }
}

读取被添加的javascript文件

function get_source() {
    $script = "";
    foreach ($this->options['files'] as $file) {
        $script .= file_get_contents($file) . "\n\n";
    }
    return $script;
}

最后你当然还可以把压缩后的文件放到CDN上去。

完整代码我就不放了,每个人的需求不一样,还是自己动手的好

-------------

貌似google在线的这个功能国内被墙了,这里提供下载版本,需要java再能用噢

https://github.com/google/closure-compiler