1.js模組化演變過程
1.通過立即執行函式達到隱藏私有變數、暴露公共方法
2.通過require.js sea.js這一類js模組載入框架
3.通過ES6 import實現js模組化
2.程式碼演示
1.通過立即執行函式達到隱藏私有變數、暴露公共方法
1. 方案1:
(function(exports){
function add(){
}
var flag = true;
var x = 10;
//匯出(匯出的就相當於全域性物件的屬性、方法,支援任意一個js模組引用其匯出方法、屬性)
//其實就是通過window,將方法屬性新增到其上面
exports.add = add;
exports.flag = flag;
})(window)
2.方案2
var module = (function(){
function add(){ }
var flag = true;
var x = 10; //匯出
return {
add:add,
flag:flag
}
})()
// 這兩種方案其實都可,但是第一種方案是將對外暴露的方法掛載到window上,說白了還是全域性變數。
第二種方案最多隻會暴露一個全域性變數,建議第2種。
複製程式碼
2.sea.js 使用
// sea.js的使用(sea.js會將一個js檔案當做一個模組來看,類似的node裡的require、exports,sea.js的
api和node語法很類似,通過require引入,exports匯出)
// 語法:
// *****定義一個模組******
// *id:模組id,通常就是當前寫的js檔案的路徑(官方建議id不寫)
// *[]:依賴檔案:就是使用這個js之前需要提前引入那些檔案(官方建議不寫)
// *callback:第三個引數為回撥函式,有三個引數,其中module是整個模組的資訊,包括前面所說
的模組id,模組依賴,可通過console.log(module)檢視模組資訊
// 正常寫法
define(id,[],function(require,exports,module){
})
// 推薦寫法
define(function(require,exports,module){
// 引入a模組
var a= require('a');
// 引入b模組
var b = require('b');
// 使用a,b模組匯出的方法
a.run();b.sleep();
// 定義自己的方法、變數
var num = 10;
function eat(){
}
// 匯出自己的方法、變數
// 方法1(問什麼不能用exports指向物件呢,下面會說明)
exports.num = num;
exports.eat = eat;
// 方法2
module.exports = {
num : num,
eat : eat
}
// 方法3
return {
num : num,
eat : eat
}
})
// *****頁面內使用sea.js******
直接<script src="js/sea.js"></script>即可
// 引入口檔案
<script>
// 一般一個html的入口檔案只有一個
seajs.use('init.js') 或 seajs.use('init.js',function(){})
// 如果一個html入口檔案有多個
seajs.use(['init.js','x.js']) 或 seajs.use(['init.js','x.js'],function(){})
</script>
// ******sea.js的配置*******
// 注:只會配置常見項,其他的檢視api文件
seajs.config({
// base是基礎目錄,所有的檔案都是基於base來查詢的,base預設目錄是sea.js存在的目錄
// 但是建議不設定(除非你的sea.js放置目錄很好,否則麻煩的一匹)
// base:''
// 設定別名
alias:{
'jquery':''
}
})
// 說明一下匹配規則,以及建議常見的使用方案
* 在seajs配置中,如果別名的設定 以 相對路徑設定的,則其的匹配規則是: "以當前頁面use使用的目錄為
基準目錄,別名目錄就以它為基準就行尋找,會導致路徑複雜度提高"
* 如果別名設定是以 'app/jquery'這種目錄的,則尋找目錄的基準目錄為base目錄
常見使用方案:
1.sea.js原始檔放在一個好的位置,什麼是好的位置,答案:js檔案下的子檔案(sea所在目錄為js目錄)
2.use () :使用相對路徑,不用別名(記住,不為use檔案設定別名),規則是:當前html引入該use檔案的路徑
3.require():當使用相對路徑時,是相對於當前js檔案的,如果是require('app')的,則會尋找config的別名配置
總之一句話,sea的位置放的好,其他就都不是問題了。
常見問題:
1.為什麼不能exports = {}這種格式匯出?
exports指向了module.exports;真正匯出是通過module.exports匯出的,exports僅僅是 module.exports的對映,當exports指向了新的物件,與module.exports的聯絡便斷了。(和node一樣) 2. sea中使用jq,報錯?
jq用一層包裹;
define(function(){
jq原始碼
return $.noConflict();
})
複製程式碼
3. ES6語法
// b.js
import {a} from './a.js'
// a.js
const a = 10;
export {a}
複製程式碼