# JavaScript ES6 Modules
### Question
How can you share code between files?
### Answer
.... (略)
**ES2015 defines a module syntax which aims to replace both AMD and CommonJS.** This will eventually be supported in both browser and Node environments
:arrow_right: [Modular Programming (AMD v.s CommonJS v.s ES6)
](https://hackmd.io/iU7tBt_RTzqINZWojIWh4g?view)
<img src="https://i.imgur.com/fSTr1At.png" width="600px">
<br >
### 使用 Module 的好處
<img src="https://i.imgur.com/za1Bzuu.png" width="300px">
<img src="https://i.imgur.com/0vOEI49.png" width="300px">
- **Compose software**
Modules are small building blocks that we put together to build complex applications;
- **Isolate components**
Modules can be developed in isolation without thinking about the entire codebase;
- **Abstract code**
Implement low-level code in modules and import these abstractions into other modules;
- **Organized code**
Modules naturally lead to a more organized codebase;
- **Reuse code**
Modules allow us to easily reuse the same code, even across multiple projects.
<br >
### JS ES6 Modules `import`, `export` 瀏覽器相容性 (2021)
<img src="https://i.imgur.com/WpbOYjb.png" width="700px">
IE 已淘汰,可以開始擁抱 ES6 Module 了!
<br >
***
## ES6 Modules Overview
### Modern JavaScript Development

### ES6 Modules 與 傳統 Script 比較
| | ES6 Modules | Script |
| -------- | -------- | -------- |
| Top-level variables| Scoped to module| Global|
|Default mode|Strict mode|X|
|Top-level **`this`**|`undefined`|window|
|HTML linking|`<script type="module">`|`<script>`|
|File downloading|Asynchronous|Synchronous|
<br>
### ES6 Modules 實際上是如何運作的?

### 如何使用: `import`, `export`, `type="module"`

`index.html`
```htmlembedded
<script defer type="module" src="script.js">
```
`script.js`
```javascript
import "./shoppingCart.js"
console.log("Importing Module")
```
`shoppingCart.js`
```javascript
console.log("Exporting Module")
```
<br >
in the console
```
Exporting Module
Importing Module
```
由 console 結果可知,是先執行被 import 的 module(ex: `shoppingCart.js` ),再執行 import 這個 module 的檔案(ex: `script.js` )
<br>
#### 補充:script 載入方式:`defer`, `async`

***
## export 的方法與 syntax
- Name export
- Default export
### Name export / import
`shoppingCart.js`
```javascript=
const cart = [];
export const addToCart = function(product, quantity){
cart.push({product,quatity});
console.log(`${quantity} ${product} added to cart`);
};
const totalPrice = 237;
const totalQuantity = 23;
export {totalPrice, totalQuantity as quantity};
```
`script.js`
```javascript=
import { addToCart, totalPrice as price, quantity } from "./shoppingCart.js";
addToCart('bread', 5);
console.log(price, totalQuantity);
```
or
`script.js`
```javascript=
import * as ShoppingCart from "./shoppingCart.js";
ShoppingCart.addToCart('bread', 5);
console.log(ShoppingCart.totalPrice, ShoppingCart.totalQuantity);
```
`* as ___` creates an object containing all modules from specified file
<br>
### Default export / import
> 當我們在一個 module 只想要 export 一個項目( variable 或 function )
`shoppingCart.js`
```javascript=
const cart = [];
const totalPrice = 237;
const totalQuantity = 23;
export default function(product, quantity){
cart.push({product,quatity});
console.log(`${quantity} ${product} added to cart`);
};
```
`script.js`
```javascript=
import add from "./shoppingCart.js";
add('bread', 5);
```
對於 default export 的 import,我們可以任意命名
:::warning
Best Practice: 對於同一個 module,不應該混用 name export 和 default export
:::
<br >
#### Concept: “Live connection” between import & export (not a copy!)
`shoppingCart.js`
```javascript=
export const cart = [];
export function addToCart(product, quantity){
cart.push({product,quatity});
console.log(`${quantity} ${product} added to cart`);
};
```
`script.js`
```javascript=
import { addToCart, cart } from "./shoppingCart.js";
addToCart('pizza', 2);
addToCart('bread', 5);
addToCart('apple', 4);
console.log(cart);
// (3)[{...},{...},{...}]
```
由 console 的結果可知,import/export 為 live connection 而非 copy 被import 的 variable 的值 (如果是 copy 的話,此處應該會 log 出 `shoppingCart.js` 第一行的空陣列)
***
## Webpack 與 Babel
### 兩者角色區別
<img src="https://i.imgur.com/gU5Lzkv.png" width=" 500px">
***
### Babel
在整個 ES6 Module 中扮演的角色
<img src="https://i.imgur.com/F7m8coU.png" width=" 600px">
#### What is Babel
> 官方解釋:
> Babel is a toolchain that is mainly used to **convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.**
[ES6 新增了什麼
](https://hackmd.io/6Lruihd-Qmeu9iHoipwuvQ#%E8%A3%9C%E5%85%85%EF%BC%9A-JavaScript-ES6-%E6%96%B0%E5%A2%9E%E4%BA%86%E4%BB%80%E9%BA%BC)
#### Transpile 轉譯
例如
將 `let`, `const` 轉成`var`, 將 arrow function 轉成一般 function
<img src="https://i.imgur.com/Vc3dEzJ.png" width=" 300px">
:arrow_down: **Babel**
<img src="https://i.imgur.com/jfv1faA.png" width=" 350px">
#### Polyfill
> ES6+ 的語言特性不僅包括語法結構,還包括新的 built-in function 或是像 `Promise` 這樣的 object。
因此需要 Polyfill 去更新/添加新函数的 Script,“填補” 缺口。
***
### Webpack
<img src="https://i.imgur.com/9E0YWS6.png" width=" 500px">
### Webpack 幫我們處理了什麼?
#### Bundle 打包
> 減少 browser request JS script 的次數,改善效能與使用者體驗
<img src="https://i.imgur.com/bUmJ939.png" width="400px">
:arrow_down:
<img src="https://i.imgur.com/VphN5SZ.png" width="400px">
#### Dependencies
> 協調檔案彼此 dependency 的關係
<img src="https://i.imgur.com/0vOEI49.png" width="400px">
<img src="https://i.imgur.com/6FYrInA.png" width="200px">
### Webpack 怎麼做的
<img src="https://i.imgur.com/egyhHwl.png" width=" 400px">
<img src="https://i.imgur.com/qqvGeED.png" width=" 200px">
Webpack Config ~~(此為原理示意,非目前 Webpack5 可行的配置設定方式)~~
<br >
#### `npm run build` 的結果
<br >
<img src="https://i.imgur.com/a3ReIt2.png" width=" 150px">
<img src="https://i.imgur.com/sIgGweI.png" width=" 450px">
產生一個 bundle file (ex: `bundle.js` )
~~此為示意結果,與目前 Webpack5 結果不同)~~
<img src="https://i.imgur.com/ykjWPN3.png" width=" 500px">
entry 的 html 檔加載的 script 會被配置成 bundle file 的名稱
~~(此為示意結果,與目前 Webpack5 結果不同)~~
<br >
### Webpack 怎麼產生一個 bundle file 處理 dependency 的問題
<img src="https://i.imgur.com/GUiIqG4.png" width="400px">
webpack 協調檔案後做出的 `bundle.js` 的 **pseudo code**
## 參考資料
- Udemy - The Complete JavaScript Course 2021: From Zero to Expert! ( Jonas Schmedtmann) Section 17
- Udemy - Webpack 2: The Complete Developer's Guide ( Stephen Grider) Section 2, 3