---
# System prepended metadata

title: Module 模組
tags: [Javascript]

---

# Module 模組
###### tags: `Javascript`
由於Javascript沒有命名空間，所以並沒有私有、公開等特性，以模組化方式管理可以有效的避免全域汙染且更加方便管理。
:::danger
警告：
1. module會強制啟用[**嚴格模式**](https://hackmd.io/@PMtxKnTSRCSR16zy1H2XpA/SJqsHXDko)。
2. import時須將script標籤的type設定為module
3. 同一檔案內允許存在多個export及一個export default
:::
## Why
以下列舉傳統引入script的方式相較於模組化的缺點。
1. 易產生全域宣告衝突(汙染)
```javascript
    <script src="a.js"><script>          // 包含全域變數x=1
    <script src="b.js"><script>          // 包含全域變數x=2
    <script>
        
        console.log( x );                // error

    </script>
```
2. 僅允許依照引入順序讀取
```javascript!
    // 傳統引入方式
    <script>
        
        console.log( x );                // undefined

    </script>
    <script src="a.js"><script>          // 包含變數x=1
        
    // module方式
    <script type="module">
        
        console.log( abc.x );            // 1
        import a from './a.js';

    </script>
```
3. 開發人員必須主觀解決模組和代碼庫的依賴關係
4. 於大型專案中較難管理

## How
### export
將變量轉為模組供外部取用，export分為兩種方式。
### import
可將單個或多個模組引入，import方式分為三種。
1. 個別輸出
   輸出方式：export { ... };
   輸入方式：import { ... } from ' ... ';
:::danger
警告：輸入端需依輸出端的命名取用。
:::
```javascript!
    // module.js
    let x = 1;
    export { x };

    // html
    <script type="module">
        
        // 第一種方式
        import { x } from 'module.js';
        console.log( x );                     // 1
        
        // 第二種方式
        import * as name from 'module.js';
        console.log( name.x );                // 1

    </script>
```
2. 預設輸出
   輸出方式：export default ...;
   輸入方式：import ... from ' ... ';
:::danger
警告：輸入端需自訂取用名稱。
:::
```javascript!
    // module.js
    export default{
        x: 1
    };

    // html
    <script type="module">
        
        import abc from 'module.js'; // 自訂名稱
        console.log( abc.x );        // 1

    </script>
```