Skip to content

feat: ⚡重构世界上最快的路由库#1

Open
aui wants to merge 5 commits intomainfrom
web
Open

feat: ⚡重构世界上最快的路由库#1
aui wants to merge 5 commits intomainfrom
web

Conversation

@aui
Copy link
Collaborator

@aui aui commented Aug 1, 2025

概述

本 RFC 提出一个雄心勃勃的计划:基于现有的 find-my-way 路由库创建 Lightning Router ⚡ - 一个全新的世界级 Web 标准路由库。find-my-way 已经是当前世界上最快的 JavaScript 路由库,Fastify 基于它实现了世界上最快的 JavaScript Web 框架。我们的目标是在这个基础上进一步提升 30% 的性能,这将创造一个新的性能标杆,并为 Web Widget 元框架提供世界级性能的底层路由支持。

重要说明: Lightning Router 是一个全新的项目,将采用全新的项目名称和包名(@web-widget/lightning-router),不会保持与 find-my-way 的接口兼容性。我们将基于 find-my-way 的优秀算法和架构,但完全重新设计 API 以适配 Web 标准和性能优化需求。

这个项目将支持多个平台运行,包括 Cloudflare Workers、Service Workers、Node.js 等环境,同时保持对 Web 标准的完全兼容。

🎯 项目动机与愿景

find-my-way 是当前世界上最快的 JavaScript 路由库,但其严重依赖 Node.js 特定 API,无法在 Web 标准环境中运行。本项目旨在将其重新定位为元路由器,通过分层架构既保持原有的性能优势,又支持多平台运行。

主要改进方向:平台依赖解耦、模块系统现代化(ESM)、类型安全(TypeScript)、跨平台兼容性。

核心目标:为 Web Widget 元框架提供世界级性能的底层路由支持,同时保持对现有 Node.js 生态的完全兼容。

🏗️ 技术方案与架构设计

元路由器核心理念:分层架构

基于深入的架构分析,我们决定将 find-my-way 重新定位为元路由器,作为底层核心,然后基于它扩展出不同的上层适配器。这样既保持了核心算法的优势,又实现了跨平台的灵活性。

┌─────────────────────────────────────────────────────────┐
│                   应用层适配器                            │
├─────────────────────┬───────────────────────────────────┤
│   Node.js 适配器     │     Web 标准适配器                 │
│   (现有兼容)        │     (新增功能)                      │
├─────────────────────┴───────────────────────────────────┤
│                 Find-My-Way 元路由核心                   │
│              (平台无关的路由匹配算法)                      │
└─────────────────────────────────────────────────────────┘

设计原则

分离关注点:核心层专注于高性能路由匹配算法(平台无关),适配层处理平台特定的 API 差异。

最小化核心改动:保持 Radix 树、约束系统等核心算法不变,只抽象出平台特定的部分。

渐进式升级:现有 Node.js 代码零改动,新项目可选择 Web 标准模式。

技术栈现代化

将项目从 CommonJS + JavaScript 迁移到 ESM + TypeScript,要求 Node.js >= 18 以获得原生 Web API 支持。核心改动包括模块系统迁移、HTTP 对象标准化、TypeScript 严格模式集成。

📋 实施计划与执行策略

当前实施状态

已完成:Node.js 依赖清理、ESM 迁移,所有测试用例通过(484/484)。

进行中:TypeScript 严格模式迁移。

待开始:Web 标准 API 重构、元路由器架构重构。

实施原则

小步快跑(每个变更 200-300 行以内)、测试驱动、可回滚。前三阶段保持功能兼容,第四阶段进行架构重构。

阶段三:TypeScript 严格模式(进行中)

3.1 TypeScript 工具链部署

  • 配置 tsconfig.json 严格模式
  • 配置 ESLint 和 Prettier
  • 配置类型检查脚本
  • 验证工具链正常工作

3.2 文件重命名和基础类型

  • 使用 git mv 重命名所有 .js 文件为 .ts
  • 创建 src/types/index.ts 定义基础类型
  • 添加基础的 JSDoc 注释
  • 运行类型检查,修复基础错误

3.3 核心类型系统

  • src/core/node.ts 添加完整类型
  • src/core/handler-storage.ts 添加完整类型
  • src/core/constrainer.ts 添加完整类型
  • src/strategies/ 目录添加类型定义

3.4 主路由类型

  • src/core/router.ts 添加完整类型
  • 为路由注册方法添加类型
  • 为路由查找方法添加类型
  • 为测试用例添加类型定义

阶段四:Web 标准 API 重构(待开始)

4.1 原生 Web API 支持

  • 创建 web.js 作为 Web API 版本的入口
  • 重构签名,以符合 Web 的使用方式
  • 支持原生 Request/Response 对象
  • 更新接口定义支持原生 Web API

4.2 核心逻辑重构

  • 更新 lookup 方法签名,传入原生 Request 对象
  • 更新 Handler 接口签名,返回原生 Response 对象
  • 更新约束策略使用原生 Request 对象
  • 更新约束推导逻辑

