JavaScript 程式庫和架構之間的差異

烏瑪爾 (Umar Hansa)
Umar Hansa

本文將說明在用戶端 JavaScript 環境 (也就是網路瀏覽器中運作的程式碼) 環境中,架構和程式庫之間的差異。不過,本文提及的部分要點也適用於其他環境,因為程式庫和架構屬於許多軟體工程領域的一部分,例如原生行動應用程式開發。

本文的討論著重於定性差異,而非程式庫和架構之間的量化差異。例如:

  • 定量:架構通常遵循控制反轉原則。
  • 定性:在您尋找工作時,這套架構能吸引未來的雇主。

為何要瞭解程式庫和架構?

JavaScript 程式庫和架構在網路上的使用率很高。其他網站似乎在 JavaScript 資源中使用部分第三方程式碼。隨著網頁時間累積,網頁量愈來愈低,就會影響使用者JavaScript 是影響網頁整體量的主要因素,也是相同的 JavaScript,通常包含第三方程式庫和架構。

光是「停止使用 JavaScript 架構」並不足夠,因為架構可為開發人員帶來莫大好處。架構可協助您有效率地編寫程式碼、快速提供功能,並帶來其他好處。相反地,您應該要瞭解自己,以便在發生變化時能做出明智的決定。

「我現在應該使用程式庫還是架構?」這個不常見的問題是值得思考的。程式庫和架構是兩種截然不同的東西。然而,程式庫和架構往往較為混亂,您對這兩項工具的瞭解越多,就越有可能做出明智的決策。

程式庫和架構範例

您可能會發現第三方的程式碼有其它名稱,例如小工具、外掛程式、polyfills 或套件。但通常屬於程式庫或架構類別。基本上,兩者之間的差異可總結如下:

媒體庫

程式庫通常會比架構更簡單,功能也十分有限。如果將輸入內容傳送至方法並接收輸出內容,就表示您可能使用了程式庫。

請查看以下 lodash 程式庫範例:

import lodash from 'lodash'; // [1]
const result = lodash.capitalize('hello'); // [2]
console.log(result); // Hello

如同許多程式庫,詳閱程式碼並瞭解其用途是實際的。但這只是一些魔法

  1. import 陳述式可將 lodash 程式庫匯入 JavaScript 程式。
  2. 叫用 capitalize() 方法。
  3. 單一引數會傳送至方法。
  4. 系統會透過變數擷取傳回值。

架構

架構往往比程式庫大,而且對整體頁面權重的貢獻也比較高。事實上,架構可包含程式庫。

下方是沒有程式庫的純架構,並使用 Vue (熱門的 JavaScript 架構):

<!-- index.html -->
<div id="main">
  {{ message }}
</div>

<script type="module">
import Vue from './node_modules/vue/dist/vue.esm.browser.js';

new Vue({
  el: '#main',
  data: {
    message: 'Hello, world'
  }
});
</script>

如果您比較此架構範例與先前的程式庫範例,可能會發現以下差異:

  • 架構程式碼包含多種技術,並抽離了其專屬的 API。
  • 開發人員並沒有完全掌控作業執行的方式和時間。舉例來說,Vue 能在網頁中加入 'Hello, world' 字串的方式和時機,您就不必再處理這些內容。
  • Vue 類別的執行個體會產生一些「副作用」,這是在您使用架構時常見的副作用,程式庫也可能提供「純函式」
  • 這個架構指定了特定 HTML 範本系統,而非使用自己的 HTML 範本系統。
  • 如果您進一步閱讀 Vue 架構說明文件或大部分的其他架構文件,則可看到這些架構概述您可以使用哪些架構模式。JavaScript 架構在操作上不需費心,因此在操作上不太費力。

使用程式庫和架構的時機

閱讀完程式庫和架構的比較資料後,可能會開始瞭解這兩種架構的使用時機:

  • 架構可降低您 (開發人員) 的複雜度。如先前所述,架構可以去除邏輯、行為,甚至是架構模式。特別是當您開始進行新專案時。程式庫可以協助提高複雜性,但通常著重在可重複使用的程式碼。
  • 架構作者希望提高工作效率,因此經常開發額外的工具、偵錯軟體和全方位指南等,可協助您有效運用架構。圖書館作者也希望提高工作效率,但程式庫中的特殊工具並不常見,
  • 大多數架構都提供了功能的起點 (例如骨架或樣板),協助您快速建構網頁應用程式。程式庫會成為您現有程式碼集的一部分。
  • 一般來說,架構會對程式碼集增加一些複雜性。從一開始,事情的複雜性未必顯而易見,但可能會在一段時間後顯現。

