跟我学 coolie 之 5 模块分块构建
分析
- 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.js
和area.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
的配置,该配置有以下要求:
- 值是一个数组,每个数组项目会单独打包。
- 当有两个及以上的入口模块时,被两个及以上的入口模块引用才会被独立打包。
- 当只有一个入口模块时,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