4.3 测试环境适配

  • 更新现有测试用例使用原生 Web API
  • 添加原生 Web API 兼容性测试
  • 配置多环境测试
  • 运行完整测试套件

阶段五:元路由器架构重构(待开始)

5.1 性能基准建立

  • 运行现有性能基准测试
  • 记录关键性能指标
  • 分析性能瓶颈
  • 分析中间件 vs 处理器路由的使用模式

5.2 元路由器核心重构

  • 识别并抽象 Node.js 特定的部分(req/res 对象)
  • 设计平台无关的 RouteContext 接口
  • 创建 UniversalHandler 类型定义
  • 将现有路由匹配逻辑改为使用平台无关接口
  • 实现 MetaRouter 核心类
  • 保持所有现有算法优化(Radix树、约束系统等)

5.3 适配器实现

Node.js 适配器

  • 实现 NodeRouterAdapter
  • 保持现有 API 完全兼容
  • 包装 Node.js handler 为 UniversalHandler
  • 运行所有现有测试,确保零破坏性变更

Web 标准适配器

  • 实现 WebRouterAdapter
  • 支持中间件链执行模式
  • 实现智能路径选择优化
  • 添加 Web 标准适配器的专门测试

5.4 性能验证和优化

  • 对比重构前后的性能数据
  • 验证 Node.js 适配器性能无退化
  • 测试 Web 适配器的中间件链性能
  • 分析中间件链执行开销
  • 探索上下文对象复用策略
  • 研究编译时优化可能性

检查点说明

每个主要步骤完成后都有 Code Review 检查点,确保:

  • 代码质量符合标准
  • 所有相关测试通过
  • 性能无明显退化
  • 功能完整性得到验证

🔧 技术细节与实现方案

文件结构规划

基于元路由器架构的新文件结构:

find-my-way/
├── core/                  # 元路由核心(平台无关)
│   ├── meta-router.ts     # 元路由器主类
│   ├── radix-tree.ts      # Radix 树实现
│   ├── constrainer.ts     # 约束系统
│   ├── handler-storage.ts # 处理器存储
│   └── types.ts           # 核心类型定义
├── adapters/              # 平台适配器
│   ├── node.ts           # Node.js 适配器
│   ├── web.ts            # Web 标准适配器
│   ├── deno.ts           # Deno 适配器(未来)
│   └── cloudflare.ts     # Cloudflare Workers 适配器(未来)
├── strategies/            # 约束策略
│   ├── http-method.ts     # HTTP 方法策略
│   ├── host.ts           # 主机策略
│   └── version.ts        # 版本策略
├── utils/                 # 工具函数
│   ├── url-sanitizer.ts   # URL 处理工具
│   ├── querystring.ts     # 查询字符串处理
│   └── assertions.ts      # 断言工具
├── index.ts              # 默认导出(Node.js 适配器)
└── web.ts                # Web 标准导出

迁移策略

采用渐进式迁移:基础设施建设(ESM、Web API、TypeScript)→ 元路由器架构重构(内部重构、适配器实现、性能验证)→ 生态扩展。

要求 Node.js >= 18 以获得原生 Web API 支持,确保跨平台兼容性。

核心接口设计

元路由器核心接口 - 平台无关

/**
 * 元路由器核心接口 - 完全平台无关
 */
interface MetaRouter {
  /**
   * 注册路由处理器
   * @param method HTTP 方法
   * @param path 路径模式  
   * @param handler 平台无关的处理器
   * @param options 路由选项
   */
  register(
    method: string | string[],
    path: string, 
    handler: UniversalHandler,
    options?: RouteOptions
  ): void;

  /**
   * 查找匹配的路由
   * @param method HTTP 方法
   * @param path 请求路径
   * @param context 查找上下文
   * @returns 匹配结果或 null
   */
  lookup(
    method: string,
    path: string,
    context?: LookupContext
  ): RouteMatch | null;

  /**
   * 执行路由处理器
   * @param match 路由匹配结果
   * @param executor 平台特定的执行器
   * @returns 执行结果
   */
  execute<T>(
    match: RouteMatch,
    executor: RouteExecutor<T>
  ): T;
}

/**
 * 平台无关的处理器接口
 */
type UniversalHandler = (context: RouteContext) => any;

/**
 * 路由上下文 - 包含所有路由信息,但不包含平台特定对象
 */
interface RouteContext {
  method: string;
  path: string;
  params: Record<string, string>;
  searchParams: Record<string, string>;
  store?: any;
  constraints?: Record<string, any>;
  // 平台特定数据通过泛型扩展
  platform?: any;
}

/**
 * 路由执行器 - 平台适配器实现
 */
interface RouteExecutor<T> {
  (handler: UniversalHandler, context: RouteContext): T;
}

关键改动点

当前签名的问题:

// 当前:强依赖 Node.js 类型
handler(req: IncomingMessage, res: ServerResponse, params, store, searchParams)
lookup(req: IncomingMessage, res: ServerResponse, ctx?, done?)

