1. 認識
GitHub 自己練習的代碼
RequireJs 是一個 js 文件,用于 模塊化的管理 js 文件,屬于 AMD 規范的一種實現;可以 提升速度 和 提高代碼質量;詳情見官網:http://requirejs.org/
2. 使用
2.1 入口
配置 require.js 的 js 文件時,增加 data-main 屬性,即為 js 的入口;
Note:data-main 所指定的 js 文件是 異步加載的,所以在頁面指定多個 js 時,即便是放在 data-main 的下方也無法保證 加載的順序;
對于入口文件的選擇:
① 如果項目是將一個頁面分為 多個 layout(tiles 布局,如 general:頁面的整體,其他各個layout 填充該 頁面;header:頁面的頭部,填充 genneral;footer:頁面的尾部,填充 genneral;main:頁面的主體,不同的頁面分別創建,填充 general 等),可以在 genneral頁面 引入配置文件;而在 main 頁面 引入 各個頁面的 js ;這樣就可以保證 配置文件在 各個頁面的 js 之前加載,就可以在 main 頁面的 js 中 使用 配置文件中的配置;
② 如果并沒有采用這種布局,那么不同 jsp 頁面的 入口文件就使用 各個頁面的 js 文件 ,如果要使用配置文件 定義新的模塊,則可以在 define 引用的模塊數組中加入 配置文件的js,然后加入配置文件中已配置的 js 名,在需要使用的時候,再使用 require 加載 配置文件中的 js 名,否則的話,無法引用到;示例如下:
定義公共util.js 模塊 ,配置文件使用下方的 main.js
/** * Created by xlch on 2016/12/27. *///這里會使用到配置文件中配置的 jquery,所以依次引用 配置文件js,jquery//這里雖然引用了 main 模塊,但是其中只是聲明了 jquery,要調用該模塊仍然需要常規的 require 或者 define//這里引用的 jquery 并不存在于js/lib/jquery 路徑下,而是配置在 man.js 中,所以還需要下面的 requiredefine(['require','module','../main', 'jquery'],function (require,module) { //這里才真正的加載到 jquery;而且 jquery 必須定義在 define 的模塊數組中 var $ = require("jquery"); var utils = {}; utils.quick = { click:function (method,node) { var list = null; if (node) { list = $(node).find("[data-click]"); }else { list = $("[data-click]"); } list.on("click",function (eventObject) { var click = $(this).data("click"); if (click && method[click]) { return method[click].apply(this,[eventObject]); } }); }, offClick:function (method, node) { if (node) { $(node).find('[data-click]').off('click'); }else { $('[data-click]').off('click'); } } }; return utils;});入口文件 栗子:
<script src="${ctx}/js/require.js" data-main="${ctx}/js/app/home"></script>2.2 requirejs 配置文件
常用配置屬性
baseUrl: 所有模塊查找的根路徑,
★ 如果未設置 baseUrl 參數,未使用 data-main 屬性,則 baseUrl 的默認值 為 加載 require.js 的 HTML 頁面 的 位置;
★ 如果未設置 baseUrl 參數,使用了 data-main 屬性,那么 baseUrl 為 data-main 的 路徑;
paths:在 baseUrl 下 不能直接發現的 模塊名,則使用該選項映射路徑,例如含有多級目錄,或者在baseUrl 的上級目錄;不需要 .js 后綴;
bundles:
shim:用于配置 不兼容的模塊,即沒有使用 define() 聲明 依賴 并且 沒有設置一個 模塊名的 傳統型 腳本;例如 backbone.js;
Note :shim配置僅設置了代碼的依賴關系,想要實際加載shim指定的或涉及的模塊,仍然需要一個常規的require/define調用。設置shim本身不會觸發代碼的加載。
其下有兩個主要參數:
★ deps :用于聲明依賴,數組的形式
★ exports:定義一個模塊的名稱,作為該 js 的全局引用
那些僅僅作為 jQuery 或者 Backbone 的插件存在,而不用導出任何模塊變量的 模塊,可以簡單配置為依賴的數組;
requirejs.config({ shim: { 'jquery.colorize': ['jquery'], 'jquery.scroll': ['jquery'], 'backbone.layoutmanager': ['backbone'] }});waitSeconds:加載 js 等待的 最長時間,超時則放棄加載,默認時間為 7秒
配置文件栗子:
main.js:
/** * Created by xlch on 2016/12/27. */require.config({ //所有模塊查找的根路徑 baseUrl: 'js/lib', //目的是將繁瑣的引用名稱簡化,只需要 require(['jquery'],function(){})即可 //路徑是相對于 baseUrl 的路徑 paths: { "jquery":'jquery/jquery-3.1.1.min', }, // 配置非 amd 規范的 js ,增加依賴 和 輸出名稱 shim: { // 'backbone':{ depts:['jquery','underscore'], exports:'Backbone' }, 'underscore':{ exports:'_' }, }, //加載 js 等待的 最長時間,超時則放棄加載,默認時間為 7秒 waitSeconds: 30, //main.js 之后加載的 js 的末尾添加后綴,防止緩存,但是生產環境需要去掉 // urlArgs: "bust=" + (new Date()).getTime(), // 應用級別的參數,通過 module.config() 使用,未解 config:{ 'name':{ na:'xlch' }, },});2.3 define
define 用于定義一個 模塊 ,定義的模塊可以通過 require 調用;這里注意一定要將 結果返回,無論是對象還是函數; 因為 define 定義的模塊是給 require 調用的;這樣 define 就可以 被外部的其他 模塊(module)捕捉到,即可以利用該模塊;
例如上面定義一個公共的 util 模塊,見上面的示例代碼 util.js;
再copy 一下,使用上面的 main.js:
/** * Created by xlch on 2016/12/27. *///這里會使用到配置文件中配置的 jquery,所以依次引用 配置文件js,jquery//這里雖然引用了 main 模塊,但是其中只是聲明了 jquery,要調用該模塊仍然需要常規的 require 或者 define//這里引用的 jquery 并不存在于js/lib/jquery 路徑下,而是配置在 man.js 中,所以還需要下面的 requiredefine(['require','module','../main', 'jquery'],function (require,module) { //這里才真正的加載到 jquery;而且 jquery 必須定義在 define 的模塊數組中 var $ = require("jquery"); var utils = {}; utils.quick = { click:function (method,node) { var list = null; if (node) { list = $(node).find("[data-click]"); }else { list = $("[data-click]"); } list.on("click",function (eventObject) { var click = $(this).data("click"); if (click && method[click]) { return method[click].apply(this,[eventObject]); } }); }, offClick:function (method, node) { if (node) { $(node).find('[data-click]').off('click'); }else { $('[data-click]').off('click'); } } }; return utils;});NOTE:無論是 define 還是 require,要想能夠使用已知的模塊,必須都要放在 其中的 模塊名的數組([ ])中,無論是一級 require ,還是多級 require,他們都是在數組中;
2.4 require
require 用于調用 已定義的模塊 完成頁面渲染;與 define 的區別是,無返回值,不能夠被外部其他的模塊感知到;
示例代碼:可以在用到某個 js 的時候再使用 require 加載;
/** * Created by xlch on 2017/2/6. *///加載配置文件js,以及默認提供的 modulerequire(['../main','module'],function (main,module) { require(["../help/util"],function (util) { util.quick.click({ delete:function () { alert("delete"); } }); require(['underscore'],function (_) { var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; console.log(_.pluck(stooges, 'name')); }); })})如果在加載配置文件的同時,還想使用 配置文件中配置的 module 的話,例如上面 main.js 中配置的 jquery:
可以這樣:
require(['require', '../main', '../help/util'], function (require,main,util) { util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})但是如果我仿照 define 中那樣使用 jquery 的話,會報錯 ,jquery 404 not found
他尋找的地址為 js/app/jquery,但是我 main 中配置的 baseUrl 為 js/lib ,這里使用的路徑是 js/app ;
按照推斷,應該是此時的 main.js 還沒有加載,不知道推斷的是否正確
//這里會報錯,無法找到 js/app/jquery.js ,而 jquery 的真正路徑配置在 main.js 中//說明,這里 main.js 應該還沒有加載嗎?按照上面的 baseUrl 產生規則//設置了 data-main,未設置 baseUrl,則 baseUrl 為 data-main 的路徑//即 入口處貼的 js/app/home.js ,完全吻合;require(['require', '../main', '../help/util', 'jquery'], function (require,main,util) { var $ = require("jquery"); console.log($("#h2").text()); util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})如果,這里我把 require 的 模塊數組中的 jquery 去除,則可以成功跑通;如下代碼調整require(['require', '../main', '../help/util'], function (require,main,util) { var $ = require("jquery"); console.log($("#h2").text()); util.quick.click({ delete: function () { alert("delete 222"); } }); require(['backbone'], function (Backbone) { Backbone.Model.extend({}); }); require(['jquery'],function ($) { console.log($("#h2").text()); })})另外,require 的模塊數組 中提供了 domReady! ,作用是 保證 在 DOM 準備完畢之后 該 模塊的函數 才能被調用;require(['domReady!'], function (doc) { //等待 DOM 加載完畢之后,調用該函數});為了防止加載時間過長,導致 requirejs 產生 超時的錯誤,可以在 配置文件 main.js 中 增加 waitSeconds 配置等待的最長時間,或者 使用 domReady() 方法調用;
require(['domReady'], function (dom) { domReady(function () { // DOM 加載完畢后執行 });});《 簡單總結 ,未完待續 》
新聞熱點
疑難解答