提醒您,一般而言,您通常不會比較程式庫與架構,因為程式庫指的是執行不同任務的不同元素。但是,您對這兩種技術的瞭解越深入,就越能掌握自身需求,選出最適合自己的選項。至於要使用架構或程式庫,最終取決於您的需求。

切換性

您不會每週變更程式庫或架構。不過,瞭解套件卻是藏身其中一塊的缺點,便是最好的方式。也建議您瞭解,決定使用第三方套件的開發人員有點負責在套件與應用程式原始碼之間建立鬆耦合。

與原始碼綁定的套件較難移除及替換其他套件。在下列情況下,你可能需要更換套件:

  • 您必須更新已不再維護的套件。
  • 您發現套件太錯誤,無法使用。
  • 讓您瞭解更符合需求的全新套件。
  • 產品相關規定會有所變動,因此不再需要套件。

請參閱以下範例:

// header.js file
import color from '@package/set-color';
color('header', 'dark');

// article.js file
import color from '@package/set-color';
color('.article-post', 'dark');

// footer.js file
import color from '@package/set-color';
color('.footer-container', 'dark');

先前的範例在三個不同檔案中使用第三方 @package/set-color 套件。如果您使用這個程式碼,且需要替換第三方套件,就必須在三個位置更新程式碼。

此外,您也可以簡化維護流程,並將程式庫的使用情形提取至同一處,如以下範例所示:

// lib/set-color.js file
import color from '@package/set-color';

export default function color(element, theme = 'dark') {
  color(element, theme);
}

// header.js file
import color from './lib/set-color.js';
color('header');

// article.js file
import color from './lib/set-color.js';
color('.article-post');

// footer.js file
import color from './lib/set-color.js';
color('.footer-container');

在上一個範例中,我們移除了直接程式庫的使用方式。因此,如果你必須替換第三方套件,只需更新一個檔案。此外,由於內部 set-color.js 檔案會設定要使用的預設色彩主題,因此程式碼現在更容易使用。

使用方便

架構的 API 可能較複雜,但架構可能會提供開發人員工具,方便您整體使用。易用性取決於許多因素,而且相當主觀。架構可能會難以使用,原因如下:

  • 這個架構的 API 本身就相當複雜。
  • 這個架構的記錄不完善,需要經過多次測試和錯誤才能解決問題。
  • 這個架構使用的技術對您和您的團隊不熟悉。

架構可以減輕這些難題,包括:

  • 這個架構提供開發人員與診斷工具,有助於簡化偵錯作業。
  • 這個架構是一個活躍的開發人員社群,有許多成員可以合作製作免費文件、指南、教學課程和影片。閱讀完這些內容後,即可透過這個架構提高效率。
  • 這個架構提供的 API 符合常見程式設計慣例。您先前瞭解過這類慣例,也更熟悉程式設計方式,因此可以有效運用這個架構。

這些要點通常歸因於架構,不過也可以歸因於程式庫。舉例來說,D3.js JavaScript 程式庫不僅功能強大,而且擁有龐大的生態系統,提供研討會、指南、說明文件和其他資源,這些都影響了易於使用的便利性。

此外,架構一般會指定網頁應用程式的架構,程式庫則通常與現有架構相容,無論架構為何。

效能

一般來說,架構對效能的影響可能會比程式庫大,不過這種情況下可能會有例外狀況。網頁效能是相當龐大的領域,涵蓋許多主題,因此以下章節將說明兩部分的重點:樹晃和軟體更新。

搖樹

套裝組合只是網頁效能中的一個面向,但同時具有很大的效能,尤其對大型程式庫而言更是如此。在匯入和匯出期間使用樹晃可以提高效能,因為系統會找出並修剪應用程式不必要的程式碼。

套件 JavaScript 程式碼封裝時,有個實用步驟「樹狀圖」這項實用步驟,是您可以對程式碼做出有價值的最佳化,不過要用程式庫比架構更為容易。

將第三方程式碼匯入原始碼時,您通常會將程式碼封裝至一或多個輸出檔案。舉例來說,header.jsfooter.jssidebar.js 檔案都會合併為 output.js 檔案,也就是您在網頁應用程式中載入的輸出檔案。

