本文只在前端构建维度上讨论 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 生成(询问步骤省略,更多阅读参考fhttp://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 为(详细参考:fhttp://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.jssingle2.js导致内容变化。
    • 合并压缩后的代码是什么鬼?比原始代码还长
    • 其他构建要求需要修改配置文件
  • 致命错误
    • 原本single1.jssingle2.js,分别需要向全局作用域注入abcdef两个属性,合并压缩之后导致该属性不复存在了,改变了 JS 执行的作用域

coolie

  • 优点
    • 以页面为导向,智能分析区间内的JS,进行合并压缩
    • 有版本管理
    • 生成资源引用关系地图
    • 一次生成永久配置,不必重复修改配置
    • 生成的内容简单明了,一行一个原始 JS 文件
    • 压缩没有改变 JS 执行的作用域
    • 同时压缩了 HTML 文件
  • 缺点
    • 配置稍微复杂
    • 需要在 HTML 页面上标记

综,在静态资源的合并与压缩的 JS 文件的合并与压缩上,coolie 做的更好、更多、更简单、更漂亮,webpack 还留下了一个致命错误,coolie 胜出,得满分 10 分,webpack得 0 分。