iT邦幫忙

2022 iThome 鐵人賽

DAY 19
2
Modern Web

前端技能樹的十萬個為什麼系列 第 19

Day 19 - 為什麼要用 ES Module

  • 分享至 

  • xImage
  •  

前言

當程式碼愈寫愈多時,除了最基本切割邏輯到不同檔案,也要有組織與管理程式碼的一套方式,「模組化」可能是最方便的一條道路,但它幫我們處理掉哪些問題呢?

今天就以 ES Module 為主來討論!

先想一下

  • ES Module 是在什麼樣的時代誕生的?
  • ES Module 怎麼解決問題?
  • ES Module 的優缺點是什麼?
  • ES Module 適合什麼情境?

ES Module 是在什麼樣的時代誕生的?

還記得在以前沒有前端框架的時代,寫的是單純的 .html.js 檔案,要把它們組合起來變成一個網頁,總是需要用到 <script> tag,比如以前要使用 jQuery 總是需要這一行:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

那時沒想太多,只知道加了這一行之後,我就可以在任何 .js 裡面使用 $ 這個變數,它變成一個全域變數,但有個前提,就是引入 .js 的順序要對:

// 正確
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="scriptNeedJQuery.js"></script>

// 錯誤: '$' is not defined
<script src="scriptNeedJQuery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

這裡就帶出了兩個主要的問題:

  • 若 script 有依賴性,引入的順序就變得很重要,寫錯會直接掛掉
  • 全域變數很方便,但同時也會造成「變數汙染」的問題,沒辦法保證我 export 的變數不會跟別人衝突

ES Module 怎麼解決問題?

ES6 版本新加了 importexport 兩個語法,引入了「模組化」的思維,讓 JavaScript 在開發大型複雜應用程式時,更為方便且易於管理

只要在 <script> 加上 type="module" 的 attribute,就可以在 script 裡面使用 importexport 了:

// index.html
<script type="module" src="main.js"></script>

// main.js
import react from 'react';
...

Default exports & Named exports

基本的 export 分成兩種,加上 default 關鍵字可以不用特別命名(但只能有一個),否則需要命名:

// Default exports
export default 7;

// Named exports
export const monthDays = 31;
export const log = () => { console.log('Hello, world!'); };

透過上述兩種方式 export,就可以用下列方式 import,其中 default export 因為需要自行命名:

import weekDays, { monthDays, log } from './script.js'

console.log(weekDays); // 7
console.log(monthDays); // 31
log(); // Hello, world!

動態載入

另外,官網也提到關於動態載入的作法,就是使用 import() 語法

注意容易混淆:
import A from B 是靜態載入
import(B) 是動態載入

有些 script 只有特定情況才需要時,可以使用動態載入,透過管理回傳的 Promise 物件,盡可能提升 performance,避免一次性載入太多用不到的 js,造成首次白畫面過長:

btn.addEventListener('click', () => {
  import('./modules/test.js').then(result => {
    console.log(result);
  })
});

ES Module 的優缺點是什麼?

優點

  • 每個 .js 都是獨立的作用域(scope),不用擔心變數汙染
  • 每個 .js 都自行 import 自己的依賴,沒有順序相依問題

缺點

痾。。。我想不到...頂多算是相見恨晚?

畢竟在 ES module 之前,還有 CommonJS、AMD、UMD 等前輩,比較是一個各自實作的狀態,沒有統一的標準。

ES Module 適合什麼情境?

基本上 Module 已經是現在大型應用程式的標配了,甚至不用到多麼大型,隨著各種工具愈來愈先進,瀏覽器支援愈趨完整,要做到模組化已經是沒什麼成本的事情了。

結語

心智圖放大版

懷念起以前在 index.html 裡面排列組合,引用了一大堆 CDN 的 script,處處擔心會不會有相依性的問題,還自己研究 IIFE 的寫法來避免變數汙染,不知道有模組化這樣方便的工具,花了許多冤枉時間,如果能專心拿去寫程式邏輯多好啊~

參考資料

MDN Module
對 ES Module 的一點理解


上一篇
Day 18 - 為什麼要用 Babel
下一篇
Day 20 - 為什麼要用 Webpack
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言