如要進一步瞭解樹狀示意圖,請參考以下程式碼範例:

// library.js file
export function add(a, b) {
  return a + b;
}

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

// main.js file
import {add} from './library.js';

console.log(add(7, 10));

為進行示範,相較於實際看到的實際內容,library.js 程式碼範例的規模較小,因此程式庫長度可能多達數千行。

精簡套件程序可能會匯出以下輸出內容:

// output.js file
function add(a, b) {
  return a + b;
}

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

console.log(add(7, 10));

即使這個應用程式不需要 subtract() 函式,它仍會納入最終套件中。不必要的程式碼會增加下載大小、剖析和編譯時間,以及使用者必須支付的執行費用。基本的樹狀晃動方法可以移除無效程式碼,並產生以下輸出內容:

// output.js file
function add(a, b) {
  return a + b;
}

console.log(add(7, 10));

請注意,程式碼的長度較短且簡潔扼要。在本例中,效能的提升幅度微乎其微,但在實際應用程式中,程式庫包含數以千計的行程式碼,其效能效果可能更加顯著。更有趣的先進軟體包工具 (例如 Parcel、Webpack 和 Rollup ) 則更進一步,因為這些工具結合了壓縮和樹狀圖作用,建立高度最佳化的套裝組合。為了展現套件工具的成效,我們使用 Parcel 來建立包含先前的程式碼範例的套件檔案。Parcel 移除所有未使用的程式碼,並匯出了這個單一模組:

console.log(7+10);

Parcel 非常聰明,可移除匯入陳述式、函式定義和行為等內容,建立高度最佳化的程式碼。

套裝組合只是網頁效能中的一個面向,但同時具有很大的效能,尤其對大型程式庫而言更是如此。對程式庫而言,樹狀結構搖動通常比架構更簡單。

軟體更新

對許多程式庫和架構來說,軟體更新新增了功能、修正錯誤,最終則會隨著時間擴大規模。下載更新不一定需要下載,但如果更新包含錯誤修正、所需功能強化或安全性修正,那麼您或許就能更新。不過,您傳輸的資料越多,應用程式的效能就會越差,對使用者體驗的影響也就越大。

如果程式庫擴增,您可以使用搖樹來減少成長。此外,您也可以改用 JavaScript 程式庫的小型替代方案。詳情請參閱「可切換性」。

如果架構變大,不僅是種樹木,必須耗費更多心力,更難換掉一個架構。詳情請參閱「可切換性」。

就業機會

這聽起來不太公開透明,許多公司開發人員必須採用特定架構,才能負起他們的嚴格要求。他們可能會忽略您對網頁基礎知識的知識,並僅專注於您對特定 JavaScript 架構的瞭解!無論如何,這是許多工作必須面對的現實。

瞭解幾個 JavaScript 程式庫並不會對工作應用程式造成傷害,但無法保證應用程式一定能脫穎而出。如果您很瞭解幾個常見的 JavaScript 架構,那麼在網頁程式開發人員目前的就業市場中,可能就表示雇主認為這項知識相當受歡迎。有些大型企業組織經常無法使用非常舊的 JavaScript 架構,甚至可能想請那些熟悉此類架構的候選人。

您可以使用這個公開密鑰來獲得優勢。不過,推展工作市場時,請務必小心謹慎,並考量以下幾點:

  • 請記住,如果您在職業上花費大量時間只採用一種架構,可能會錯過採用其他現代化架構的學習體驗。
  • 假設某位不完全瞭解軟體開發或網頁開發基礎知識的開發人員,但他們是獲得架構的開發人員,這位開發人員未編寫有效的程式碼,您可能會覺得處理這類程式碼集很困難或困難。在某些情況下,這種情形會導致工作倦怠。舉例來說,您可能需要重構程式碼,或是調整程式碼效能,因為速度較慢。
  • 學習網頁開發時,最佳做法是從重心開始著手,將重心放在網頁開發、軟體開發和軟體工程等層面。如此強大的基礎可協助您快速有效地實行任何 JavaScript 架構。

結語

現在您已投注心力,瞭解 JavaScript 架構和程式庫如何比較。除非您處理綠地專案或擔任顧問,否則通常不會挑選架構或程式庫。但是,這類決策產生時,您對主題的瞭解越多,決策就越充分。

如您所知,您所建立的架構 (在某些情況下,選擇程式庫) 可能會對開發體驗和使用者 (例如效能) 產生重大影響。