前端框架簡介
- (en-US)
我們從整體概述來探討框架、提供 JavaScript 與框架的簡要歷史、框架存在的理由、他們提供什麼東西、如何決定選擇哪個框架、以及前端框架的的替代方案。
先決條件: 熟悉 HTML 、 CSS 、 JavaScript 這些核心技術。 理解 JavaScript 前端框架存在的理由、他們解決的問題、可用的替代方案、還有決定選擇的方法。一段簡短的歷史
在 JavaScript 誕生的 1996 年,它的作用僅僅是為當時由靜態文檔組成的網頁,提供些許的互動和興奮感。而當網路漸漸從 閱讀 的媒介,成為 做事 的場所,JavaScript 也慢慢地紅了起來。JavaScript 開發者們撰寫了許多工具,來解決自己遭遇的問題,並打包成能重複使用的工具包,稱為 函式庫 (library),以便和他人共享自己的解決方案。這個共享函式庫的生態,也推進了網路的增長。
目前 JavaScript 已經是網路的必需品了, 大約 95% 的網站都又在使用 JavaScript ,網路也成了當今生活的必須。使用者可以透過文字與影像,來寫論文、聽音樂、看電影、與人遠距離交流。曾經只能透過裝在電腦內的原生軟體所完成的事情,現在也能網路上做到。這種現代化、複雜度高、還有各種互動的網站,被稱為 網路應用程式 (web applications)。
當代 JavaScript 框架的問世,讓構建高度動態的互動式應用,變得簡單許多。 框架 是個針對軟體構建,提供完整解決方案的函式庫。這些選項能讓應用程式,開始能預測和同質化。可預測性讓軟體能擴展到巨大的規模時依舊能維護;可預測性和可維護性則對軟體的健康和長壽至關重要。
JavaScript 框架能構建常用的網站裡,許多令人印象深刻的軟體。目前你正在看的 MDN Web Docs 網站,也是用 React/ReactDOM 作為前端支援的。
那有什麼框架?
有很多框架,不過主要有以下「四大框架」。
Ember
Ember 在 2011 年 12 月發行。這個框架始於 SproutCore 的內部專案。這是個比較老的框架:與 React 或 Vue 之類的替代方案相比,其用戶數比較少,不過在穩定性、社區支持、和一些巧妙的編碼原則方面,仍然享譽無數。
Angular
Angular 是個由 Google 內部的 Angular Team 與其他社群所開發的開源專案。這個專案是同一群人由 AngularJS 所重寫的專案。該專案於 2016 年 9 月 14 日發行。
Angular 是基於組件、並使用指令式 HTML 樣板的框架。在構建時,框架的編譯器會將模板,轉換為優化的 JavaScript 程式。Angular 使用了 JavaScript 超集(superset)的 TypeScript 。我們將在下一章中詳細介紹它。
Vue
React
Facebook 於 2013 年發表了 React 。在發表當時 Facebook 內部早已使用 React 解決許多內部問題。技術上來說 React 並不是 框架,而是一個用來渲染 UI 組件的函式庫。React 通常會配合 其他 函式庫來建立應用程式:例如 React 搭配 React Native 建立手機程式、React 與 ReactDOM 建立網路程式...等等。
由於 React 與 ReactDOM 通常會搭在一起用,React 在通俗上會被理解為 JavaScript 框架。在閱讀本模塊時,我們將以這種通俗理解為基礎。
React 使用一種很像是 HTML 的 JavaScript 語法: JSX 。
為什麼有框架?
我們已經討論了啟發框架建立的環境,但那不是開發人員 為什麼 要製造它們的理由。要探索原因,首先需要首先檢查開發軟體所碰上的挑戰。
來看看一個常見的例子吧:一個能建立待辦事項程式,我們將會用待辦事項程式為例子,來介紹不同的框架。這個應用程序要能讓使用者執行諸如渲染事項列表,添加新任務和刪除任務之類的操作;還要能可靠地跟踪並更新程式所依賴的資料在軟體開發中,此這些資料稱為狀態(state)。
每個目標分開來看,理論上都很簡單:我們能遍歷需要渲染的資料、建立新的工作物件、還能用標識符來查詢、編輯或刪除工作。然而,當我們要求程式,讓用戶在瀏覽器完成 這一切 的話,麻煩就來了。 問題在於:更動狀態時,也同時需要更動 UI 的顯示。
讓我們藉由待辦事項程式的 一個功能 來看看這個問題有多難搞:把工作清單渲染出來。
DOM 的冗長變化
建立 HTML 元素並在瀏覽器上渲染,會需要驚人數量的程式碼。假設我們的狀態,是一個由多個物件組成的陣列:
js
const state = [
id: "todo-0",
name: "Learn some frameworks!",
我們如何對用戶顯示工作?我們想將每個工作,都表示為一個列表項目:結構為無序列表元素 <ul>
(en-US) 內,含有一定數量的 <li>
(en-US) 元素。怎麼做呢?看起來就像這樣:
js
function buildTodoItemEl(id, name) {
const item = document.createElement("li");
const
span = document.createElement("span");
const textContent = document.createTextNode(name);
span.appendChild(textContent);
item.id = id;
item.appendChild(span);
item.appendChild(buildDeleteButtonEl(id));
return item;
我們在這裡用上了 document.createElement()
方法建立了 <li>
、還有一些程式碼來建立需要的屬性與子元素。
程式的第十行引用了另一個構建函式:buildDeleteButtonEl()
。它與用於構建列表元素的模式很像:
js
function buildDeleteButtonEl(id) {
const button = document.createElement("button");
const textContent = document.createTextNode("Delete");
button.setAttribute("type", "button");
button.appendChild(textContent);
return button;
這個按鈕還派不上用場,但稍後我們會用它來實做刪除功能。這渲染程式,會讓頁面看起來像這樣:
js
function renderTodoList() {
const frag = document.createDocumentFragment();
state.tasks.forEach((task) => {
const item = buildTodoItemEl(task.id, task.name);
frag.appendChild(item);
});
while (todoListEl.firstChild) {
todoListEl.removeChild(todoListEl.firstChild);
todoListEl.appendChild(frag);
光是為了弄 UI 我們就寫了大約三十行左右的程式:這樣就只是為了能讓清單在 DOM 渲染而已喔。更別提之後還需要添加方便樣式化的 class。
像範例這樣直接操作 DOM 的話,會需要理解很多 DOM 的東西:像是 DOM 的原理、如何建立元素、更改屬性、巢狀排列……同時還要把他們都呈現出來。這些程式甚至還沒有處理與用戶的互動或工作。在增加功能的時候,我們需要在正確的時間、用正確的方法,來更新我們的 UI。
JavaScript 框架旨在使這類工作更加輕鬆:他們會提供更好的開發體驗。框架本身並沒有給 JavaScript 提供新功能;而是用更容易的方案,建立當代的網站。
如果想查看本節中的程式碼範例,請參閱 CodePen 的程式:這網站同樣允許用戶添加和刪除新任務。
閱讀本節中使用的 JavaScript 資訊:
document.createElement()
document.createTextNode()
document.createDocumentFragment()
eventTarget.addEventListener()
node.appendChild()
(en-US)
node.removeChild()
建立 UI 的另一種方法
建立 UI 的另一種方法
JavaScript 框架都會提供一種能更加
宣告性
撰寫介面的方法。也就是說,框架能讓你描述 UI 看起來要怎麼樣、然後在 DOM 的背後完成這一切。
原生 JavaScript 試圖重複建立新 DOM 元素的方法,很難一眼理解。相反地,來看看 Vue 的程式碼會怎麼完成吧:
html
<ul>
<li v-for="task in tasks" v-bind:key="task.id">
<span>{{task.name}}</span>
<button type="button">Delete</button>
就這樣啦。原本大約三十多行的程式,現在只要六行。如果不太熟悉大括號和 v-
屬性的話,沒關係;那些語法會在 Vue 模塊學到。這裡只是要講說與原生 JavaScript 對比,框架的程式碼看起來更像是實際呈現的 UI。
也因為有 Vue,我們再也不用自己寫針對 UI 呈現的函式;整個框架會幫我們用最優化、最效率的方法完成這件事。我們只要告訴 Vue 整個排版要怎麼排就好。熟悉 Vue 的開發者,也可以盡快參與我們的專案、搞清楚整個專案到底怎麼做的。不過並不是只有 Vue 這樣:使用框架本身,就可以提高團隊與個人的工作效率。
要在原生 JavaScript 做類似的事是可以的。樣板文字就能在編寫 HTML 字串的同時,也表示最終元素的外觀。就算是待辦事項列表應用,這樣簡單的事情,這可能是一個有用的想法,但是對於管理成千上萬條數據記錄、並且要在用戶界面中呈現盡可能多唯一元素的大型應用程序而言,這樣子是很難維護的。
框架給我們的其他東西
框架給我們的其他東西
讓我們看看框架賦予的其他優勢。正如之前提,你可以透過原生 JavaScript 實現框架,但是使用框架可以消除自行解決這些問題所需要的認知負擔。
工具
工具
本模塊提到的幾個框架,背後都有著龐大而活躍的社群;這些社群形成了各種生態圈、並提供能增進開發體驗的工具:像是確保功能正常的測試、或著維持程式一致性的 linting。
備註:
如果對這方面的概念有興趣,請看看
Client-side tooling overview
(en-US)
。