相信大家應該都有這樣的經驗,當同一隻JS裡程式碼越寫越多,維護起來是一件很頭痛的事。如果將一隻JS拆分多個檔案出來,雖然是拆開了,但相互調用變數只能透過全域變數來使用,但這樣可能也會造成全域污染的問題,所以也不是很好的作法,所幸後來ES6出現了export / import,讓Javascript也可以使用原生方式來使用模組化。
首先我們先去看看MDN官方文件:
用 export 可以指派函式、物件或變數,透過 import 宣告給外部檔案引用。
導出的模塊都會處於嚴謹模式,無論是否有所宣告。導出宣告無法使用嵌入式腳本(embedded script)。
因為是宣告式,當要使用時需要先宣告,以下是export的兩種使用方式:
一個js檔案可以有多行命名匯出,將export用於宣告前,用法如下:
//匯出值
export let myString = "hello";
//匯出物件
export const myObject = { name: "river" };
//匯出函式
export function myFunction() {
console.log("myFunction");
}
//匯出類別
export class myClass {
constructor(name, gender) {
this.name = name;
this.gender = gender;
}
}
也可以先全部宣告最後再統一匯出:
//宣告
let a = 1;
let b = { num: 2 };
//匯出
export { a, b };
跟命名匯出用法差不多,差別在一個js檔案只能有一行預設匯出:
//匯出函式
export default function myFunction () {
console.log('myFunction')
}
也可以這樣
//匯出函式(arrow function)
const myFunction = () => {
console.log('myFunction')
}
export default myFunction
不過要注意的是,命名匯出在匯出後的引入要使用完全相同的名稱才能使用,預設匯出可以在引入時給予新名稱使用。
這邊一樣看看MDN官方文件:
import 宣告用於引入由另一個模塊所導出的綁定。被引入的模塊,無論是否宣告strict mode,都會處於該模式。import 宣告無法用於嵌入式腳本(embedded scripts)。
我們直接來看怎麼用,首先是Named exports(命名匯出)的引入:
//引入單個或多個
import { name1 } from "./export.js";
import { name1, name2 } from "./export.js";
//使用
name1();
name2();
//引入所有(需指定名稱)
import * as name from "./export.js";
//使用
name.name1();
//引入後重新命名
import { name1 as func1, name2 as func2 } from "./export.js";
//使用
func1();
func2();
接著是Default export(預設匯出)的引入:
//引入預設匯出
import myFunction from "/export.js";
//使用
myFunction();
除此之外,以上兩種也可以同時引入:
//同時引入預設及命名匯出
import myFunction, { name1, name2 } from "/export.js";
若想要單純執行某支檔案程式,則不用帶任何名稱引入即可
import "/export.js";
看完以上的說明後,這邊準備一個簡單的範例來做示範,我們建立要匯出的模組,取名myModule.js。
//named export
export const name = { first: "river", last: "huang" };
//named export
const age = 30;
const city = "Taipei";
export { age, city };
//default export
export default function hello() {
return "Hello";
}
再來建立index.js,作為引入myModule.js用
import hello, { name, age as myAge, city } from "./myModule.js";
const wrapper = document.querySelector("#wrapper");
wrapper.innerHTML = `
${hello()}!
I am ${name.first} ${name.last}.
I am ${myAge} years old.
Located in ${city}.
`;
建立HTML並嵌入index.js(HTML要直接使用模組化在script的type屬性要為module)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DAY 12 | export / import</title>
</head>
<body>
<div id="wrapper"></div>
<script type="module" src="./index.js"></script>
</body>
</html>
最終成果:
以上是關於Javascript模組匯出與引入的基礎介紹,有興趣可以至下方參考資料處進行閱讀。這部份在SPA開發中會大量使用到,只要掌握「先匯出,再引入」,也能夠輕鬆使用模組化的程式。除了能提高程式維護性,也能提昇模組與元件的管理效率。以上內容到這邊,我們明天見!
參考資料: