在網頁開發的世界中,各種框架和函式庫日新月異地發展。到了2025年,目前前端和後端各有許多選擇,選擇適合專案的最佳解決方案將成為成功的關鍵。
本文將詳細解釋目前最常使用的主要網頁框架及其特點和差異。
前端
後端
另外,本文也將探討與這些框架密切相關的TypeScript。
框架與函式庫經常被混淆,但它們之間有明確的差異。
函式庫 是開發者可呼叫所需功能的「工具箱」。開發者控制程式碼的流程,並在需要時調用函式庫的功能。
框架 則提供應用程式整體的「骨架」。框架控制整體流程,開發者在這個框架內撰寫代碼。這被稱為「控制反轉」(Inversion of Control)。
例如,React嚴格來說是「函式庫」,但在實際開發中,因為常與路由和狀態管理等函式庫結合使用,因此也常被當作框架來看待。
TypeScript是一種在JavaScript上增加靜態類型的程式語言。由微軟開發,設計為JavaScript的超集(向下相容)。
理解TypeScript本身不是框架,而是擴展JavaScript的「語言」是非常重要的。用TypeScript撰寫的代碼會被編譯並最終轉換為JavaScript。
TypeScript的主要特點
接下來,我們看看本文介紹的框架與TypeScript之間的關係。
| 框架 | TypeScript支持 | 預設語言 | 備註 |
|---|---|---|---|
| React | 完全支持 | JavaScript | 型別定義檔(@types/react)相當豐富 |
| Vue.js | 完全支持 | JavaScript | Vue 3大幅增強TypeScript支持 |
| Next.js | 完全支持 | JavaScript | TypeScript優先的開發體驗 |
| Express.js | 完全支持 | JavaScript | @types/express提供型別定義 |
| Django | - | Python | 使用Python的型別提示 |
| FastAPI | - | Python | Python的型別提示是必需的 |
| Ruby on Rails | - | Ruby | Ruby的型別檢查工具另有提供 |
基於JavaScript的框架越來越普遍使用TypeScript進行開發,而Python及Ruby的框架則分別利用其語言本身的型別系統。
減少錯誤的型別安全性
透過編譯時檢測型別錯誤,能在執行前防止許多錯誤。
// TypeScript的範例
interface User {
id: number;
name: string;
email: string;
}
function getUserName(user: User): string {
return user.name;
}
// 若型別不符會出現編譯錯誤
getUserName({ id: 1, name: "太郎" }); // 錯誤: 必須有email屬性
提升開發體驗
IDE能理解型別資訊,使代碼補全和函式簽名的顯示更準確。這有助於減少對文件的頻繁查閱,並提升開發速度。
重構的安全性
有了型別資訊,代碼變更對其他部分的影響將自動被檢測出來,使得在大型代碼庫中也能放心進行重構。
前端框架是用來構建用戶直接操作的UI部分的基礎。我們將對目前最常用的三個框架進行比較。
React是由Facebook開發的最受歡迎的JavaScript函式庫。在2024年的Stack Overflow開發者調查中,其滿意度達到67%,在超過200萬的網站上使用。
React最大的特點是能將UI構建為獨立的可重用元件。每個元件都有其獨特的狀態和邏輯,通過組合形成複雜的UI。
// React元件的範例
interface ButtonProps {
label: string;
onClick: () => void;
}
function Button({ label, onClick }: ButtonProps) {
return (
<button onClick={onClick}>
{label}
</button>
);
}
// 組合使用元件
function App() {
return (
<div>
<Button label="送信" onClick={() => console.log('送信')} />
<Button label="取消" onClick={() => console.log('取消')} />
</div>
);
}
React使用Virtual DOM(虛擬DOM)作為實際DOM的輕量復本,而不直接操作實際的DOM。當有變更時,會在Virtual DOM中計算差異,僅將必要的部分更新至實際DOM,從而實現快速渲染。
React擁有非常龐大的社群,並提供許多豐富的函式庫可供使用。
React適合的情境
Vue.js是一個漸進式框架,學習曲線平緩,非常適合初學者。已被超過150萬個網站使用,具有適用小型到大型專案的靈活性。
Vue.js的「漸進式」特點意味著可以根據需要逐步導入功能。從簡單的函式庫開始,隨著專案成長可逐漸增加功能。
可從最小的配置開始,然後再添加路由、狀態管理、構建工具等,因此學習成本分散。
Vue.js的模板語法接近HTML的寫法,因此非常適合初學者理解。
<!-- Vue.js元件的範例 -->
<template>
<div>
<h1>{{ title }}</h1>
<button @click="increment">計數: {{ count }}</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const title = ref('Vue.js範例');
const count = ref(0);
function increment() {
count.value++;
}
</script>
<style scoped>
h1 {
color: #42b983;
}
</style>
單文件元件(SFC)的形式可以將模板、邏輯和樣式集中在一個文件中。這種結構可以在明確分離元件關心的同時,將相關元素靠近以提高可讀性。
Vue.js提供Options API和Composition API兩種書寫風格。
Options API是傳統的書寫方法,以物件定義選項。對初學者來說結構容易理解。
Composition API是Vue 3引入的新書寫方式,將邏輯定義為函式。與TypeScript的相容性良好,能提高複雜邏輯的重用性。
// Composition API的範例
import { ref, computed } from 'vue';
export function useCounter(initialValue: number = 0) {
const count = ref(initialValue);
const doubled = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubled, increment };
}
這些邏輯可在其他元件中重用,使代碼組織變得更容易。
Vue.js適合的情境
Next.js是一個基於React的全棧框架,支援SSR(伺服器端渲染)和SSG(靜態網站生成),在SEO優化上表現出色。
Next.js建立在React之上,因此可直接使用React的知識。然而,它不只是React函式庫,更是一個包含後端功能的「全棧」框架。
Next.js最大的特點是可為每個頁面選擇不同的渲染策略。
SSR(伺服器端渲染)
每次請求都在伺服器上生成HTML。適合希望顯示最新數據的情況。
// SSR範例
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: { data },
};
}
export default function Page({ data }) {
return <div>{data.title}</div>;
}
SSG(靜態網站生成)
在構建時生成HTML。當內容不常變動時,能以最快速度進行分發。
// SSG範例
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: { data },
revalidate: 60, // 每60秒重新生成(ISR)
};
}
ISR(增量靜態重生成)
SSG和SSR的中間方法,可以定期更新靜態生成的頁面。是一種平衡速度和新鮮度的方案。
| 渲染方式 | 生成時機 | 速度 | 新鮮度 | 適用案例 |
|---|---|---|---|---|
| SSG | 構建時 | 最快 | 低 | 部落格、文件 |
| ISR | 構建時 + 定期更新 | 快速 | 中 | 新聞網站、電子商務網站 |
| SSR | 請求時 | 中速 | 高 | 儀表板、個性化內容 |
| CSR | 瀏覽器 | 可變 | 最佳 | 管理界面、動態應用 |
在Next.js中,路由會自動基於文件系統進行設置。只要將檔案放置於pages或app目錄中,相應的URL就會自動生成。
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ ├── page.tsx → /blog
│ └── [slug]/
│ └── page.tsx → /blog/:slug
└── api/
└── users/
└── route.ts → /api/users
這種機制使得無需明確撰寫路由設置,可以直觀地管理頁面結構。
Next.js適合的情境
| 項目 | React | Vue.js | Next.js |
|---|---|---|---|
| 類型 | 函式庫 | 框架 | 框架 |
| 學習難度 | 中 | 低 | 中〜高 |
| 初始設置 | 需搭建工具 | 靈活 | 最小限 |
| TypeScript支持 | 完全支持 | 完全支持 | 完全支持 |
| 渲染類型 | CSR | CSR | SSR/SSG/ISR/CSR |
| 路由 | 需額外導入 | Vue Router | 基於文件系統 |
| 狀態管理 | 需額外導入 | Vuex/Pinia | React + 需額外導入 |
| SEO支持 | 弱 | 弱 | 強 |
| 後端 | 不可 | 不可 | 支持API Routes |
| 生態系統 | 最大 | 大 | 正在成長 |
| 採用企業 | Facebook, Instagram, Airbnb | GitLab, Adobe | Netflix, Twitch, Nike |
| 社群 | 最大 | 大 | 快速成長 |
後端框架負責伺服器端的數據處理、數據庫操作、API提供等。每種語言有特定的框架,擁有不同的哲學和優勢。
Express.js是運行於Node.js上最受歡迎的後端框架。設計輕量且極簡,能實現全JavaScript棧的開發。
Express.js是「非意見導向」(Non-opinionated)的框架。這意味著它不強制特定的開發方式,開發者可以自由設計。
// Express.js的基本用法
import express, { Request, Response } from 'express';
const app = express();
// 啟用JSON解析器
app.use(express.json());
// 定義路由
app.get('/api/users', (req: Request, res: Response) => {
res.json({ users: ['Alice', 'Bob', 'Charlie'] });
});
app.post('/api/users', (req: Request, res: Response) => {
const user = req.body;
// 處理新增用戶的邏輯
res.status(201).json({ message: '創建成功', user });
});
app.listen(3000, () => {
console.log('伺服器運行於3000端口');
});
此靈活性使得從小型API到大型應用程式,可以自由地根據專案需求進行組建。
前端和後端都使用JavaScript(或TypeScript),帶來如下好處:
// 共享的型別定義
interface User {
id: number;
name: string;
email: string;
}
// 後端(Express.js)
app.get('/api/users/:id', async (req: Request, res: Response) => {
const user: User = await getUserById(Number(req.params.id));
res.json(user);
});
// 前端(React)
async function fetchUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
Django是用Python編寫的「電池隨附」的全面Web框架,幾乎包含了所有必要的功能,使得快速開發成為可能。
Django的「電池隨附」哲學意味著標準提供Web開發所需的功能。內建的有ORM(物件關聯映射)、管理介面、驗證系統、表單處理、安全策略等。
這樣可以減少尋找和集成外部函式庫的麻煩,讓開發更為專注。
Django的ORM可使用Python類定義數據庫表,無需編寫SQL即可進行數據庫操作。
# models.py - 模型定義
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
class Meta:
db_table = 'users'
ordering = ['-created_at']
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
published_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
ORM使得複雜的SQL查詢也能用Python的方法鏈式表達,並且對數據庫類型的變更也沒有影響。
Django的一大特點是其自動生成管理介面的功能。僅透過定義模型,便可以自動創建具備CRUD操作的管理介面。
# admin.py
from django.contrib import admin
from .models import User, Post
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ['name', 'email', 'is_active', 'created_at']
list_filter = ['is_active', 'created_at']
search_fields = ['name', 'email']
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'published_at']
list_filter = ['published_at']
search_fields = ['title', 'content']
raw_id_fields = ['author']
僅透過這些設置,便可擁有以下功能的管理介面。
這個功能對於原型開發或內部管理工具來說極其方便。
Django適合的情境
FastAPI是2024-2025年增長最快的Python Web框架,專注於高性能的API構建,充分利用非同步處理。
FastAPI是基於Python的非同步功能(async/await)設計而成的,可實現高效的API響應。其性能可與Node.js或Go相媲美。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
import asyncio
app = FastAPI()
class User(BaseModel):
id: int
name: str
email: str
# 非同步端點
@app.get("/api/users/{user_id}", response_model=User)
async def get_user(user_id: int):
user = await fetch_user_from_db(user_id)
if not user:
raise HTTPException(status_code=404, detail="未找到用戶")
return user
# 以並行方式執行多個非同步處理
@app.get("/api/users/{user_id}/dashboard")
async def get_user_dashboard(user_id: int):
user, posts, followers = await asyncio.gather(
fetch_user_from_db(user_id),
fetch_user_posts(user_id),
fetch_user_followers(user_id)
)
return {
"user": user,
"posts": posts,
"followers": followers
}
非同步處理使得在等待I/O(例如數據庫查詢或外部API調用)時,可以處理其他請求,因此能顯著提高吞吐量。
FastAPI能自動生成基於OpenAPI(舊稱Swagger)標準的互動式API文檔。僅通過編碼即可自動獲得以下資源。
/docs)/redoc)/openapi.json)from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
from typing import Optional
app = FastAPI(
title="用戶管理API",
description="用於創建、獲取、更新和刪除用戶的API",
version="1.0.0"
)
class UserCreate(BaseModel):
name: str = Field(..., description="用戶名")
email: str = Field(..., description="電子郵件地址")
age: Optional[int] = Field(None, description="年齡")
@app.post("/api/users", response_model=User, summary="創建新用戶", description="接收用戶信息並創建新用戶")
async def create_user(user: UserCreate):
"""創建用戶的端點
- **name**: 用戶名(必需)
- **email**: 電子郵件(必需)
- **age**: 年齡(可選)
"""
# 用戶創建處理邏輯
return created_user
這段代碼自動生成的文檔,包括了:
FastAPI充分利用Python的型別提示,與Pydantic庫連用,自動處理以下項目。
from fastapi import FastAPI, Query, Path
from pydantic import BaseModel, validator
from typing import List
from datetime import datetime
app = FastAPI()
class PostCreate(BaseModel):
title: str
content: str
tags: List[str] = []
@validator('title')
def title_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('標題不得為空')
return v
@app.get("/api/posts")
async def list_posts(
skip: int = Query(0, ge=0, description="跳過的數量"),
limit: int = Query(10, ge=1, le=100, description="最大取得數量"),
tag: Optional[List[str]] = Query(None, description="根據標籤過濾")
):
# 查詢參數自動進行驗證
posts = await fetch_posts(skip=skip, limit=limit, tag=tag)
return posts
@app.post("/api/posts")
async def create_post(post: PostCreate):
# 請求主體自動進行驗證
# 若型別不符,自動返回422錯誤
created_post = await save_post(post)
return created_post
型別提示使得IDE能提供準確的代碼補全,顯著提升開發效率。
FastAPI適合的情境
Ruby on Rails(簡稱Rails)是一個用Ruby編寫的Web應用框架,受到了初創公司廣泛的青睞。其快速原型開發和「設定比規約更重要」的哲學特點尤為明顯。
Rails的中核哲學是「設定比規約更重要」(CoC: Convention over Configuration),這意味着開發者依循Rails的規約,可自動獲得所需功能,而無需撰寫繁瑣的設定檔。
# app/models/user.rb
class User < ApplicationRecord
has_many :posts
validates :email, presence: true, uniqueness: true
end
# app/models/post.rb
class Post < ApplicationRecord
belongs_to :user
validates :title, presence: true
end
這段簡單的代碼自動完成了以下工作:
users表與User模型關聯posts表與Post模型關聯user.posts獲取用戶的帖文列表Rails重視「DRY」(Don't Repeat Yourself: 避免重複)原則,即不應重複寫相同的代碼,而應作為可重用的組件進行整理。
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
@posts = Post.all
end
def show
# @post已在before_action中設置
end
def create
@post = current_user.posts.build(post_params)
if @post.save
redirect_to @post, notice: '成功創建帖子'
else
render :new
end
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :content)
end
end
共同處理的邏輯則經由before_action進行整理,避免重複。此外,使用Rails的輔助方法能進一步減少冗餘代碼。
Rails非常適合迅速將想法轉化為實體。通過scaffold命令,可以在幾分鐘內生成具備CRUD操作的基本應用。
# 使用scaffold命令一鍵生成帖子功能
rails generate scaffold Post title:string content:text user:references
# 執行遷移以更新數據庫
rails db:migrate
僅此一條命令,即可自動生成:
Post)PostsController)進行原型設計並從用戶那裡取得反饋,隨後再逐步改進,這種敏捷開發方式非常適合。
Ruby on Rails適合的情境
| 項目 | Express.js | Django | FastAPI | Ruby on Rails |
|---|---|---|---|---|
| 語言 | JavaScript/TypeScript | Python | Python | Ruby |
| 類型 | 輕量型 | 全棧 | 專注於API | 全棧 |
| 學習難度 | 低〜中 | 中 | 中 | 中 |
| 效能 | 高 | 中 | 最高 | 中 |
| 非同步處理 | 原生支持 | 部分支持 | 原生支持 | 視情況可能支持 |
| ORM | 需額外導入 | Django ORM | SQLAlchemy等 | Active Record |
| 管理介面 | 需經過實作 | 內建 | 需額外實作 | 需額外實作 |
| API文檔 | 需額外實作 | 需額外實作 | 自動生成 | 需額外實作 |
| 型別安全性 | TypeScript支持時支持 | 支持型別提示 | 需型別提示 | 僅限於某些情況 |
| 設計理念 | 非意見導向 | 電池隨附 | 現代API開發 | 設定比規約 |
| 適用範圍 | 小〜大 | 中〜大 | 小〜中 | 小〜中 |
| 社群 | 最大 | 大 | 快速成長 | 成熟 |
| 主要採用企業 | Netflix, Uber | Instagram, Pinterest | Microsoft, Uber | GitHub, Shopify |
| 社群活躍度 | 最大 | 大 | 快速增長 | 成熟 |
原文出處:https://qiita.com/ktdatascience/items/e09cf1a615013f49388d