Skip to content

从 Express 到 Vafast

本指南适用于希望了解 Express 与 Vafast 之间差异的 Express 用户,包括语法,以及如何通过示例将应用程序从 Express 迁移到 Vafast。

Express 是一个流行的 Node.js 网络框架,广泛用于构建 Web 应用程序和 API。因其简单性和灵活性而闻名。

Vafast 是一个高性能的 TypeScript Web 框架,支持 Node.js、Bun 等多种运行时,专注于类型安全、中间件系统和性能优化。设计时强调简单性和开发者友好,提供完整的 TypeScript 支持。

性能

由于 Radix Tree 路由匹配算法和 JIT 编译验证器,Vafast 在性能上相比 Express 有显著提高。

  1. Vafast
    2,454,631 reqs/s
  2. Express

    113,117

Measured in requests/second. Result from TechEmpower Benchmark Round 22 (2023-10-17) in PlainText

路由

Express 和 Vafast 有类似的路由语法,但 Vafast 使用配置对象的方式定义路由,提供更好的类型安全和中间件支持。

ts
import express from 'express'

const app = express()

app.get('/', (req, res) => {
    res.send('Hello World')
})

app.post('/id/:id', (req, res) => {
    res.status(201).send(req.params.id)
})

app.listen(3000)

Express 使用 reqres 作为请求和响应对象

ts
import { Server, defineRoute, defineRoutes } from 'vafast'

const routes = defineRoutes([
  defineRoute({
    method: 'GET',
    path: '/',
    handler: () => 'Hello World'
  }),
  defineRoute({
    method: 'POST',
    path: '/id/:id',
    handler: ({ params }) => {
      return { id: params.id }
    }
  })
])

const server = new Server(routes)
export default { fetch: server.fetch }

Vafast 使用配置对象定义路由,支持类型安全和中间件

主要差异

1. 路由定义方式

Express 使用链式方法调用:

typescript
app.get('/users', (req, res) => { ... })
app.post('/users', (req, res) => { ... })

Vafast 使用配置对象数组:

typescript
const routes = defineRoutes([
  defineRoute({
    method: 'GET',
    path: '/users',
    handler: () => { ... }
  }),
  defineRoute({
    method: 'POST',
    path: '/users',
    handler: () => { ... }
  })
])

新框架用法说明

  • 所有路由必须使用 defineRoute 包装
  • Handler 直接是函数,不再需要 createHandler 包装

2. 请求处理

Express 使用 reqres 对象:

typescript
app.get('/user/:id', (req, res) => {
  const id = req.params.id
  const query = req.query
  res.json({ id, query })
})

Vafast 使用解构参数:

typescript
defineRoute({
  method: 'GET',
  path: '/user/:id',
  handler: ({ params, query }) => {
    return { id: params.id, query }
  }
})

3. 中间件系统

Express 使用 app.use() 和路由级中间件:

typescript
app.use(loggingMiddleware)
app.get('/admin', authMiddleware, (req, res) => {
  res.send('Admin Panel')
})

Vafast 支持全局和路由级中间件:

typescript
import { defineRoute, defineRoutes, defineMiddleware } from 'vafast'

const loggingMiddleware = defineMiddleware(async (req, next) => {
  console.log(`${req.method} ${req.url}`)
  return await next()
})

const routes = defineRoutes([
  defineRoute({
    method: 'GET',
    path: '/admin',
    handler: () => 'Admin Panel',
    middleware: [authMiddleware]
  }
])

4. 错误处理

Express 使用错误处理中间件:

typescript
app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

Vafast 支持中间件链中的错误处理:

typescript
import { defineMiddleware, json } from 'vafast'

const errorHandler = defineMiddleware(async (req, next) => {
  try {
    return await next()
  } catch (error) {
    return json({ error: error.message }, 500)
  }
})

新框架用法说明

  • 中间件使用 defineMiddleware 定义,支持类型注入

迁移步骤

步骤 1: 安装 Vafast

bash
npm install vafast

步骤 2: 重构路由定义

将 Express 的路由定义转换为 Vafast 的配置对象格式:

typescript
// Express 风格
app.get('/api/users', (req, res) => {
  const users = getUsers()
  res.json(users)
})

// Vafast 风格
defineRoute({
  method: 'GET',
  path: '/api/users',
  handler: () => {
    return getUsers()
  }
})

步骤 3: 更新中间件

将 Express 中间件转换为 Vafast 中间件格式:

typescript
// Express 中间件
const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization
  if (!token) {
    return res.status(401).send('Unauthorized')
  }
  next()
}

// Vafast 中间件
import { defineMiddleware, json } from 'vafast'

const authMiddleware = defineMiddleware(async (req, next) => {
  const token = req.headers.get('authorization')
  if (!token) {
    return json({ error: 'Unauthorized' }, 401)
  }
  return await next()
})

步骤 4: 更新错误处理

typescript
// Express 错误处理
app.use((err, req, res, next) => {
  res.status(500).json({ error: err.message })
})

// Vafast 错误处理
import { json } from 'vafast'

const errorHandler = async (req: Request, next: () => Promise<Response>) => {
  try {
    return await next()
  } catch (error) {
    return json({ error: error instanceof Error ? error.message : 'Unknown error' }, 500)
  }
}

完整迁移示例

Express 应用

typescript
import express from 'express'
import cors from 'cors'
import helmet from 'helmet'

const app = express()

app.use(cors())
app.use(helmet())
app.use(express.json())

app.get('/users', (req, res) => {
  const users = getUsers()
  res.json(users)
})

app.post('/users', (req, res) => {
  const user = createUser(req.body)
  res.status(201).json(user)
})

app.get('/users/:id', (req, res) => {
  const user = getUserById(req.params.id)
  if (!user) {
    return res.status(404).json({ error: 'User not found' })
  }
  res.json(user)
})

app.listen(3000)

Vafast 应用

typescript
import { Server, defineRoute, defineRoutes, json, err } from 'vafast'
import { cors } from '@vafast/cors'

const routes = defineRoutes([
  defineRoute({
    method: 'GET',
    path: '/users',
    handler: () => getUsers()
  }),
  defineRoute({
    method: 'POST',
    path: '/users',
    handler: ({ body }) => json(createUser(body), 201)
  }),
  defineRoute({
    method: 'GET',
    path: '/users/:id',
    handler: ({ params }) => {
      const user = getUserById(params.id)
      if (!user) {
        throw err.notFound('User not found')
      }
      return user
    }
  })
])

const server = new Server(routes)
server.useGlobalMiddleware(cors())

export default { fetch: server.fetch }

新框架用法说明

  • 所有路由使用 defineRoute 包装
  • Handler 直接是函数,不再需要 createHandler
  • 全局中间件使用 server.useGlobalMiddleware()

优势对比

特性ExpressVafast
类型安全❌ 需要额外配置✅ 完整的 TypeScript 支持
性能⚠️ 中等高性能
中间件系统✅ 成熟✅ 灵活可扩展
路由定义⚠️ 链式调用✅ 配置对象
错误处理✅ 中间件方式✅ 中间件链
Bun 支持❌ 需要适配✅ 原生支持

下一步

现在您已经了解了如何从 Express 迁移到 Vafast,建议您:

  1. 查看 快速入门 开始使用 Vafast
  2. 阅读 核心概念 深入了解 Vafast 的工作原理
  3. 探索 中间件系统 了解如何扩展功能
  4. 查看 示例代码 获取更多实践示例

如果您在迁移过程中遇到任何问题,欢迎在我们的 GitHub Issues 社区寻求帮助。