---
# System prepended metadata

title: JS ESModule
tags: [Javascript]

---

---
tags: Javascript
---

# JS ESModule

要在原生瀏覽器運行`ESModule`需要在`script tag` 加上`type="module"`，才能使用`ESModule`

```html=
<script type="module">

// code...

</script>
```

## 匯出

### 預設匯出

每個檔案唯一，在`vue`開發中可用來匯出元件

在資料夾根目錄創建預設匯出範例程式`export1.js`

```javascript=
export default{
    name: "joe",
    about() {
        console.log(`我的名子叫${this.name}`);
    }
}
```

### 具名匯出

可以匯出多個，在第三方框架，套件，函式經常看到

根目錄創建`export2.js`

```javascript=
export const num = 10;

export function print() {
  console.log(1);
}

export function add(a, b) {
  return a + b;
}
```


## 匯入

### 預設匯入

預設匯出沒有名子，所以可以自己加上，為他取名`export1`，可以在`console`看到輸出結果

```html=
<script type="module">
  import export1 from "./export1.js";
  export1.about();
</script>
```

### 具名匯入

#### 單一匯入

建議此寫法

```html=
<script type="module">
  import { num, print } from "./export2.js";
  console.log(num);
  print();
</script>
```

#### 全部匯入

全部匯出可能造成名稱衝突，所以要用as賦予名子

不建議此寫法，錯誤較難發現

```html=
<script type="module">
  import * as export2 from "./export2.js";
  console.log(export2.num);
  export2.print();
</script>
```

## SideEffect

`side effect`又稱副作用，因其效果不是可以預測的，因為他裡面內容可能會覆蓋你所寫的現有內容，這就是副作用，因此裡面的內容需要審慎評估，以免影響到現有內容。

`side effect`並無進行匯出，但匯入後會立即執行，在很多舊套件是採用此種方式

新建`SideEffect.js`並匯入

```javascript=
(function (global) {
  global.$ = "JQuery";
})(window);
```

可以看到他輸出`JQuery`
```html=
<script type="module">
  import "./SideEffect.js";
  console.log($);
</script>
```

## 後記

### 每一個`type="module"`都是獨立的作用域

舉範例來說，可以看到下面的`script`程式碼是讀取不到`window.a`的

```html=
<script type="module">
  var num = 1;
  window.a = 2;
</script>
<script>
  console.log(a); // Uncaught ReferenceError: a is not defined
</script>
```
    window.a的變數的
但是在這個範例中，把`script tag` 加上 `type="module"`，是讀取的到`window.a`的變數的，不過在實戰中這種例子很少見，所以還是把它想成`type="module"`都是獨立的作用域

```html=
<script type="module">
  var num = 1;
  window.a = 2;
</script>
<script type="module">
  console.log(num); // Uncaught ReferenceError: num is not defined
  console.log(a); // 2
</script>
```

### 匯入 ESM套件

舉`Vue`為例，我們就沒有把整個`Vue`匯入只會入`createApp`，可以看到匯入的 `CDN` 有 `esm-browser`，就是可以給 browser 使用的`ESModule`

```html=
<div id="app">
  <button @click="count++">Count is: {{ count }}</button>
</div>
<script type="module">
  import { createApp } from "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.31/vue.esm-browser.js";

  createApp({
    data() {
      return {
        count: 0,
      };
    },
  }).mount("#app");
</script>
```
