React開發不可不知的JavaScript語法01:import與export

Sean Yeh
Web Design Zone
Published in
9 min readJun 8, 2023
Kölner Dom, Cologne Cathedral, Greman, photo by Sean Yeh

以下短文說明在React開發上,常常需要用到的JavaScript語法之一 — import與export。

當我們在使用React的時候,常常會在原始檔案的最前面看到下面的語法:

import React from 'react';
import ReactDOM from 'react-dom';

這兩行以import開頭的程式碼到底是什麼意思?實際上又是如何運作的呢?

有時候,你覺得將所有的變數與函式寫在一個JavaScript檔案裡面,對於有「潔癖」的你來說,實在看不順眼。你希望將相關的變數與函式集中在一個檔案中方便管理。並且在有需要的時候,將必要的函式載入另一個使用中的JavaScript檔案裡面,這時候該如何處理呢?

為了得到這個答案,我們在此要稍微深入了解一下模組(modules)的概念。

關於模組

為了開發上的方便與容易維護,我們會希望不要將程式碼都寫在同一支檔案中,以至於檔案中程式碼的行數非常的冗長。

不過,我們可以透過模組解決這個問題。

在程式設計中,模組是一個軟體或程式的一部分,包含一個或多個程式碼區塊。

如果以一本書來比喻,模組就會像書中的章節一般。每一章都具備獨特的內容,而它也為一本書的整體故事產生貢獻。同樣的道理,每個模組都它有特定的功能,所有的模組加起來,共同組成整個程式的功能。

採用模組化編寫程式的一個關鍵觀念是程式碼的可重複使用。程式設計師可以將常用的程式碼打包成一個模組,在需要的時候,將打包好的程式碼添加到現在的程式裏面,而不是一再地重複撰寫同樣的程式碼。這樣子做,可以使程式碼更易於被理解與使用。

透過模組系統,開發者就可以根據實際上的需要,適時的讓程式碼被重複使用。

JavaScript裡面有兩種

目前JavaScript有兩種模組系統,一套用於前端,另一套用於後端。前者稱作為ES modules (全名為ECMAScript modules),後者則是CommonJS。

我們都知道,早期JavaScript的發明是用來解決前端問題的「膠水語言」(glue language)。當初,主要是作為「接著劑」用於網站前端網頁上面的視覺效果。因此,原本就只能在瀏覽器環境中使用,沒有辦法離開瀏覽器獨立運行。

然而當Node.js的出現後,JavaScript也可以被用寫伺服器端(後端)的程式。透過Google Chrome提供的V8引擎,我們只需要在電腦上安裝Node.js後,就可以讓JavaScript離開瀏覽器,獨立運行於電腦上。如果各位對JavaScript的歷史有興趣,可以參考下面的文章話說從前 — JavaScript的過去與現在

React屬於前端框架,換句話說它會在網頁瀏覽器上執行,對照上面的說明,它使用的是ES modules 模組,也就是一般常說的ES6(ECMAScript)模組。為了得到前述問題的答案,我們在此要稍微深入了解一下ES6中的模組的概念。

JavaScript 模組的匯入與匯出

在 JavaScript 中,從 ES6(ECMAScript 2015)開始,你可以使用由 importexport 定義的 JavaScript 模組。當你想要把程式碼片段匯出只需要透過 export 關鍵字實現。反之,若要將一隻檔案匯入時,則使用 import 作為關鍵字。以下分別針對匯入與匯出功能進行說明。

依照順序,我們先來看檔案的匯出方式,再看它們如何被匯入。前面提到,「想要把程式碼片段匯出只需要透過 export 關鍵字來實現」。然而事情並沒有如此單純。實際上,匯出又可以分為下面兩種方式:

name export 實名匯出

又稱為具名匯出,我們可以直接定義好變數,然後匯出該變數。以下透過一個範例來說明。

假設我們有一個名稱為 math.js的模組:

// math.js 直接定義好變數並匯出
export const pi = 3.14159;

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

export function subtract(a, b) {
return a - b;
}

我們可以使用上面的方式匯出變數。在宣告變數( const pi = 3.14159 )的同時,匯出( export const pi = 3.14159; )該變數。

同理,在宣告一個函式( function add(a, b) { } )的時候,也可以同時匯出( export function add(a, b) { } )該函式。

