FED

©FrontEndDev.org
2015 - 2024
web@2.23.0 api@2.21.1

跟我学 coolie 之 5 模块分块构建

接前文《coolie入门6-coolie 实例演示

分析

- webroot-dev 开发环境目录
|-- static
|	|-- js
|   |   |-- app
|   |   |	|-- length.js
|   |   |   `-- area.js
|	|   |-- utils.js
|   |   |-- coolie.min.js      模块加载器
|   |   `-- coolie-config.js  模块加载器配置
|   `-- css
|		|-- font.css
|		|-- img.css
|        `-- style.css
|-- views
|   |-- length.html
|   `-- area.html
|-- coolie.json    前端构建配置
`-- readme.md
- webroot-pro    生产环境目录

这是项目的目录结构。utils.js已经被length.jsarea.js两个入口模块同时使用了,却分别打包在两个入口模块里:

length.cac2241d618488f567abef6c7c99dd0d.js,length 入口模块:

/*coolie@0.21.6*/
define("0",["1"],function(t,e,n){"use strict";var u=t("1"),i=document.getElementById("output");document.getElementById("input").onkeyup=function(){var t=u.parseFloat(this.value);i.innerHTML=String(2*u.PI*t)}});
define("1",[],function(t,a,e){"use strict";a.parseFloat=function(t){t=parseFloat(t);return isNaN(t)?0:t};a.PI=Math.PI});

area.e633541fdaad38d5a0a86b24c3ad419c.js,area 入口模块:

/*coolie@0.21.6*/
define("0",["1"],function(t,e,n){"use strict";var u=t("1"),i=document.getElementById("output");document.getElementById("input").onkeyup=function(){var t=u.parseFloat(this.value);i.innerHTML=String(u.PI*Math.pow(t,2))}});
define("1",[],function(t,a,e){"use strict";a.parseFloat=function(t){t=parseFloat(t);return isNaN(t)?0:t};a.PI=Math.PI});

如上,模块1 是同时被 length.js 和 area.js 使用的,它们可以被分离出来单独构建一个模块。

实现

要实现这个想法,使用 coolie 非常的简单,只需要修改js.chunk的配置,该配置有以下要求:

  1. 值是一个数组,每个数组项目会单独打包。
  2. 当有两个及以上的入口模块时,被两个及以上的入口模块引用才会被独立打包。
  3. 当只有一个入口模块时,chunk 里的模块都会独立打包。

详细配置说明点这里

因此,修改 coolie.json 如下:

{
  "js": {
    "main": [
      "./static/js/app/**/*.js"
    ],
    "coolie-config.js": "./static/js/coolie-config.js",
    "dest": "./static/js/",
    "chunk": [
      "./static/js/utils.js"
    ]
  },
  "css": {
    "dest": "./static/css/"
  },
  "html": {
    "src": [
      "./views/**/*.html",
      "./index.html"
    ],
    "minify": true
  },
  "resource": {
    "dest": "./static/res/"
  },
  "dest": {
    "dirname": "../webroot-pro/",
    "host": "/"
  },
  "copy": []
}

开始构建:

➜  coolie-example git:(master) ✗ coolie build webroot-dev

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


                 1/5 => copy files

                 2/5 => build main
                  √  => /path/to/webroot-dev/static/js/app/area.js
                  √  => /path/to/webroot-dev/static/js/app/length.js
                  √  => /path/to/webroot-pro/static/js/app/0.5d0b77c21d6f7b2d7a35c8ef8fbbf201.js

                 3/5 => overwrite config
                  √  => base: "./app/"
                  √  => version: "{
                          "area.js": "b6f0df354dd261760ea6a7b426620b13",
                          "length.js": "03f778a06e76d30bbe923450a6407887",
                          "0.js": "5d0b77c21d6f7b2d7a35c8ef8fbbf201"
                        }"
                  √  => callbacks: 0
                  √  => /path/to/webroot-pro/static/js/coolie-config.6160755692689573cce3789528ae80e1.js

                 4/5 => build html css
                  √  => /path/to/webroot-pro/static/css/255990a3b6b5b76cf3488ffb76157d45.css
                  √  => /path/to/webroot-pro/static/js/coolie.min.js
                  √  => /path/to/webroot-dev/views/**/*.html
                  √  => /path/to/webroot-dev/index.html

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

       build success => copy 1 file(s),
                        build 2 main file(s),
                        build 0 js file(s),
                        build 3 html file(s),
                        build 6 css file(s),
                        build 6 resource file(s),
                        past 254 ms

构建之后的目录结构:

- webroot-dev 开发环境目录【不变】
- webroot-pro 生产环境目录
|-- static
|    |-- js
|    |   |-- app
|    |   |    |-- 0.5d0b77c21d6f7b2d7a35c8ef8fbbf201.js
|    |   |    |-- length.03f778a06e76d30bbe923450a6407887.js
|    |   |    `-- area.b6f0df354dd261760ea6a7b426620b13.js
|    |   |-- coolie.min.js 模块加载器
|    |   `-- coolie-config.6160755692689573cce3789528ae80e1.js
|    `-- css
|		`-- 255990a3b6b5b76cf3488ffb76157d45.css
|-- views
|   |-- length.html
|   `-- area.html
`-- relationship-map.json 资源引用关系地图

chunk 模块按照数组的索引值命名,因此不要将你的入口模块与之重复。

0.5d0b77c21d6f7b2d7a35c8ef8fbbf201.js

/*coolie@0.21.6*/
define("1",[],function(t,a,e){"use strict";a.parseFloat=function(t){t=parseFloat(t);return isNaN(t)?0:t};a.PI=Math.PI});

area.b6f0df354dd261760ea6a7b426620b13.js

/*coolie@0.21.6*/
define("0",["1"],function(t,e,n){"use strict";var u=t("1"),i=document.getElementById("output");document.getElementById("input").onkeyup=function(){var t=u.parseFloat(this.value);i.innerHTML=String(u.PI*Math.pow(t,2))}});
coolie.chunk(["0"]);

length.03f778a06e76d30bbe923450a6407887.js

/*coolie@0.21.6*/
define("0",["1"],function(t,e,n){"use strict";var u=t("1"),i=document.getElementById("output");document.getElementById("input").onkeyup=function(){var t=u.parseFloat(this.value);i.innerHTML=String(2*u.PI*t)}});
coolie.chunk(["0"]);

构建之后的代码,在末尾添加了coolie.chunk(["0"]);,表示该入口模块还需要加载 0 chunk 的模块。

构建之后,每个模块都有一个唯一独立的 ID,因此可以全局公用一个 chunk 模块。

总结

chunk 配置由用户手动指定,并且遵循一定的分析原则,来进行模块分块打包。

chunk 配置支持通配符,因此,可以根据你的项目来自由设置,如你的项目里的 libs 需要打包打包, 那么可以配置成:

"chunk": [
    "./static/js/libs/**/*"
]

coolie 现已支持了模块分块打包,是一个非常完整的前端构建通用解决方案了。 避免了入口模块巨大无比的尴尬,也同时实现了公共模块的共享加载。

关于如何优化模块 chunk 处理,需要使用者自己决定,它的出现决定了模块构建将会更加灵活,而不失简单。

源码

https://github.com/cloudcome/coolie-example/releases/tag/2.0