模塊化
什么是模塊?
一個具有處理邏輯的js文件,把相關的方法或?qū)ο筮M行導出,經(jīng)過導入就可以使用.
模塊化有什么作用?
- 避免命名沖突(減少命名空間污染)
- 更好的分離, 按需加載
- 更高復用性
- 高可維護性
- 分治(你會發(fā)現(xiàn)當邏輯復雜的時候蟀俊,可以分得更加細的模塊猜旬,而且多人同時開發(fā)楔绞,可見分治是模塊化最大的優(yōu)點。)
為什么要用模塊化?
那么webpack提出來的,萬物都是模塊化.比如一個項目越做越大,項目也變得越來越難維護,JavaScript模塊化,把每個單獨的可復用性的業(yè)務邏輯抽離出來成為一個個模塊,需要用到的時候直接導入,進行使用,一處編寫處處使用,以后業(yè)務需要更新,只需要改模塊的邏輯即可.我們項目肯定會封裝一個異步請求的js文件,使用的時候代碼非常精簡,舒服.
在ES6之前,javascript是不是沒有模塊體系,javascript社區(qū)制定的CommonJS,AMD赖条,CMD.都是不是我們真正需要的,直到ES6提出來的模塊化—ES6模塊
<font color="red" size=3>主角放在前面 ??????</font>
主角ES6 模塊
在 ES6 前, 實現(xiàn)模塊化使用的是 RequireJS (基于 AMD 規(guī)范的模塊化庫)或者 seaJS(基于 CMD 規(guī)范的模塊化庫)扰她。直到ES6模塊出來了,他們就被取代了, 新王登基犹赖。
嚴格模式:模塊化自動是嚴格模式,總之我們老老實實寫,不會報錯了啦.
**export(導出): **規(guī)定模塊的對外導出的接口
import(導入): 規(guī)定模塊的對外導入的接口
實踐一下怎么使用
導出:
//寫一個邏輯代碼,這是js文件===模塊
function atoe(params) {
console.log("這是模塊中的邏輯代碼",params);
}
export { //導出
atoe, //方式一:將函數(shù)暴露出去
atoe as newAtoe //方式二: 將newAtoe暴露出去,然而newAtoe引用了atoe,達到了重命名的效果
//所以這里總共導出了 atoe 和 newAtoe到外面.
}
導入:
//組件中使用,我以vue為例子.其他也一樣的.
//這是要使用的時候?qū)?
<template>
<div>
<button @click="runAtoe('msg')">HelloWorld</button>
</div>
</template>
<script>
//導入方式一:這種叫做按需導入方法,物盡其用.贊成??
import {atoe, newAtoe} from '../js/atoeModule'
export default {
methods: {
runAtoe(params){
atoe(params);
newAtoe(params);
}
},
}
</script>
<script>
//導入方式二:整體導入,這種不管三七二十一,全部導過來,然后這里把他們都放在了allFn這個對象里面,然后通過對象獲取他們,也沒有說這種不行就是low
import * as allFn from '../js/atoeModule'
export default {
methods: {
runAtoe(params){
allFn.atoe(params);
allFn.newAtoe(params);
}
},
}
</script>
注意這兩種做法沒有性能差別,因為ES6模塊是靜態(tài)加載,只是一個引用,不會在內(nèi)存中造成負擔.
剛剛上面介紹的是非常合情理的導入導出.但是為了照顧哪些心急的人,往往也需要添加一些東西,來滿足他們的需求
export default: 默認導出,它能帶來的好處就是<font color="red" size=3>一次導出(只能導出一次)</font>,導出的時候只要路徑對了,不管你取什么名字,都可以使用.
導出:
//寫一個邏輯代碼
function atoe(params) {
console.log("這是模塊中的第一個邏輯代碼",params);
}
function atoe2(params) {
console.log("這是模塊中的第二個邏輯代碼",params);
}
export default{ //默認導出
atoe,
atoe2
//所以這里默認暴露出去 atoe atoe2
}
導入:
<script>
//這個allFn你想用什么名字都是可以的,just you like it.
//注意點: 因為它導出來得是對象,所以不用花括號{},注意一下.
import allFn from '../js/atoeModule'
export default {
methods: {
runAtoe(params){
allFn.atoe(params);
allFn.atoe2(params);
}
},
}
</script>
<font size=4 color="###">總結(jié):ES6模塊化就這么點東西,但是這里導入導出太多方法了,請記住一點:用了一種就要一直用,不忘初心,懂吧,不然到后面你會懷疑你垃圾代碼原來是自己寫得.</font>
CommonJS(用于服務器)
node是用CommonJS規(guī)范的,然后node是后臺語言,所以這個規(guī)范是用于服務器的.
導出:exports
或者module.exports
暴露需要被外部訪問的屬性和方法。<font size=4 color="red">記得別和ES6模塊搞混了,export這是多個S, export default 也不一樣.</font>
導入:require("url");
var module = {
exports: {}
};
(function (module, exports) {
exports.atoe = function (n) { return n };
}(module, module.exports))
var atoe = module.exports.atoe;
atoe(1) //1 這是CommonJS的原理
為什么CommonJS僅僅適用于服務器不適用瀏覽器?
場景:當我們需要加載一個模塊的時候,這時候 CommonJS規(guī)范適用了 var atoe = require("atoe"); 如果在服務器完全ok的,因為atoe這個模塊肯定在服務器,即拿即用.就是用的時候加載也ok,它就是運行的時候atoe才是確定的值,無所謂啊.然后當我們?yōu)g覽器用的這個模塊的時候還要去請求,好了拿到了,堵塞代碼了,怎么可能會用這種規(guī)范.但是可以做其他處理,我覺得沒有必要深究下去了.
import 是編譯時就完成模塊加載,效率比CommonJS,沒有說CommonJS垃圾,只是說CommonJS只是用于服務器端.
AMD (Asynchronous Module Definition)用于瀏覽器
中文意思異步模塊定義,有沒有發(fā)現(xiàn)異步的東西好像都能扯上瀏覽器身上.
AMD 是RequireJS[模塊加載器]的一種規(guī)范,然后加載的時候不會堵塞瀏覽器的渲染董瞻,AMD 推崇依賴前置寞蚌。
有趣的是webpack也是打包工具,但是它的規(guī)范是CommonJS
CMD(Common Module Definition )
CMD是Seajs [web端模塊加載器]推廣的產(chǎn)物,嗯钠糊,他對我未來的方向毫無幫助睬澡,我不打算去了解太深入,CMD 推崇依賴就近 眠蚂。
我們的重點是ES6的模塊化
模塊化的發(fā)展史
歷史故事總是有趣的
一、原始寫法函數(shù)
function Atoe(){
console.log("這是最low的模塊寫法")
}
其實當這個在現(xiàn)在偶爾還是會在頁面出現(xiàn)的斗躏,因為簡單易用的邏輯通過函數(shù)寫出來逝慧,進行復用還是可取的,但是對于大的模塊化是不可能的啄糙。
缺點:1.污染全局命名空間笛臣。
2.容易引起命名沖突或數(shù)據(jù)不安全。
3.而且模塊成員之間看不出直接關系隧饼。
二沈堡、對象寫法
let Atoe = {
name : "Atoe",
can : function(){
console.log(`${this.name}can code`);
}
}
解決問題:1.減少了全局變量。
2.解決命名沖突燕雁。
缺點就是:1.對象外部可以修改內(nèi)部的一切東西诞丽,不安全鲸拥。
三、立即執(zhí)行函數(shù)寫法
((function (win) {
let name = "Atoe";
function atoe() {
console.log("這是自調(diào)用函數(shù)里面的atoe函數(shù)");
}
win.me = { //win 接收到window參數(shù)僧免,然后通過給windo添加一個me屬性刑赶,將函數(shù)里面的東西暴露出去,見下圖
name:name,
atoe:atoe
}
})(window))
console.log( window.me.name); //Atoe
window.me.atoe(); //這是自調(diào)用函數(shù)里面的atoe函數(shù)
// 大名鼎鼎的jQuery都是用立即執(zhí)行函數(shù)懂衩,好像是一個天衣無縫的解決方案撞叨。
解決問題:外部無法修改里面的東西。
但是這個歷史上面的浊洞,沒有一個是真正嚴格意義上的模塊化牵敷,真正的屬于前端,而且適用于前端的法希,就是ES6模塊