ES6 新特性之 Module
關於模組化,在之前有過AMD和CMD,require.js以及後面的sea.js,實際上都是藉助於第三方的外掛。那麼在ES6裡面它官方引入了模組化程式設計,它的不同之處在於:
ES6的Module它的執行環境實際上是編譯時的,也就是說在編譯時它就會把所有的依賴匯入匯出,每一個模組有自己獨立的名稱空間,然後這些關係都明確了。
1:基本概念
編譯時模組(module)體系
2:export - 規定模組的對外介面
export在ES5之前或者是在sea.js和require.js裡面我們用的都是export.default,但是在ES6我們實際上只需要用一個export關鍵字就可以了,它是規定模組化的對外介面,也就是說匯出的是什麼。
情況一:下面的程式碼這兩個如果放在一個模組化的尾部(或者是一個js尾部、一段程式碼尾部),那麼它的意思就是說匯出了兩個變數,一個叫做name,一個叫做age,這是最基本的用法。
也就是說在一個js一段程式碼下我們匯出了兩個模組,兩個變數可以供外部使用或者說兩個方法。
export const name = 'Eric';
export const age = 28;
情況二:default,預設引入。
當別人使用我們寫的模組的時候,可能會不知道我們匯出的關鍵字是什麼,但是當使用了default之後,不管外來是以什麼引入,以什麼變數把它命名為什麼都沒有關係,因為這時候匯出的是整個的物件。因此,別人在引用這個物件時,可以隨意命名,物件下面就可以看到變數的名稱。
const name = 'Eric';
const age = 28;
export default { name, age };
情況三:匯出方法
const name = 'Eric';
const age = 28;
export default function getProperty() {
return `name: ${name} age: ${age}`
};
情況四:自身匯出
const name = 'Eric'; const age = 28; export default { name as customName, age as customAge };
3:import - 載入模組
這裡{ name, age }用到的是一個解構,對應上面的第一種匯出寫法。
import { name, age } from '../xxx.js';
重新命名:
import { name as customName } from '../xxx.js';
下面的沒有{}沒有解構的它得到的是一個預設匯出的,可以不用解構就直接匯出。
import getProperty from '../xxx.js';
lodash是一個很有用的函式是程式設計的工具庫。
在ES6裡面,當我們引入兩個同樣的內容的時候,比如下面的寫兩遍import,但實際上它只會引入一次。甚至說當我們引用了同一個檔案兩次,每次取它不同的方法,但是實際上也只引入一次。這是ES6 Module內部的特有處理。
import 'lodash';
import 'lodash';
import { name } from '../xxx.js';
import { age } from '../xxx.js';
整個檔案全部引入:* 代表所有,如下把../xxx.js檔案下所有的都匯出來然後把它命名到這個utils 。
import * as utils from '../xxx.js';
4:export 與 import 複合
在某些場景下,我們可能需要把export和import結合。比如我們引入了很多其他的庫,然後封裝一下供我們使用,在封裝時我們需要引入其他的庫,也就是import,然後丟擲來給我們自己的模組,這個時候我們就要用到export。
// 先引進來再匯出去
import { foo, bar } from '../xxx.js';
export { foo, bar };
/* 等同於 */
export { foo, bar } from '../xxx.js';
把../xxx.js中的全部匯出來然後再把它匯出去:
export * from '../xxx.js';
把../xxx.js裡面default匯出的再把它匯出來,這樣省去了一些中間變數:
export { default } from '../xxx.js';
從../xxx.js中只引入其中一個es6,但是我們把它預設的default成為了一個es6:
import { es6 } from '../xxx.js';
export default es6;
// 等同於 也就是說從../xxx.js把es6引進來然後再把它export預設匯出
export { es6 as default } from '../xxx.js';
// 預設匯出也可以重新命名
export { default as es6 } from '../xxx.js';
5:import() - 動態載入
import除了引入模組,一般來說我們通常是把它放在檔案的頂部來引入依賴,但是這個import它可以動態載入。比如說我們有一些檔案不需要用到,比如點選某一個按鈕才可能去實現一些功能,那麼實現這個功能的時候我們就需要一些額外的檔案,這個時候就需要用到import動態載入了。
- 按需載入
button.addEventListener('click', event => { import('./xxx.js') .then(value => { console.log(value); }) .catch(error => { /* Error */ }) });
- 條件載入
if (condition === 1) { import('./xxx.js').then(module => { console.log(module.default); }); } else if (condition === 2) { import('./xxx.js').then(({ name, age }) => { console.log(name, age); }); } else { import('./xxx.js').then(({ name: customName, age }) => { console.log(customName, age); }); }