coolie PK webpack 之一:JS 文件的合并与压缩
本文只在前端构建维度上讨论 webpack 和 coolie,分析他们两个工具谁更好、更优秀。关于如何使用 webpack 和 coolie,暂且不在本文讨论范围内。
什么是前端构建
把 less 文件编译成 css 文件属于构建?把 coffee 编译成 js 属于构建?压缩 JS、CSS 属于构建吗?合并 JS、CSS 属于构建吗?
为了方便比较,我们将前端构建分为以下几个部分和权重(满分 100 分),并定义前端开发中发布到生产环境的过程称之为前端构建。
| # | 构建内容 | 权重值 | 
|---|---|---|
| 1 | 静态资源的合并与压缩 | 20 分 | 
| 2 | 模块化构建 | 40 分 | 
| 3 | 静态资源引用与版本管理 | 30 分 | 
| 4 | 便捷与扩展性 | 10 分 | 
接下来的几篇文章,就根据这个表格来逐一分析对比 webpack 和 coolie,到底孰优孰劣。
在静态资源的合并与压缩(满分 20 分)方面,分为以下两个维度
- JS 的合并与压缩:10 分
 - CSS 的合并与压缩:10 分
 
#JS 的合并与压缩
准备以下文件和目录结构:
|-- demo
	|-- src
	|	|-- single1.js
	|	`-- single2.js
	`-- index.html
single1.js
var abc = 1;
alert(abc);
single2.js
var def = 2;
alert(def);
index.html
<!DOCTYPE html>
<script src="./src/single1.js"></script>
<script src="./src/single2.js"></script>
webpack
需要新增配置文件webpack.config.js
var path = require("path");
module.exports = {
    entry: ['./src/single1.js', './src/single2.js'],
    output: {
        path: path.join(__dirname, '../out'), 
        filename: 'single.js'
    }
};
执行 webpack -p 之后(为了不影响阅读,加了断行):
!function(r){function t(n){if(e[n])return e[n].exports;
var o=e[n]={exports:{},id:n,loaded:!1};
return r[n].call(o.exports,o,o.exports,t),
o.loaded=!0,o.exports}
var e={};
return t.m=r,t.c=e,t.p="",t(0)}([function(r,t,e){e(1),
r.exports=e(2)},function(r,t){
var e=1;alert(e)},function(r,t){var e=2;alert(e)}]);
目标文件的目录结构为:
-- out
`-- single.js
coolie
需要新增配置文件,执行coolie json 生成(询问步骤省略,更多阅读参考http://coolie.ydr.me/begin/coolie.json.html)的文件为:
{
  "js": {
    "dest": "./src/"
  },
  "css": {
    "dest": "./src/",
    "minify": {
      "compatibility": "ie7"
    }
  },
  "html": {
    "src": [
      "./*.html"
    ],
    "minify": true
  },
  "resource": {
    "dest": "./src/",
    "minify": true
  },
  "copy": [],
  "dest": {
    "dirname": "../dest/",
    "host": ""
  }
}
并且,需要修改 index.html 为(详细参考:http://coolie.ydr.me/advance/build-js.html):
<!DOCTYPE html>
<!-- coolie -->
<script src="./src/single1.js"></script>
<script src="./src/single2.js"></script>
<!-- /coolie -->
执行coolie build构建之后的目录结构为:
-- dest
|-- src
|	`-- 6c762d4e4b7d1e9504281bc12abd65b9.js
|-- index.html
`-- relationship-map.json
构建生成的 JS 文件为6c762d4e4b7d1e9504281bc12abd65b9.js,内容为:
/*coolie@0.20.10*/
var abc=1;alert(abc);
var def=2;alert(def);
index.html 内容为:
<!DOCTYPE html><script src="/src/6c762d4e4b7d1e9504281bc12abd65b9.js"></script>
<!--coolie@0.20.10-->
生成的relationship-map.json(资源引用关系地图)内容为:
{
    "index.html": {
        "css": {},
        "js": {
            "src/6c762d4e4b7d1e9504281bc12abd65b9.js": [
                "src/single1.js",
                "src/single2.js"
            ]
        },
        "main": ""
    }
}
一张图说明一切
总结
webpack
- 优点
- 只有一个配置文件:只需要写一个
webpack.config.js即可,使用简单。 
 - 只有一个配置文件:只需要写一个
 - 缺点
- index.html 里引用的 JS 怎么办?无法处理
 - 无法处理版本,修改了
single1.js和single2.js导致内容变化。 - 合并压缩后的代码是什么鬼?比原始代码还长
 - 其他构建要求需要修改配置文件
 
 - 致命错误
- 原本
single1.js和single2.js,分别需要向全局作用域注入abc和def两个属性,合并压缩之后导致该属性不复存在了,改变了 JS 执行的作用域 
 - 原本
 
coolie
- 优点
- 以页面为导向,智能分析区间内的JS,进行合并压缩
 - 有版本管理
 - 生成资源引用关系地图
 - 一次生成永久配置,不必重复修改配置
 - 生成的内容简单明了,一行一个原始 JS 文件
 - 压缩没有改变 JS 执行的作用域
 - 同时压缩了 HTML 文件
 
 - 缺点
- 配置稍微复杂
 - 需要在 HTML 页面上标记
 
 
综,在静态资源的合并与压缩的 JS 文件的合并与压缩上,coolie 做的更好、更多、更简单、更漂亮,webpack 还留下了一个致命错误,coolie 胜出,得满分 10 分,webpack得 0 分。