coolie 之 JS 模块依赖分析、合并、压缩、版本管理

发布于 2021-11-29 12:55:42 字数 4487 浏览 1148 评论 0

一、引子

假设现在要做一台计算机,coolie 是帮你这样做到的:

  1. 根据你的要求,从全世界购买各种零件,包括 CPU、主板、网卡等。
  2. 将这些零件封装成一台看起来比较丑陋的计算机原型。
  3. 将多余的电线剪掉、去除多余的零件,加上包装盒。

coolie 就这么漂亮的完成了你分配给它的任务,任劳任怨。

本文将从 JS 模块依赖分析、合并、压缩、版本管理开始讲讲 coolie 到底能做什么,值得作者这么牛气哄哄的推荐他。我想前端 JS 目前需要做的事情也就这些了吧,这也是我为什么不遗余力的推荐的一个理由。

二、模块依赖分析

描述以下场景:你的网站就一个页面,一个首页,首页上有一个 index.js。但是你的首页比较复杂,index.js 使用了各种脚本库、插件,包含关系是这样的:

- index.js
|-- jquery.js
|	`-- jquery.fullscreen.js
|		`-- fullscreen.js
`-- reamd.md

图示,不表示层级关系,仅表示引用关系,其实 5 个文件是同级的。coolie 是如何知道这个依赖分析的?当然你必须写一些依赖标记,让 coolie 知道你的依赖关系。因此,你的 index.js 应该是这么写的(为了更好的描述,define 及其他代码被省略了):

// index.js
require('./fullscreen.js');

index.js 作用很简单,他只需要 fullscreen.js。index.js 不需要关心 fullscreen.js 是如何实现的,你爱怎么来怎么来。但是 fullscreen.js 给我的接口一定是可用的。就像一开始说的组装电脑,coolie 去购买 CPU,而不会关心 CPU 是如何做出来的,只需要能用即可。当然,这里只讨论实现,不能较真,如果你非要说,不知道 fullscreen.js 可能吗?

与 index.js 道理一样,fullscreen.js 也是如此。fullscreen.js 只需要 jquery.fullscreen.js。

// fullscreen.js

require('./jquery-fullscreen.js');

jquery.fullscreen.js 也是如此,终点文件是 jquery.js ,他没有任何依赖。因此,coolie 可以根据源代码上的require关键字来找到他们之间的依赖关系,因此require关键字不能被修改,这是一个小约定,开发者和 coolie 的小约定。他们之间的依赖关系最终被分析出来是这样的:

index.js(入口文件) => fullscreen.js => jquery.fullscreen.js => jquery.js

三、模块合并

coolie 在上一步已经将入口文件的依赖关系分析出来了,coolie 很聪明,在分析依赖的时候就已经将模块合并起来了,并且保存在内存里,等待处理。合并后的模块集合是这样的:

// index.js
define(function(require, exports, module){require('./fullscreen.js')});

// fullscreen.js
define(function(require, exports, module){require('./jquery-fullscreen.js')});

// jquery-fullscreen.js
define(function(require, exports, module){require('./jquery.js')});

// jquery.js
define(function(require, exports, module){});

四、模块压缩

coolie 在上一步的得到模块集合的基础上,会将模块进行压缩。压缩之后只有一个新文件了,并且模块的路径也已经被压缩成 1 个字符了,所以 coolie 不需要任何的路径别名配置,require 进来就好了。

// index.abcdef123456.js

define('0', ['1'], function(a, b, c){a('1')});
define('1', ['2'], function(a, b, c){a('2')});
define('2', ['3'], function(a, b, c){a('3')});
define('3', [], function(a, b, c){});

上面的代码,人类已经无法正常阅读了,这是给机器读的。通过上面的关系,我们可以到这样的依赖关系:

0(入口模块) => 1 => 2 => 3

那么模块的对应关系是:

0 <=> index.js(入口模块)
1 <=> fullscreen.js 
2 <=> jquery.fullscreen.js
3 <=> jquery.js

五、自动入口版本管理

可能你已经注意到,coolie 处理过的 index.js,名称变为了index.abcdef123456.js,其中index是初始名字,coolie 会保留他,因为这是入口模块,是硬编码。而后面的abcdef123456是版本号,文件名后面加一串随机字符串来表示版本号,是不是觉得自己的逼格顿时变高了?

那么,coolie 是怎么进行版本管理的,还是以 index.js 为例。

- index.js
|-- fullscreen.js
|-- jquery.fullscreen.js
`-- jquery.js

coolie 很聪明的,在分析依赖这一步就进行文件 MD5 计算了:

- index.js => md5: abc
|-- fullscreen.js => md5: def
|-- jquery.fullscreen.js => md5: 123
`-- jquery.js => md5: 456

coolie 将依赖链里的各个文件的 MD5 值计算出来,然后安装组装顺序合并起来。因此,只要依赖链的任何一个模块发生了变化,那么这个文件的最终产出就会发生变化,这就是 coolie 能够进行 JS 模块版本化管理的奥秘。

六、总结

coolie 很渺小,要做的事情还有很多,比如生成路径对应关系、sourceMap,动态合并等等。他要走的路还很长,但他能做的已经完全能够解决当前前端开发中的一些重点和难点。

市面上能够和 coolie 一样做的一样好的,可能还有(?),coolie 抱着开放的态度,吸收好的,摒弃坏的。

那我们为什么还要选择 coolie?

coolie 能做的很简单:一条命令,发布一个工程;少量配置,分分钟上手。coolie 维护了是前端工程化的一环:前端开发构建,做的纯粹、足够。coolie 不会增加配置,来适配各种特殊情况,一定的约定可以让 coolie 保持最快的速度。下面简要的做个对比:

构建工具JS版本管理JS构建配置JS 模块路径压缩
百度 fis半自动复杂、繁杂无法
淘宝 spm手动繁杂无法
webpack手动简单可以
coolie全自动少量配置可以

简单的比较之后,你该怎么选择。

coolie 能做的,不止如此,还有更多,后文详述。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

命硬

暂无简介

文章
评论
360 人气
更多

推荐作者

迎风吟唱

文章 0 评论 0

qq_hXErI

文章 0 评论 0

茶底世界

文章 0 评论 0

捎一片雪花

文章 0 评论 0

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文