1. 程式人生 > >前端模組化之ES Module

前端模組化之ES Module

## 一、概述 之前提到的幾種模組化規範:CommonJS、AMD、CMD都是社群提出的。ES 2015在語言層面上實現了模組功能,且實現簡單,可以替代CommonJS和AMD規範,成為在伺服器和瀏覽器通用的解決方案 ## 二、特性 #### 1、ES Module自動啟用嚴格模式 ```javascript ``` #### 2、ES Module執行在單獨的作用域中,與外界互不干擾 ```javascript ``` #### 3、ES Module是通過CORS方式請求外部檔案,需外部檔案支援CORS請求 ```html //該檔案支援CORS請求,則可以請求成功 //該檔案不支援CORS請求,報跨域錯誤 ``` #### 4、ES Module引用的檔案會延遲執行 ``` //index.js alert('hello'); ``` ```html //index.html 等價於

文字內容

``` **執行結果【js的載入並未影響到DOM的載入】** ![](https://img2020.cnblogs.com/blog/741018/202102/741018-20210207151816321-1247304482.png) ## 三、export命令 由於在ES Module中,每個模組都是一個單獨的作用域,如果想使模組內的變數暴露出去,使用**export**關鍵字,匯入其他模組的關鍵字使用**import**。 #### 1、挨個匯出變數 ```javascript //module.js export var name = "張三"; export function add(a, b) { return a + b; } export var obj = { name: 'jack' }; ``` #### 2、批量匯出變數 ```javascript //module.js var name = "張三"; function add(a, b) { return a + b; } var obj = { name: 'jack' }; export { name, add, obj } ``` 優點:在指令碼尾部,使用一個export統一匯出,清晰簡潔 #### 3、匯出預設資料 ```javascript //module.js export default 'es module' 或者 export default function(a,b){ return a+b; } ``` **注意:**說完import後再說注意事項 #### 4、匯出時起別名,使用as關鍵字 ```javascript //module.js var name = "張三"; function add(a, b) { return a + b; } var obj = { name: 'jack' }; export { name as v1, add as v2, obj as v3} ``` ## 四、import命令 要想接受其他模組通過export匯出的成員時,使用import關鍵字 #### 1、import匯入其他模組中的變數 ```javascript //module.js var name = "張三"; function add(a, b) { return a + b; } export { name ,add } ``` ```javascript //app.js import { name, add as MathAdd} from "./module.js" console.log(name);//張三 console.log(MathAdd(1, 1)) //2 ``` 注意: ##### 1.1使用相對路徑 字尾名和./不能省略 ​ import {name} from "./module.js" ##### 1.2使用絕對路徑 ​ import {name} from "/demo/module.js" ##### 1.3使用全路徑 ​ import {name} from "http://localhost:8080/demo/module.js" ##### 1.4可以在匯入模組時使用as 起別名 ​ 起別名後,as前的變數不可使用了 #### 2、使用import只執行引入檔案,不提取引入檔案中的成員時 1. import {} from "./module.js"; 2. import './module.js'【常用】 ```javascript //module.js console.log('module.js中執行') var name = "張三"; function add(a, b) { return a + b; } var obj = { name: 'jack' }; export { name, add, obj } ``` ```javascript //app.js import {} from "./module.js"; 或者寫成 import './module.js' ``` ```html //index.html //執行結果 //module.js中執行
``` 當多次執行同一個import語句時,只會執行一次 #### 3、模組的整體載入 使用import除了可以載入單個值,也可以一次性載入模組匯出的所有值 ```javascript //module.js var name = "張三"; function add(a, b) { return a + b; } var obj = { name: 'jack' }; export { name, add, obj } ``` ```javascript //app.js import * as all './module.js' console.log('name:',all.name); console.log('obj',all.obj); console.log(add(1,1)) ``` ## 五、export default 前面使用export匯出模組內的成員時,需要指定具體的成員名稱,同樣載入時需要根據匯出的具體名稱進行載入。還有一種快捷的匯出方式,使用export default 為模組指定預設匯出,**每個模組只能使用一次export default**。 #### 1、匯出匿名成員時,使用任意變數接受成員 ```javascript //module.js export default function(a, b) { return a + b; } ``` ```javascript //app.js import add from "./module.js"; console.log(add(1,2)); ``` 因為使用export匯出成員時是匿名的,所以在匯入時並不知道這個成員的名字是什麼,這時候就可以隨意寫變數去接受這個匿名成員,案例中使用add接受的匿名函式,也可以使用其他名稱接收。 **注意:export default也可以匯出具名成員,但效果和匯出匿名成員是一樣的** ```javascript //module.js export default function add(a, b) { return a + b; } //或者 function add(a,b){ return a + b; } export default add ``` ```javascript //app.js import temp from "./module.js"; console.log(temp(1,2)); ``` **總結:使用export default匯出成員,在外部載入時都視為匿名成員載入,可以隨意起變數名接受** #### 2、同時匯入其他模組的預設成員和具名成員時 ```javascript //module.js var name = 'jack'; var age = 19; export { name, age } //匯出預設成員 export default 'default export' ``` ```javascript //app.js import str,{name,age} from "./module.js"; 或者 import {name,age,default as str} from "./module.js" console.log(str);//default export console.log(name);//jack console.log(age);//19 ``` #### 3、另類的預設匯出 ```javascript //module.js var number = 1; export { number as default } 等同於 export default number; ``` ```javascript //app.js import { default as number} from "./module.js" console.log(number); //1 ``` **總結:可見export default的本質就是匯出一個名字叫default的成員,當匯出的成員叫default時,接受這個成員可以隨意命名** #### 4、使用export default來匯出類 ```javascript //Person.js export default class Person(){ .... } //main.js import Person from "./Person.js"; const person = new Person(); ``` #### 5、比較一下預設輸出和正常輸出 ```javascript //1.預設輸出 export default function add(a,b){ return a + b; } //接受預設輸出 import temp from './module.js' //2.具名輸出 function add (a,b){ return a + b; } export {add} //接受具名輸出 import {add} from './module.js' ``` **總結:使用預設匯出時,在外部接受成員,不需要使用大括號;使用具名輸出時,在外部接受成員時,import後需要使用大括號** ## 六、迷惑性的點 #### 1、export批量匯出變數時,匯出的並不是物件字面量 ```javascript //module.js var name = 'jack'; var age = 19; export { name, age } //export {name,age} 並不是匯出的一個物件,而是export批量匯出的語法 ``` #### 2、import載入多個變數時,並不是ES6的解構用法 ```javascript import {name,age} from "./module.js" //impot後面的大括號並不是解構作用 ``` #### 3、import匯入的變數都是常量,不可修改,與CommonJS不同 ## 七、export和import的複合用法 當我們在檔案內import一個成員後,同時把它匯出時 ```javascript //index.js import {Button} from './button.js' export { Button } 可以寫成 export {Button} from "./button.js" ``` ## 八、import()函式 import關鍵字匯入其他模組成員時,必須寫在最頂層作用域,不可巢狀在其他邏輯處理中。如果說我們想在某段邏輯執行完成後去動態載入某些成員,這時候可以使用import()函式載入 ```javascript //module.js var name = "張三"; function add(a, b) { return a + b; } var obj = { name: 'jack' }; export { name, add, obj } export default function() { return '匿名成員' } ``` ```javascript //app.js //使用setTimeout來模擬一個非同步載入的過程 setTimeout(() =>
{ //import返回的是個promise,返回的模組內容都在回撥函式的引數中(moduleResult) import ("./module.js").then(moduleResult => { console.log(moduleResult) console.log(moduleResult.add) console.log(moduleResult.name) console.log(moduleResult.default) console.log(moduleResult.obj) }) //也可以直接把成員結構出來 import ("./module.js").then(({add,name,obj,default:defaultData}}) =>
{ console.log(moduleResult.add) console.log(moduleResult.name) console.log(moduleResult.defaultData) console.log(moduleResult.obj) }) }, 200