沒有規(guī)矩忠烛,不成方圓芥喇,今天我們就來聊聊模塊化規(guī)范
模塊:對(duì)一些復(fù)雜的代碼功能進(jìn)行分離、按照某個(gè)規(guī)范進(jìn)行封裝成單個(gè)或者多個(gè)文件罐呼,同時(shí)暴露一些屬性或者方法給外界調(diào)用鞠柄。
為什么要模塊化?
1.避免變量污染或者沖突
2.便于代碼封裝嫉柴,提高復(fù)用性
3.代碼便于維護(hù)厌杜,邏輯分離
溫馨提示:文章結(jié)構(gòu)如下,閱讀完可能需要花費(fèi)3分鐘
一计螺、模塊化的進(jìn)化過程
二夯尽、模塊化規(guī)范之-CommonJS規(guī)范
三、模塊化規(guī)范之-AMD規(guī)范
四登馒、模塊化規(guī)范之-CMD規(guī)范
五匙握、模塊化規(guī)范之-ES6規(guī)范
進(jìn)入正文
一、模塊化的進(jìn)化過程
1.全局function模式 : 將不同的功能封裝成不同的全局函數(shù)
優(yōu)點(diǎn):把單一功能封裝在函數(shù)中陈轿,增加復(fù)用性
缺點(diǎn):命名空間被污染圈纺,數(shù)據(jù)不安全,容易命名沖突
使用案例:
function funcA() {
console.log('函數(shù)A')
}
function funcB() {
console.log('函數(shù)B')
}
2.namespace模式: 命名空間麦射,封裝成對(duì)象
優(yōu)點(diǎn):減少全局變量
缺點(diǎn): 數(shù)據(jù)不安全蛾娶,可以直接修改內(nèi)部變量
使用案例:
const module = {
message: "我是一個(gè)message",
run(){
console.log('開始運(yùn)行', this.message);
},
};
module.message = "test";
module.run();
3.IIFE模式: 立即執(zhí)行函數(shù)
優(yōu)點(diǎn):私有數(shù)據(jù),外部只能訪問暴露的方法或者屬性
缺點(diǎn):模塊依賴其他模塊比較麻煩
使用案例:
(function (window) {
const url = "www.baidu.com";
function run(){
console.log('開始運(yùn)行', this.url);
};
window.myModule = {run, url};
})(window);
myModule.run();
二潜秋、模塊化規(guī)范之-CommonJS規(guī)范
同步加載蛔琅,服務(wù)端文件一般存在本地,所以使用同步加載比較快峻呛,這個(gè)規(guī)范服務(wù)端常用
CommonJS說明
1.1.每個(gè)文件就是一個(gè)模塊罗售,有自己的作用域;
1.2 每個(gè)文件里面定義的變量杀饵、函數(shù)莽囤、類谬擦,都是私有的切距;
1.3.服務(wù)端-模塊的加載是運(yùn)行時(shí)同步加載;
1.4.瀏覽器端-模塊需要提前編譯打包處理惨远,才可以被運(yùn)行
1.5 運(yùn)行時(shí)確定依賴關(guān)系
1.6 CommonJS 模塊輸出的是一個(gè)值的拷貝基本語法
導(dǎo)出方式一 : module.exports.xxxx = value
const url = "www.zb.com";
function funcA() {
console.log('commonjs-導(dǎo)出-模塊A',url);
}
//暴露屬性
module.exports.test = url;
// 暴露方法
module.exports.funcB = funcA;
導(dǎo)出方式二 : module.exports = {}
module.exports = {
count: 4,
addCount(){
this.count++;
},
printB(){
console.log('打印模塊B');
}
}
導(dǎo)入引用: require('路徑引入或者第三方模塊')
瀏覽器不能直接使用require,需要使用webpack 或者browserify 編譯之后的文件瀏覽器才能識(shí)別
本質(zhì):加載某個(gè)模塊谜悟,其實(shí)是加載該模塊的module.exports屬性
const moduleA = require('./moduleA.js');
const moduleB = require('./moduleB.js');
console.log('打印模塊A的屬性',moduleA.test);
moduleA.funcB();
moduleB.printB();
console.log('模塊計(jì)算前的值',moduleB.count);
moduleB.addCount();
console.log('模塊計(jì)算后的值',moduleB.count);
3.使用工具
browserify 或者 weback
三话肖、模塊化規(guī)范之-AMD規(guī)范
非同步加載,主要用于瀏覽器端
AMD規(guī)范說明
1.1 主要用于瀏覽器端葡幸,模塊加載是異步的
1.2 依賴于require.js-
基本語法
導(dǎo)出方式一 : 無依賴直接導(dǎo)出模塊define(function () { const moduleA = { getMessage: function () { return "我是模塊A的message"; } } return moduleA; });
導(dǎo)出方式二 :有依賴導(dǎo)出
define(['moduleA'], function (moduleA) {
const moduleB = {
getReuslt: function () {
return moduleA.getMessage() + "我是模塊B";
},
};
return moduleB;
});
引用模塊
require(['moduleA','moduleB'], function (moduleA , moduleB) {
moduleB.getReuslt();
})
- AMD + requirejs 使用
第一步: 下載require.js
下載方式 : 官網(wǎng)下載 或者 npm install requirejs --save-dev
第二步: 創(chuàng)建自定義模塊, 目錄如下moduleA, moduleB
第三步: 創(chuàng)建main.js 作為自定義模塊的入口并配置
// main.js
(function () {
require.config({
baseUrl: "./05-模塊化規(guī)范/053-AMD規(guī)范",
paths:{
//映射: 模塊標(biāo)識(shí)名: 路徑 不能加js
moduleA: './moduleA',
moduleB: './moduleB'
}
});
require('moduleB', function (moduleB) {
moduleB.getReuslt();
})
})();
第四步:html中引用main.js 與requirejs
<script src="../node_modules/requirejs/require.js" defer async="true"data-main="./053-AMD規(guī)范/main.js"></script>
defer async 表示異步 兼容寫法
src: 引用requirejs
data-main: 模塊入口
三最筒、模塊化規(guī)范之-CMD規(guī)范
CMD規(guī)范說明
1.1 commonjs + AMD 組合版
1.2 主要用于瀏覽器
1.3 模塊的加載是異步的
1.4 依賴于sea.js基本語法
導(dǎo)出方式一:導(dǎo)出沒有依賴的模塊
define(function (require, exports, module) {
const moduleAA = {
message: "我是模塊AA",
};
module.exports = moduleAA;
});
導(dǎo)出方式二:導(dǎo)出有依賴的模塊
define(function (require, exports, module) {
const moduleAA = require('./moduleAA');
const moduleBB = {
printMessage:function () {
console.log("我是模塊BB" + moduleAA.message);
},
};
module.exports = moduleBB;
});
引入導(dǎo)入方式:define(function (require) {})
define(function (require) {
const moduleBB = require('./moduleBB');
const moduleAA = require('./moduleAA');
// console.log('main文件打印---',moduleAA.message);
console.log('main文件打印---',moduleBB.printMessage());
});
- CMD+sea.js
第一步:下載或安裝seajs npm install seajs --save-dev
第二步:新建自定義模塊, 目錄結(jié)構(gòu)如下
第三步:新增main.js作為模塊入口
// main.js
define(function (require) {
const moduleBB = require('./moduleBB');
const moduleAA = require('./moduleAA');
// console.log('main文件打印---',moduleAA.message);
console.log('main文件打印---',moduleBB.printMessage());
});
第四步:html 使用模塊
<script src="../node_modules/seajs/dist/sea.js"></script>
<script type="text/javascript">
seajs.use('./054-CMD規(guī)范/main');
</script>
五、模塊化規(guī)范之- ES6規(guī)范- 常用
ES6規(guī)范說明
1.1 編譯時(shí)確定依賴關(guān)系
1.2 ES6 模塊是動(dòng)態(tài)引用蔚叨,并且不會(huì)緩存值床蜘,模塊里面的變量綁定其所在的模塊
1.3 ES6 模塊輸出的是值的引用值基本語法
導(dǎo)出
export default xxx 或者 export {}
導(dǎo)入
import
- 語法編譯工具
A. 使用Babel將ES6編譯為ES5代碼;
B. 使用Browserify編譯打包js