# ES6 的module語法
###### tags: `分享`
---
之前在使用 vue-cli 時接觸到
`export default {something}`,
在寫 JS 的 17 題題目時用到
`module.exports = something`
---
| |module.exports / require|export / import|
|-|--------|---|
|實作標準|**CommonJs**|**ES6**|
|可能會聽到|**Node.js module**|**ES module(ESM)**|
|export|`module.exports = something`|`export default something`|
|import|`require("./something.js")`|`import something from "./something.js"`|
---
為什麼會分成兩種(或者更多)方式啊?
---
## 稍微考古一下
---
JavaScript 在 ES6 之前只有兩種 scope
1. 全域範圍
2. 函式範圍
並沒有模組化的概念,
所以那時候如果要把 JavaScript 做**模組化**
就只能用 **物件**、**閉包**、**立即函式** 來封裝成模組
---

---
之後出現一些實作標準
(但不是真正的 JavaScript 標準)
例如:
1. Asynchronous Module Definition (AMD)
2. **CommonJs**
來實現在寫 JavaScript 時的模組化
---
npm 裡面你所安裝的模組,
幾乎都是用 CommonJs 的 node.js module
---
CommonJs 的 module.export / require
並沒有辦法在瀏覽器上使用,
因此 webpack 打包出來的網頁程式碼都是使用 立即函式
---
所以平常在 webpack 這類的工具環境下引入模組並且打包的時候,
webpack 就會把瀏覽器看不懂的 commonjs 語法轉換成瀏覽器看的懂的語法,
用的方式大概就是把模組內的程式碼轉換成 閉包+立即函式 再安插進去
---
等到 ES6 誕生後,JavaScript 才有原生的模組語法可以使用
---
來細部看一下
---
# CommonJS 的 module.exports
---
當 webpack 在打包的時候看到 `require` 這個*標記*的時候會去執行某個函式把位置裡的程式碼做轉換並且安插
---
```
// something.js
var something = "any string"
module.export = something
==========================================
// main.js
const something = require(./something.js)
console.log(something)
```
---
# ES6 的 export / import
1. Named export (Zero or more exports per module)
3. Default export (One per module)
---
# Named export
1. ```
export const superNumberOne = 1 / export function getNumber() {}```
3. ```
const superNumberOne = 1;
function getNumber() {}
export {superNumberOne, getNumber}
// 可以用 as 取別名
// export { superNumberOne as one, getNumber}
---
# Default export
1. ```
export default 1;
5. ```
export default function() {} / export default class
3. ```
const superNumberOne = 1
export default number1
3. ```
const superNumberOne = 1
function getNumber() {}
export {superNumberOne as one, getNumber as default}
可以把 default 當作是一個特別的**簡稱**,
一個 js file 只能有**一個** default,
export default 的內容**不一定**要事先宣告
---
# import
1. ```
import anyName from "module.js" // import default
2. ```
import * as anyName from "module.js" // import every thing
3. ```
import {default as anyName, superNumberOne as one, getNumber} from "module.js"
3. ```
import anyName, {superNumberOne as one, getNumber} from "module.js"
//等同於 3.
5. ```
import "module.js"
// Import an entire module for side effects only
---
大概就是這樣~
{"metaMigratedAt":"2023-06-15T15:17:04.237Z","metaMigratedFrom":"Content","title":"ES6 的module語法","breaks":true,"contributors":"[{\"id\":\"111acc36-4797-4d6c-9b0f-ac6f5795c573\",\"add\":4077,\"del\":1470}]"}