美文网首页
CommonJs 、amd规范、cmd规范是什么?

CommonJs 、amd规范、cmd规范是什么?

作者: 卫泽洪_70a7 | 来源:发表于2020-04-27 16:32 被阅读0次

    原始社会:

    在很久很久以前,前端=html+css+js,其中js的代码是最少的,那个时候的 JavaScript 就像个玩具,用处大概就是在侧栏弄个时钟,用 media player 放个 mp3 之类的脚本,代码量不是很多,直接放在 <script> 标签里或者弄个 js 文件引一下就行,日子过得很轻松愉快。

    随后的几年,人们开始尝试在一个页面里做更多的事情。容器的显示,隐藏,切换。用 css 写的弹层,图片轮播等等。但如果一个页面内不能向服务器请求数据,能做的事情毕竟有限的,代码的量也能维持在页面交互逻辑范围内。这时候很多人开始突破一个页面能做的事情的范围,使用隐藏的 iframe 和 flash 等作为和服务器通信的桥梁,新世界的大门慢慢地被打开,在一个页面内和服务器进行数据交互,意味着以前需要跳转多个页面的事情现在可以用一个页面搞定。但由于 iframe 和 flash 技术过于 tricky 和复杂,并没能得到广泛的推广。

    插件时代:

    直到 Google 推出 Gmail 的时候(2004 年),人们意识到了一个被忽略的接口,XMLHttpRequest, 也就是我们俗称的 AJAX, 这是一个使用方便的,兼容性良好的服务器通信接口。从此开始,我们的页面开始玩出各种花来了,前端一下子出现了各种各样的库,PrototypeDojoMooToolsExt JSjQuery…… 我们开始往页面里插入各种库和插件,我们的 js 文件也就爆炸了。

    随着 js 能做的事情越来越多,引用越来越多,文件越来越大,加上当时大约只有 2Mbps 左右的网速,下载速度还不如 3G 网络,对 js 文件的压缩和合并的需求越来越强烈,当然这里面也有把代码混淆了不容易被盗用等其他因素在里面。JSMinYUI CompressorClosure CompilerUglifyJS 等 js 文件压缩合并工具陆陆续续诞生了。压缩工具是有了,但我们得要执行它,最简单的办法呢,就是 windows 上搞个 bat 脚本,mac / linux 上搞个 bash 脚本,哪几个文件要合并在一块的,哪几个要压缩的,发布的时候运行一下脚本,生成压缩后的文件。

    CommonJS诞生:

    基于合并压缩技术,项目越做越大,问题也越来越多,大概就是以下这些问题:

    ●库和插件为了要给他人调用,肯定要找个地方注册,一般就是在 window 下申明一个全局的函数或对象。难保哪天用的两个库在全局用同样的名字,那就冲突了。

    ●库和插件如果还依赖其他的库和插件,就要告知使用人,需要先引哪些依赖库,那些依赖库也有自己的依赖库的话,就要先引依赖库的依赖库,以此类推。

    恰好就在这个时候(2009 年),随着后端 JavaScript 技术的发展,人们提出了 CommonJS 的模块化规范,大概的语法是: 如果 a.js 依赖 b.js 和 c.js, 那么就在 a.js 的头部,引入这些依赖文件:

    var b = require('./b')

    var c = require('./c')

    那么变量 b 和 c 会是什么呢?那就是 b.js 和 c.js 导出的东西,比如 b.js 可以这样导出:

    exports.square = function(num) { return num * num }

    然后就可以在 a.js 使用这个 square 方法:

    var n = b.square(2)

    大名鼎鼎的NodeJS就是符合CommonJS规范的。

    AMD诞生

    但是 CommonJS 在浏览器内并不适用。但是 CommonJS 在浏览器内并不适用。因为 require() 的返回是同步的,意味着有多个依赖的话需要一个一个依次下载,堵塞了 js 脚本的执行。所以人们就在 CommonJS 的基础上定义了 Asynchronous Module Definition (AMD) 规范(2011 年),使用了异步回调的语法来并行下载多个依赖项,比如作为入口的 a.js 可以这样写:

    require(['./b', './c'], function(b, c) {

        var n = b.square(2)

        console.log(c)

    })

    相应的导出语法也是异步回调方式,比如 c.js 依赖 d.js, 就写成这样:

    define(['./d'], function(d) {

        return d.PI

    })

    可以看到,定义一个模块是使用 define() 函数,define() 和 require() 的区别是,define() 必须要在回调函数中返回一个值作为导出的东西,require() 不需要导出东西,因此回调函数中不需要返回值,也无法作为被依赖项被其他文件导入,因此一般用于入口文件,比如页面中这样加载 a.js:

    <script src="js/require.js" data-main="js/a"></script>

    以上是 AMD 规范的基本用法,更详细的就不多说了(反正也淘汰了~)

    CMD诞生:

    大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:seajs官方doc

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

    相关文章

      网友评论

          本文标题:CommonJs 、amd规范、cmd规范是什么?

          本文链接:https://www.haomeiwen.com/subject/psfuwhtx.html