作为一个曾经的后端开发者,当我第一眼看到一些javascript模块化的代码案例时,我就想到了java、c#这些天生的模块化语言。
今天就拿 require.js 来捋一捋这其中的异同。
模块化
一个基本的javascript模块,应该是隐藏私有成员及方法,暴漏外部调用的所需的接口。
常见的写法有:
|
在以上代码中,外部环境无法读取和修改变量prop
和方法tool
,但是该模块返回了一个公开的对象,并有一个可执行的方法fn
。
这不就相当于面向对象编程中的封装吗?
在以上代码中使用了闭包来隔离变量作用域,而像java中可以使用public
、private
这样的关键字来定义成员。
require.js入门
刚才通过一段简单的代码理解了模块化的作用,下面来看看require.js是如何定义和调用模块的。
页面加载
|
在页面中插入了require.js文件,使用data-main
指定主模块或者叫入口模块,我理解为java中的main()
方法。data-main
属性可以写模块文件的路径,在require.js中默认的后缀.js
可省略。
入口模块
如果我们的页面非常简单的话,在入口模块中可以写我们的js代码。
比如:
|
此时刷新页面就会直接在控制台输出Hello require.js!
。
当然如果是这样的话,也就没必要用require.js了。
正常的写法一般是这样的:
|
第一个参数数组表示依赖的模块名,然后在其后的回调函数中就可以使用这些模块。
加载模块
当然,不可能凭空使用模块,按照常规肯定需要某个地方指定模块加载路径吧。
在主模块头部可作以下配置:
|
如果所有模块都在同一个目录则可以配置baseUrl
。
|
也可以直接使用URL配置远程文件链接。
|
与java中的导包的作用类似,import xxx.xxx.xxx;
。
定义模块
目前常见的的js模块规范有CMD
、AMD
、CommonJS
以及兼容性写法的UMD
,require.js是实现了AMD规范的js库。
定义一个模块tool
,如下写法:
|
如果该模块依赖其他模块,如jquery,就需要定义模块依赖。如入口模块的定义一样,第一个参数写成模块名数组。
|
依赖的模块依然需要在入口模块中配置加载路径,但不是必须要在入口模块中注入。
在这个模块中我们发现了这段代码与一开始的基本模块写法类似,一样是只暴漏必须的调用接口。
现在可以在入口模块中调用这个模块:
|
如果jquery加载正确的话,控制台会输出:
|
好了,现在可以去更新简历在技能上加上require.js了!
结束
各种模块化规范殊途同归,都是为了解决同样的问题。理解了其中一种,都可以轻松掌握其他规范的写法。
未来我们还有天然支持类和模块的ES6,期待吧?
我一直认为好的开发人员不应该局限于一个技术栈,因为这样会阻碍你对一个问题的全面认知和对新知识的快速领会。