元路由签名:

// 改为:平台无关
handler(context: RouteContext)
lookup(method: string, path: string, context?: LookupContext)

适配器架构

1. Node.js 适配器(保持现有兼容性)

class NodeRouterAdapter {
  constructor(private metaRouter: MetaRouter) {}

  // 保持现有签名不变
  on(method: string, path: string, handler: NodeHandler, store?: any) {
    // 将 Node.js handler 包装为 UniversalHandler
    const universalHandler = (context: RouteContext) => {
      const { req, res } = context.platform;
      return handler(req, res, context.params, context.store, context.searchParams);
    };
    
    this.metaRouter.register(method, path, universalHandler, { store });
  }

  lookup(req: IncomingMessage, res: ServerResponse, ctx?: any, done?: Function) {
    // 使用元路由器查找并执行
    // ...实现细节
  }
}

2. Web 标准适配器(支持中间件)

class WebRouterAdapter {
  constructor(private metaRouter: MetaRouter) {}

  // 新的中间件 API
  use(path: string, middleware: MiddlewareHandler) {
    // 中间件注册逻辑
  }

  on(method: string, path: string, handler: MiddlewareHandler, options?: RouteOptions) {
    // 将中间件风格 handler 包装为 UniversalHandler
    const universalHandler = (context: RouteContext) => {
      return handler(context, () => Promise.resolve(new Response('', { status: 404 })));
    };
    
    this.metaRouter.register(method, path, universalHandler, options);
  }

  async lookup(request: Request, initialContext?: any): Promise<Response> {
    // 使用元路由器查找,构建中间件链并执行
    // ...实现细节
  }
}

包结构设计

find-my-way/
├── core/                 # 元路由核心
│   ├── meta-router.js
│   ├── radix-tree.js
│   └── constrainer.js
├── adapters/
│   ├── node.js          # Node.js 适配器
│   ├── web.js           # Web 标准适配器
│   ├── deno.js          # Deno 适配器
│   └── cloudflare.js    # Cloudflare Workers 适配器
├── index.js             # 默认导出 Node.js 适配器(兼容性)
└── web.js               # 导出 Web 适配器

使用方式:

// 现有项目(无变化)
import FindMyWay from 'find-my-way';

// Web 标准项目
import { WebRouter } from 'find-my-way/web';

// 自定义适配器
import { MetaRouter } from 'find-my-way/core';

约束系统优化

基于现有的 constrainer.jshandler-storage.js 分析:

  • 位图优化: 当前使用位图进行约束匹配,可以进一步优化
  • 编译时优化: 利用 TypeScript 编译时信息优化约束匹配
  • 策略缓存: 为常用约束策略提供缓存机制

🎯 成功标准

功能完整性:所有现有功能正常工作,通过所有单元测试,支持目标平台。

代码质量:TypeScript 严格模式无错误,完整的 API 文档,代码质量检查通过。

性能基准:Node.js 适配器保持原有性能,Web 适配器性能影响可控。

质量保证

每个提交运行类型检查、单元测试和代码质量检查。每个阶段进行 Code Review 和功能验证。

关键技术决策

分阶段策略:前三阶段保持算法兼容,第四阶段重新设计 API 以优化性能和 Web 标准兼容。

核心优势保留:Radix 树路径匹配算法、灵活的约束策略机制、高效的位图匹配算法。

重构重点:Node.js 依赖替换、测试框架迁移到 Vitest、模块系统 ESM 化、TypeScript 严格模式。

性能研究:评估中间件链对路由性能的影响、分析适配器模式的性能成本、验证现有优化算法的兼容性。

@aui aui changed the title docs: update feat: lightning router Aug 1, 2025
@aui aui changed the title feat: lightning router feat: ⚡挑战性能极限的世界级 Web 标准路由库 Aug 1, 2025
- Replace Node.js specific dependencies with platform-agnostic alternatives:
  * node:assert -> lib/assertions.js (custom implementation)
  * fast-querystring -> lib/querystring.js (custom implementation)

- Complete CJS to ESM migration:
  * Convert all source files from CommonJS to ESM
  * Update all import/export statements
  * Fix directory imports to use explicit file paths
  * Add .js extensions to all imports

- Update package.json:
  * Add 'type: module' for ESM support
  * Keep original 2-space indentation format
  * Add new scripts for formatting and linting

- Fix benchmark files for ESM compatibility:
  * Replace __dirname with import.meta.url
  * Fix CommonJS module imports (benchmark, chalk, inquirer)
  * Update directory imports to explicit paths

- All tests pass (483/483) with 100% success rate
- All benchmark tests work correctly
- Maintain existing code style and formatting standards

This completes RFC Phase 1.3 - Dependency Cleanup requirements.
@changeset-bot
Copy link

changeset-bot bot commented Aug 1, 2025

⚠️ No Changeset found

Latest commit: b8908b0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@aui aui changed the title feat: ⚡挑战性能极限的世界级 Web 标准路由库 feat: ⚡重构世界上最快的路由库 Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant