浅谈JavaScript 模块化

2017-03-27  本文已影响0人  BeYanJin

参考资料

Modules/1.0——维基百科
CommonJS Modules/1.0——伯乐在线
js模块化——博客园
Javascript模块化编程系列——阮一峰
《ECMAScript 6 入门》——阮一峰

前言

本人菜鸟,入IT只为当鼓励师。本编文章意在简单总结一下 什么是模块化,模块化的优点, js模块化 的发展历史,关于 js模块化 的一些规范 等等。

一、什么是模块化

根据百度百科说法:模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。

晕了,这是什么嘛。

简单的说就是,我们实现一个应用时(不管是web、桌面还是移动端),通常都会按照不同的功能,分割成不同的模块来编写,编写完之后按照某种方式组装起来成为一个整体,最终实现整个系统的功能。

所以,如果一个团队一起做一个复杂的应用,肯定要分模块分工合作(一个人战斗不太现实)。这时,有很多需要注意的点就出现了:

C、C++、Java、PHP等等编程语言本身就拥有可以实现模块化的指令或方法,有了这些指令或方法,就可以把子功能写在另外的文件上,需要用到的时候直接引入即可。举下例子:

抛开C、C++、Java、PHP这些不说,就说前端领域,认真想想,其实 html css 也实现了模块化。

那 JavaScript 呢?带着疑问,下面会介绍js模块化的发展历程。(大神请无视)

二、模块化的优点

可维护性:

可测试性:

三、前端的模块化思想的发展

3.1 那年的诞生——1995

1995年,JavaScript正式发布,当时它只是作为一种客户端脚本语言,目的是 将 不涉及后端数据的、简单的 表单有效性验证 转移到客户端完成,减少客户端向服务端的请求数。那时的JavaScript只是服务端工程师在使用,他们或许只需在页面上随便写几句js代码就能满足需求。

if (xxx) {
  // ......
} else {
  // ......
}
element.onsubmit= function () {
  //......
}

代码可能像这样子,从上到下执行就行了,没有什么模块的规范。

3.2 模块萌芽

随着ajax的概念被提出,前端有了主动发起请求的能力,一些业务开始向客户端方向偏移。网站逐渐变成“互联网应用程序”,嵌入网页的Javascript代码越来越庞大,越来越复杂。于是,一些问题就暴漏出来了:

如果放着这些问题不解决,团队的工作重点与关注点就不只是系统的业务逻辑,还包括队内的沟通,这会阻碍着项目进度。而且当人数一多时(几十人甚至上千人一起开发同一个项目),沟通就变得非常困难且低效了。

于是,前人创造了很多方法来避免这些问题,尽最大的努力实现模块化:

3.2.1 避免全局环境污染的方法

jQuery的封装风格曾被很多框架模仿。
这种方式用到了匿名函数包装代码(即第二种方法)。多出的点是,所依赖的外部变量可以传给这个函数,在函数内部就可以使用这些依赖了,然后把模块自身暴漏给window。
如果需要添加扩展,则可以作为jQuery的插件,把它挂载到$上。例如:fullpage.js插件。
这种风格虽然灵活了些,但并未解决根本问题:所需依赖还是得外部提前提供、还是增加了全局变量。

3.2.2 避免命名冲突的方法

3.2.3 完善依赖关系的管理

后面提到的 require.js、sea.js 等 可以解决这个问题,这个后续再说。

3.2.4 推荐

想了解更多实现模块化的方法,可以拜读一下峰哥的文章:
Javascript模块化编程(一):模块的写法

3.2.5 模块化问题

当人们觉得再这样下去写代码槽糕透了的时候,他们就想运用模块化的思想,写好一个模块,要用就导入,导入后毫不影响原先的代码。这样就引发很多需要思考的问题:

四、服务端 js 的诞生

4.1 nodejs

2009年,nodejs诞生,我们可以用 js 编写服务端的代码了。
在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程。
于是,CommonJS 社区制定了 Modules/1.0 规范(现在已经被1.1取代)。nodejs 采用了该规范,故以下用 nodejs 作为例子。

4.2 Modules/1.0

总结起来,Modules/1.0规范指出:

Modules/1.0规范的内容如下:

4.2.1 模块上下文

程序执行顺序

④ 如果请求模块失败,require函数应抛出一个错误。

4.2.2 模块标识符

五、服务端的模块化在前端领域的应用

既然服务端出了模块化方案 Modules/1.0 ,那么是不是可以把这个规范直接用在客户端啊?
只可惜,不能。出于以下原因:

既然如此,问题要怎么解决?于是乎,就像党派斗争一样,分裂了三种解决方案。

5.1 Modules/1.x

这一派人的意见是:

典型的工具有:browserify。Browserify 可以让你使用类似于 node 的 require() 的方式来组织浏览器端的 Javascript 代码,通过 预编译 让前端 Javascript 可以直接使用 Node NPM 安装的一些库。难懂,那就直接看它的例子吧:

browserify的简单用法

所以,若采用这一派的规范,我们就可以直接像服务端一样编写代码了,编写完后,只需要用工具把它编译成浏览器使用的代码即可。

5.2 Modules/2.0

这一派人的意见是:

CMD/seajs

seajs 的作者 是 国内大牛 淘宝前端步道者 玉伯。seajs 全面拥抱
Modules/Wrappings规范,不用 RequireJS 那样回调的方式来编写模块。

它的特色和用法以后再来补充。(待续)

5.3 Modules/Async

这一派人的意见是:

AMD/RequireJs

这里主要介绍 RequireJs,若想了解其用法,可以看我的另一篇文章:AMD/RequireJS 使用入门

六、ES6模块化标准

既然模块化开发的呼声这么高,作为官方的ECMA必然要有所行动,js模块化很早就列入草案,终于在2015年6月份发布了ES6正式版。

ES6只要增加了 exportimportmodule 等命令。具体用法以后再补充。

想了解更多关于ES6的东西,推荐大家阅读《ECMAScript 6 入门》,这是这本书的 网上教程

上一篇 下一篇

猜你喜欢

热点阅读