另外,我們也可以先把變數都定義好之後,在檔案最後的地方,將我們想要匯出的變數以 export{} 的方式匯出。

同樣的,我們以上面的假設 math.js模組來說明:

// math.js 先把變數都定義好,再匯出
const pi = 3.14159;

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

function subtract(a, b) {
return a - b;
}

export {pi,add,subtract};

也可以透過 as 將原本匯出的變數改為比較簡單的別名:

// math.js 改為別名,再匯出
//...

function subtract(a, b) {
return a - b;
}

export {subtract as subT};

實名匯出的匯入(import)方式

對於前面的例子,也就是名稱為 math.js的模組,我們可以透過下面的方式匯入檔案。

假設你有一個app.js檔案,需要用到math.js模組中的變數,你可以使用下面的語法匯入:

// 在app.js中匯入
import { pi, add, subtract } from './math.js';

app.js 中,我們使用 import 關鍵字從 math.js 匯入 piaddsubtract。匯入後,就可以像在 app.js 檔案本身定義的一樣使用它們。

// 在app.js中匯入
import { pi, add, subtract } from './math.js';

// 使用
console.log(pi); // 輸出:3.14159
console.log(add(5, 10)); // 輸出:15
console.log(subtract(20, 7)); // 輸出:13

從上面的例子可以看到,當我們要匯出變數時,不只需要確實知道變數的名稱,並且一個個的指名改變數來匯出,當匯入檔案時也一樣,變數名稱必須與匯出的名稱相應,如果錯了就無法找到對應的變數。

實際上,這樣子的方式雖然不是完全沒有其優點(只匯出需要的變數,其他的不會載入),但是在平常的狀況下,似乎是比較麻煩的。因此,我們可以來看看另外一種匯出方式:export default

default export 預設匯出

這種匯出的方式稱為預設匯出,export default 是它的語法。它允許我們將一個模組的主要功能或物件作為預設的匯出,使其可以在其他文件中使用。

再以 math.js 檔案為例,我們可以使用 export default 導出這個模組的功能。下面是如何使用 export default

const pi = 3.14159;

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

function subtract(a, b) {
return a - b;
}

export default {
pi,
add,
subtract
};

在這個例子中,我們將 math.js 檔案裡的常數 pi,以及函式 addsubtract 封裝在一個物件中,並使用 export default 匯出這個物件。這表示在其他檔案中引入 math.js 時,預設匯出的物件將可用於存取 piaddsubtract

預設匯出的匯入(import)方式

承上面的例子,假設我們有一個主要的檔案 main.js ,這個檔案想要使用 math.js 中的函式和常數,我們可以透過下面的語法匯入:

// 在main.js中匯入
import math from './math.js';

main.js 中,我們使用 import 關鍵字來匯入 math.js 檔案,並將匯出的物件存放在名為 math 的變數中。

然後,我們就可以透過 math 物件存取 piaddsubtract

// 在main.js中匯入
import math from './math.js';

j// 使用
console.log(math.pi); // 3.14159
console.log(math.add(2, 3)); // 5
console.log(math.subtract(5, 2)); // 3

與前面不同的是,當我們將 math.js 檔案裡的常數 pi,以及函式 addsubtract 封裝在一起並透過 math 物件存取後,在使用時就需要先提及 math 物件,再取用裡面的變數與函式。

// 使用
console.log(math.pi);
// 非使用
console.log(pi);

易言之,export default 讓我們可以方便地匯出模組的主要功能或物件,並在其他檔案中使用這些匯出的功能或物件。

不過,值得我們注意的是,一支檔案最多只會有一個 export default。雖然在理論上實名匯出和預設匯出可以同時使用在同一支檔案中。在實務上不建議如此使用。

結論

匯入和匯出概念讓前端開發更模組化,將大型檔案拆分成易管理的模組。這個概念則被React廣泛使用。匯入React模組,就可以讓我們使用其功能。

此外,模組化能提升程式碼的組織性、有利於工程團隊間的合作,並提升應用程式的效能。這種開發方式不僅改善可維護性,也適用於其他前端框架,為程式碼提供更好組織和可維護性。

--

--

Sean Yeh
Web Design Zone

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。