coolie PK webpack 之三:模塊構建

本文主要說明的是這兩款構建工具(coolie 和 webpack),是分別如何完成模塊化構建的,以及它們之間的優缺點。css

預備

首先準備如下文件和目錄,基本是承接上文的。html

- demo
|-- src
|   |-- body.png
|   |-- entry1.js
|   |-- entry2.js
|   |-- module1.js
|   |-- module2.js
|   |-- single1.css
|   `-- single2.css
|-- coolie.json
|-- index.html
`-- weboack.config.js

entry1.js 的內容爲:node

define(function(require){
    require('./module.js');
    require('./single1.css');
    require('./single2.css');
});

引用關係爲webpack

entry1.js => module1.js + single1.css + ( single2.css => body.png )

entry2.js 的內容爲:git

define(function(require){
    require('./module.js');
    require('./single1.css');
});

引用關係爲,唯獨缺乏了 single2.cssgithub

entry1.js => module1.js + single1.css

其餘文件內容都在前文說到。web

webpack

webpack.config.js

修改 webpack.config.js 爲(可能做者對 webpack 的使用和配置可能不當,如有錯誤歡迎指正):npm

var path = require("path");

module.exports = {
    entry: {
        entry1: './src/entry1.js',
        entry2: './src/entry2.js'
    },
    output: {
        path: path.join(__dirname, '../out'), 
        filename: '[name].js'
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style!css" }
        ]
    }
};

loader 插件

須要先安裝如下兩個插件:json

npm i -SD style-loader css-loader

構建

而後再執行:gulp

➜  webpack
Hash: 55a90533e92c37e40c33
Version: webpack 1.9.11
Time: 441ms
    Asset     Size  Chunks             Chunk Names
entry1.js  13.7 kB       0  [emitted]  entry1
entry2.js  13.5 kB       1  [emitted]  entry2
   [0] ./src/entry1.js 131 bytes {0} [built]
   [0] ./src/entry2.js 94 bytes {1} [built]
   [1] ./src/module.js 49 bytes {0} {1} [built]
   [2] ./src ^\.\/.*$ 360 bytes {0} {1} [built] [5 warnings]
   [3] ./src/body.png 0 bytes [built] [failed]
   [4] ./src/single1.js 24 bytes {0} {1} [optional] [built]
   [9] ./src/single2.js 24 bytes {0} {1} [optional] [built]
    + 6 hidden modules

WARNING in ./src/entry2.js
Critical dependencies:
3:4-11 require function is used in a way in which dependencies cannot be statically extracted
 @ ./src/entry2.js 3:4-11

WARNING in ./src/entry1.js
Critical dependencies:
3:4-11 require function is used in a way in which dependencies cannot be statically extracted
4:4-11 require function is used in a way in which dependencies cannot be statically extracted
 @ ./src/entry1.js 3:4-11 4:4-11

WARNING in ./src ^\.\/.*$
Module not found: Error: a dependency to an entry point is not allowed
 @ ./src ^\.\/.*$

WARNING in ./src ^\.\/.*$
Module not found: Error: a dependency to an entry point is not allowed
 @ ./src ^\.\/.*$

WARNING in ./src ^\.\/.*$
Module not found: Error: a dependency to an entry point is not allowed
 @ ./src ^\.\/.*$

WARNING in ./src ^\.\/.*$
Module not found: Error: a dependency to an entry point is not allowed
 @ ./src ^\.\/.*$

WARNING in ./src/body.png
Module parse failed: /path/to/demo/src/body.png Line 1: Unexpected token ILLEGAL
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
 @ ./src ^\.\/.*$

呵呵,沒法正常處理 css 引用的圖片。

結果

看下目標目錄的 entry1.js

// 省略...

// 注意點 1
var map = {
    "./module": 1,
    "./module.js": 1,
    "./single1": 4,
    "./single1.css": 5,
    "./single1.js": 4,
    "./single2": 9,
    "./single2.css": 10,
    "./single2.js": 9
};

// 省略...

// 注意點 2
if(!content.locals) {
    module.hot.accept("!!./../node_modules/css-loader/index.js!./single1.css", function() {
        var newContent = require("!!./../node_modules/css-loader/index.js!./single1.css");
        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
        update(newContent);
    });
}

// 省略...

單從注意點 1 和 注意點 2 來看,就知道 webpack 構建的徹底錯誤了。

coolie

修改的有點多,但值得,由於一旦配置完善,後續的配置都不會再變了。

coolie.json

