前面有一篇博文提到了RequireJs,那么这篇主要是从某个实际项目中的应用来总结一下RequireJs。
RequireJs项目的应用
拿出最近某个同事使用RequireJs写的一个项目,来分析一下其中的代码。
目录结构:
HTML引入:
|
|
main.js的内容:
|
|
关于HTML引入RequireJs
使用RequireJs的话,我们只需要导入RequireJs即可,不需要显式导入其它的js库,因为这个工作会交给RequireJs来做。
属性data-main
是告诉RequireJs:你下载完以后,马上去载入真正的入口文件。它一般用来对RequireJs进行配置,并且载入真正的程序模块。
关于main.js
main.js 中通常用来做两件事:
使用
require.config()
配置RequireJs。
baseUrl:与paths是相关的,指定paths里文件的基准目录。
paths:指定项目中用到哪些模块,文件路径是什么等等。
shim:将某个依赖中的某个全局变量暴露给requirejs,当作这个模块本身的引用。使用
require()
函数载入“主模块”。
关于模块
我们可以把main.js可以理解为所有模块的入口(称为“主模块”)。通常在项目中,都在main.js中使用require()函数来引入依赖的其他模块。在后文中,我把每一个引入到main.js的js文件都称作为模块。
所有模块都必须按照AMD的规定来写,即采用特定的define()函数来定义。有两种情况:
- 模块不依赖其他模块:
直接用define()函数,传入一个函数即可。 - 模块还依赖其他模块:
使用define()函数传入两个参数,第一个参数必须是一个数组,指明该模块依赖的模块;第二个参数是函数。当require()加载这个模块的时候,就会先加载当前这个模块依赖的模块。
当然,如果一个模块没有按照AMD的规定来写,也可以被依赖。就需要在require.config()的shim参数中定义。
例如有一个未按照AMD的规定来写的模块hello.js:
|
|
先看下面不能正确工作的代码:
|
|
这段代码会报错,提示:
|
|
原因是最后调用 hello() 的时候,这个 hello 是个undefined . 这说明,虽然我们依赖了一个js库(它会被载入),但requirejs无法从中拿到代表它的对象注入进来供我们使用。
在这种情况下,我们要使用 shim ,将某个依赖中的某个全局变量暴露给requirejs,当作这个模块本身的引用。
|
|
再运行就正常了。
上面代码exports:'hello'
中的hello,是我们在hello.js中定义的hello函数。当我们使用function hello() {}
的方式定义一个函数的时候,它就是全局可用的。如果我们选择了把它export给requirejs,那当我们的代码依赖于hello模块的时候,就可以拿到这个hello函数的引用了。
补充
关于paths参数中配置的'js': 'js'
,目的是为了省略后面的扩展名.js。
参考资料:
haorooms博客:http://www.haorooms.com/post/requirejs_sy_lj
AMD规范:https://github.com/amdjs/amdjs-api/wiki/AMD