--- tags: web develop --- # 模組的匯出與匯入 [TOC] ## What - 模組是一種的功能封裝機制,可以優化專案的設計、可維護性、測試更輕鬆 - 模組以文件承載,模組內所有變數,外部無法訪問,需要匯出才可供外部使用 - 模組化,允許匯出與匯入模組 - 可以便於使用別人以npm開發的豐富模組生態系統 ### CommonJS規範 - 是Ndoe.js的模組化規範 - 瀏覽器無法直接使用Common.js規範,需要依賴打包工具進行支持,如 Webpack ### ES Module規範 - ES Module ( ES6 Module / ECMAScript Module/ JavaScript Module) - ES6 的新語法 - JS的官方包裝機制,JS的正式規範,可以直接在瀏覽器執行 - React屬於前端框架,使用ES Module - Node.js也支援 ### JS的模組化發展過程: - 無模組 ⇒ CJS ⇒ 社區實現 AMD、CMD、UND ⇒ ESM - 社區實現了諸多規範:AMD、CMD、UND - AMD:與CommonJS規範,主要區別是異步加載模組 - CMD:與AMD規範類似,主要區別是依賴後置,模組加載完後再執行(?) - UND:AMD規範與CommonJS規範的結合 在導入模組庫後,都能在瀏覽器直接執行,最終被整合成了ESM ## Why - 隨著js的複雜度與能力提升,程式維護成本相應提高,產生兩個問題: - 命名空間衝突:所有腳本都暴露在全域作用域下,有命名衝突的風險,如,jquery和zepto都使用window.$ - 依賴關係不清晰:對於腳本的依賴、版本、加載順序,無法合理管理 - 用模組匯入匯出,才能拆分成不同檔案,職責分離 ## Which - 前後端模組系統,語法不同 ### 前端模組系統:ES Module (ESM) - 如前端框架 react.js - [補充:ESM 在 React 中的使用建議](#補充:ESM-在-React-中的使用建議) ### 後端模組系統:CommonJS (CJS) #### When(CJS) - Node.js - 原先不能使用 ESM,可用 CJS - Node.js 12版本後(2019-04-23發佈),支援 ESM - Node.js 13版本後,可以更容易的使用 ESM 語法 使得 Node.js可以直接使用ESM,而不需要透過babel等編譯器 #### How(CJS) Node >= v13,可選擇下面兩種其一: - 將 ES modules 檔案的副檔名存為 .mjs - 在 package.json 檔案中,加入 `{ “type”: “module” }` 參考:https://eddychang.me/node-es6-module ## How ### CJS ```javascript // 後端 CommonJS => ES5 // 匯入 const products = require('./data/products') // 匯出 exports products module.exports = products ``` ### ESM ```javascript // 預設 匯出/匯入 export default products; import products from "../products"; // 實名 匯出/匯入 export products; import { products } from "../products"; ``` - 實名匯出,匯入匯出的變數名稱必須一致 #### 實名匯出:直接定義變數並匯出 ```javascript // 匯出 // in demoA.js export const fruit1 = "apple"; export const fruit2 = "banana"; // 匯入 // in demoB.js import { fruit1, fruit2, } from "./demoA"; console.log(fruit1); // apple ``` #### 實名匯出:先定義好變數再匯出 - 匯出匯入時,都可以透過as修改名稱 - export後面接的不是物件 ```javascript // // 匯出 // in demoA.js const fruit1 = "apple"; const fruit2 = "banana"; export { fruit1, fruit2 as fruit222, } // 匯入 // in demoB.js import { fruit1 as fruit111, fruit222, } from "./demoA"; console.log(fruit111); // apple ``` ### ESM 預設匯出 - 可以直接匯出,不用管匯出變數有哪些 - 匯入時可以隨意取名 - 一隻檔案只能有一個export default ```javascript // 匯出 // in demoA.js export default ["apple, "banana", "cherry"]; // 匯入 // in demoB.js import products from "./demoA" ``` ### 補充:ESM 在 React 中的使用建議 React 開發時,檔名、元件名稱、匯出名稱都要一致 ```javascript function App(){ return( <></> ) } export default App; ``` 有些開發者為求程式簡潔,會寫成 export function App() { },即直接定義並匯出 ```javascript export function App(){ return( <></> ) } ``` 箭頭函式,就無法前面直接接 export ```javascript const App = () => { return( <></> ) } export default App; ```