{
  "js": {
    "src": [
      "./src/entry1.js", 
      "./src/entry2.js"
    ],
    "coolie-config.js": "./src/coolie-config.js",
    "dest": "./src/"
  },
  "css": {
    "dest": "./src/",
    "minify": {
      "compatibility": "ie7"
    }
  },
  "html": {
    "src": [
      "./*.html"
    ],
    "minify": true
  },
  "resource": {
    "dest": "./src/",
    "minify": true
  },
  "copy": [],
  "dest": {
    "dirname": "../dest/",
    "host": ""
  }
}

相比較以前,主要修改了 JS 的配置,增長了srccoolie-config.js兩個配置:
- src:須要構建的入口模塊,一般咱們將入口模塊放在一個文件夾內,使用通配符便可。
- coolie-config.js:模塊加載器的配置文件。

coolie.js

在 src 目錄下新增 coolie.min.js,使用

coolie pull

下載便可。

➜  src  coolie pull

            ╔═══════════════════════════════════════════════════════╗
            ║          coolie.cli@0.20.11                           ║
            ║          The front-end development builder.           ║
            ╚═══════════════════════════════════════════════════════╝

  pull coolie.min.js => https://raw.githubusercontent.com/cloudcome/coolie/master/coolie.min.js
  pull coolie.min.js => /path/to/demo/src/coolie.min.js

coolie-config.js

在 src 目錄下新增 coolie-config.js(模塊加載器的配置文件):

coolie.config({
    base: "./"
}).use();

html 修改

將 index.html 修改成:

<!DOCTYPE html>

<!-- coolie -->
<link rel="stylesheet" type="text/css" href="./src/single1.css">
<link rel="stylesheet" type="text/css" href="./src/single2.css">
<!-- /coolie -->

<!-- coolie -->
<script src="./src/single1.js"></script>
<script src="./src/single2.js"></script>
<!-- /coolie -->

<script coolie src="./src/coolie.min.js" data-config="./coolie-config.js" data-main="entry1.js"></script>

主要新增了一個模塊加載器,並添加了:
- coolie屬性:標誌這個script屬於 coolie 的管轄範圍。
- data-config屬性:標誌了模塊加載的配置文件路徑,相對於src屬性。
- data-main屬性:標誌了模塊入口文件路徑,相對於coolie-config.js裏的base(而base是相對於coolie-config.js自己)。

關於路徑關係,詳細看這裏

entry

爲了方便的引入 css 文件,須要修改 entry1.js 爲:

define(function(require){
    require('./module.js');
    require('./single1.css', 'css');
    require('./single2.css', 'css');
});

修改 entry2.js 爲:

define(function(require){
    require('./module.js');
    require('./single1.css', 'css');
});

require 添加第二個參數,是否是以爲奇怪?coolie 支持的 require 語法爲:

require(path, [type]);
  • path:模塊的路徑,相對於當前模塊。
  • type:模塊的類型,默認爲js模塊,還支持htmlcsstextjsonimage一共 6 種模塊。

這種語法定義的緣由:

  • 路徑關係能夠在 webstorm 裏按 cmd + 單擊直達模塊,而若是加入了css!這種前綴就不能夠了。
  • 清晰的路徑,能夠直接在 webstorm 裏拖動模塊層級,而沒必要手動修改模塊的路徑。
  • 獨立的 type 很是清晰的標識了模塊的類型。

構建

在 demo 目錄下執行:

➜  coolie build

            ╔═══════════════════════════════════════════════════════╗
            ║          coolie.cli@0.20.11                           ║
            ║          The front-end development builder.           ║
            ╚═══════════════════════════════════════════════════════╝


                 1/5 => copy files

                 2/5 => build main
                  √  => /path/to/demo/src/entry1.js
                  √  => /path/to/demo/src/entry2.js

                 3/5 => overwrite config
                  √  => base: "./"
                  √  => version: "{
                          "entry1.js": "0ba981967e8b2712d6da6114ae90675c",
                          "entry2.js": "1c9621d551021410aa19acb2ecac94dc"
                        }"
                  √  => callbacks: 0
                  √  => /path/to/dest/src/coolie-config.c58dd5aa2dacebd9a86c92b49b66a6ba.js

                 4/5 => build html css
                  √  => /path/to/dest/src/bdd8e022ce7470f06d7183daabac0b79.css
                  √  => /path/to/dest/src/6c762d4e4b7d1e9504281bc12abd65b9.js
                  √  => /path/to/dest/src/coolie.min.js
                  √  => /path/to/demo/*.html

                 5/5 => generator relationship map
                  √  => /path/to/dest/relationship-map.json

       build success => copy 1 file(s),
                        build 2 main file(s),
                        build 2 js file(s),
                        build 1 html file(s),
                        build 2 css file(s),
                        build 1 resource file(s),
                        past 157 ms

構建的過程很是的清晰,說下構建結果:

  • 複製了一個文件,就是coolie.min.js文件,即模塊加載器。
  • 構建兩個入口文件,即entry1.jsentry2.js
  • 構建了兩個 JS 文件,即single1.jssingle2.js
  • 構建了一個 HTML 文件,即index.html
  • 構建了兩個 CSS 文件,即single1.csssingle2.css
  • 構建了一個資源文件,即body.png

結果

看下目標目錄

.dest
|-- src
|   |-- 6c762d4e4b7d1e9504281bc12abd65b9.js
|   |-- a821bd973bf1114e6ed1d9170b6e84eb.png
|   |-- bdd8e022ce7470f06d7183daabac0b79.css
|   |-- coolie-config.c58dd5aa2dacebd9a86c92b49b66a6ba.js
|   |-- coolie.min.js
|   |-- entry1.0ba981967e8b2712d6da6114ae90675c.js
|   `-- entry2.1c9621d551021410aa19acb2ecac94dc.js
|-- index.html
`-- relationship-map.json

來看下 entry1.js(爲了便於閱讀,已省略了 base64 編碼):

/*coolie@0.20.11*/
define("0",["1","2","3"],function(n){n("1");n("2");n("3")});
define("1",[],function(){console.log("module")});
define("2",[],function(y,d,r){r.exports="html{margin:0;padding:0}"});
define("3",[],function(y,d,r){r.exports="body{background:url(data:image/png;base64...)}"});

來看下 entry2.js:

/*coolie@0.20.11*/
define("0",["1","2"],function(n){n("1");n("2")});
define("1",[],function(){console.log("module")});
define("2",[],function(y,d,r){r.exports="html{margin:0;padding:0}"});

看下 index.html(爲了便於閱讀已折行和註釋處理):

<!DOCTYPE html>
<!--1-->
<link rel="stylesheet" href="/src/bdd8e022ce7470f06d7183daabac0b79.css">
<!--2-->
<script src="/src/6c762d4e4b7d1e9504281bc12abd65b9.js"></script>
<!--3-->
<script src="/src/coolie.min.js" data-config="./coolie-config.c58dd5aa2dacebd9a86c92b49b66a6ba.js" data-main="entry1.js"></script>
<!--coolie@0.20.11-->

很是的清晰明瞭:

  1. CSS 文件的合併、壓縮、版本管理
  2. JS 文件的合併、壓縮、版本管理
  3. 模塊文件的構建。

最後看看relationship-map.json

{
    "index.html": {
        "css": {
            "src/bdd8e022ce7470f06d7183daabac0b79.css": [
                "src/single1.css",
                "src/single2.css"
            ]
        },
        "js": {
            "src/6c762d4e4b7d1e9504281bc12abd65b9.js": [
                "src/single1.js",
                "src/single2.js"
            ]
        },
        "main": "src/entry1.js",
        "deps": [
            "src/module.js",
            "src/single1.css",
            "src/single2.css"
        ]
    }
}

與前文相比,多了maindeps

  • main:入口模塊。
  • deps:入口模塊的依賴模塊。

總結

在模塊構建上:

webpack

  • 優勢

    • 自由定製。
  • 缺點

    • 須要安裝各類插件,沒法基本知足通用化需求。
    • 和 gulp、grunt 是沒有本質區別的,都是本身實現一個 runner,而後來跑各類插件。
    • 出現了構建錯誤,依賴分析錯誤。
    • 沒法正常構建 css 和 css 裏引用的圖片文件。
    • 須要豐富經驗才能駕馭配置。

coolie

  • 優勢

    • 構建徹底正確
    • 很是優秀的版本管理。
    • 模塊路徑進行了壓縮,將原有的./module1.js這種路徑壓縮成了1這種單個字符,極大減小了文件體積。
    • 支持 html/css/text/image/json 模塊構建(部分未在本文涉及到)。
    • 支持 html/css 裏引用的靜態資源構建(本文未涉及)。
  • 缺點

    • 須要搭配訂製的模塊加載器。
    • 部分寫法有些特殊。

綜合,coolie 顯而易見的徹底勝出,得滿分 40 分,webpack 得 1 分。


原文:http://frontenddev.org/article/coolie-pk-webpack-3-module-build.html

相關文章
相關標籤/搜索