🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# requireJS 首先看下目录结构,我们需要使用 requireJS 搭建以下结构的应用 : :-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/%E6%88%AA%E5%9B%BE/QQ%E6%88%AA%E5%9B%BE20180328103514.png) ## 引入 requireJS 在入口文件 index.html 中引入 requireJS,使用 `data-main` 定义入口文件。 ```html <script src="./require.js" data-main="./main"></script> ``` ## config 使用 `require.config` 对 requireJS 进行基础配置。 其中 : (1)baseUrl:模块默认加载路径; (2)paths:自定义模块加载路径; (3)shim:定义模块之间的依赖关系。 比如在 `main.js` 中 : ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min' } } ``` 以上代码进行了基本的 requireJS 配置,其中 baseUrl 将默认加载目录设置在 js 目录下,paths 中的依赖都将相对于 baseUrl 进行配置。 ## require 使用 `require` 对加载的文件进行引用,如使用 jquery,在 `main.js` 中 : : ```js require(['jquery'], ($) => { $('body').css({'background-color':'#0f0'}) }) ``` ## define 使用 `define` 自定义要导出的模块,比如在 `test.js` 中 : ```js define(['jquery'], () => { return { changeBgColor () { $('body').css({'background-color':'#f00'}) }, changeTextSize () { $('body').css({'font-size':'20px'}) } } }) ``` 这里定义了一个自定义模块,define 的第一参数为依赖项,第二参数为回调函数,在里面使用 return 导出需要导出的模块。 使用自定义模块也很容易,在 `main.js` 中 : ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min', 'test': 'test' } }) require(['jquery', 'test'], ($, test) => { $('#bgBtn').on('click', () => { test.changeBgColor() }) $('#textBtn').on('click', () => { test.changeTextSize() }) }) ``` 注意到,paths 中的路径都是基于 baseUrl 的,并不需要带 js 后缀。 在 `index.html` 中 : ```html <div> <div id="text">Hello world</div> <div> <button id="bgBtn">改变颜色</button> <button id="textBtn">改变字体大小</button> <button id="colorBtn">改变字体颜色</button> <button id="resetBtn">恢复字体颜色</button> <button id="boldBtn">改变字体粗细</button> </div> </div> ``` ## 在 shim 中指定依赖 以上 `test.js` 中,明确指定了其依赖,也可以不在自定义模块中指定依赖,而使用配置项指定依赖。 比如 `util.js` : ```js define([], function() { return { changeTextColor () { $('#text').css({'color':'#fff'}) } } }) ``` 也可省略第一参数 : ```js define(function() { return { changeTextColor () { $('#text').css({'color':'#fff'}) } } }) ``` 此时,在 `main.js` 中 : ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min', 'util': 'util' }, 'shim': { 'util': { 'deps' : ['jquery'] } } }) require(['jquery', 'util'], ($, util) => { $('#colorBtn').on('click', () => { util.changeTextColor() }) }) ``` 可以看到,在 `shim` 中使用了 `deps` 指定依赖,其实也可以不指定,只需要在 `require` 中前置加载 jquery 依赖即可。 ## 针对非 AMD 模块 针对非 AMD 模块,requireJS 也提供了加载机制,只需要在 shim 中指定 export 即可。 比如 `exp.js` : ```js function resetTextColor () { $('#text').css({'color':'#000'}) } ``` 此时在 `main.js` 中 ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min' }, 'shim': { 'exp': { 'export': 'resetTextColor' } } }) require(['jquery', 'exp'], ($, exp) => { $('#resetBtn').on('click', () => { resetTextColor() }) }) ``` 可以看到,在 shim 中制定了 exp 文件的输出模块,在 require 里面引用之,可直接调用其方法。 ### 导出多模块 使用 export 只能指定导出一个模块,但如果需要导出多个模块,则需要使用 init 方法。 如改写 `exp.js` : ```js function resetTextColor () { $('#text').css({'color':'#000'}) } const changeTextWeight = () => { $('#text').css({'font-weight':'bold'}) } ``` 在 `main.js` 中 ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min' }, 'shim': { 'exp': { 'init': function(){ return { 'resetTextColor': resetTextColor, // 注意这里不需要加引号 'changeTextWeight': changeTextWeight } } } } }) require(['jquery', 'exp'], ($, exp) => { $('#resetBtn').on('click', () => { exp.resetTextColor() }) $('#boldBtn').on('click', () => { exp.changeTextWeight() }) }) ``` 注意,跟 export 不同,在调用的时候需要使用 exp 调用。 ## 加载 css 可以使用 `css.js` 加载 css 文件,在 shim 中配置即可,如 : ```js require.config({ 'baseUrl': './js/', 'paths': { 'jquery': '../lib/jquery-3.3.1.min', 'util': 'util', 'css': '../lib/css' }, 'shim': { 'util': { 'deps' : ['jquery', 'css!../css/style.css'] } } }) ``` 案例地址: http://xiaoyulive.oss-cn-beijing.aliyuncs.com/date/2018-03-28/require.js.zip ## 总结 最后总结下RequireJs的原理: (1)我们在使用requireJS时,都会把所有的js交给requireJS来管理,也就是我们的页面上只引入一个require.js,把data-main指向我们的main.js。 (2)通过我们在main.js里面定义的require方法或者define方法,requireJS会把这些依赖和回调方法都用一个数据结构保存起来。 (3)当页面加载时,requireJS会根据这些依赖预先把需要的js通过document.createElement的方法引入到dom中,这样,被引入dom中的script便会运行。 (4)由于我们依赖的js也是要按照requireJS的规范来写的,所以他们也会有define或者require方法,同样类似第二步这样循环向上查找依赖,同样会把他们村起来。 (5)当我们的js里需要用到依赖所返回的结果时(通常是一个key value类型的object, requireJS 便会把之前那个保存回调方法的数据结构里面的方法拿出来并且运行,然后把结果给需要依赖的方法。