字节笔记本

2026年3月22日

Dart Edge - 在边缘运行 Dart/Flutter 服务端

本文介绍 dart_edge,一个将 Dart 代码运行在边缘函数运行时的实验性项目,支持 Vercel、Cloudflare Workers 及 Supabase Edge Functions 等平台。

项目简介

dart_edge 是由 Invertase 团队(FlutterFire 的维护者)发起的一个实验性开源项目,目标是在边缘计算平台上运行 Dart 代码。在传统的 Dart 后端开发中,开发者通常使用 Shelf、ServerPod 或 Dart Frog 等框架,将应用部署到 Google Cloud Run、AWS 等容器化服务上。而 dart_edge 提供了一种全新的思路:将 Dart 代码编译为 JavaScript,部署到全球分布的边缘网络中。

项目目前支持 Cloudflare Workers、Vercel Edge Functions 和 Supabase Edge Functions,未来计划扩展到更多平台如 Netlify Edge、Deno Deploy、AWS Lambda@Edge 等。对于已经熟悉 Dart/Flutter 生态的开发者来说,dart_edge 打开了前后端代码共享和统一技术栈的大门。

核心特性

多平台边缘部署支持

dart_edge 当前支持以下边缘计算平台:

  • Cloudflare Workers:全球 300+ 数据中心,提供低延迟响应
  • Vercel Edge Functions:与 Vercel 生态深度集成
  • Vercel Serverless Functions:传统无服务器函数支持
  • Supabase Edge Functions:基于 Deno 运行时的边缘函数

团队还在积极评估 Netlify Edge、Deno Deploy、AWS Lambda@Edge 等平台的支持计划。

低延迟边缘计算

边缘函数运行在距离用户最近的节点上,相比传统的区域化部署(如单一 AWS 区域),能够显著降低请求延迟。这对于需要快速响应的 API、动态内容渲染等场景尤为关键。

极快的代码启动时间

与传统的无服务器函数(Lambda 等)相比,边缘函数的代码启动时间极短。这意味着冷启动时间大幅减少,用户请求能够更快地得到响应。

平台特定 API 访问

边缘函数运行时提供了丰富的平台特定 API,例如:

  • Cloudflare Workers:HTMLRewriter、KV 存储、Durable Objects、R2 存储等
  • Vercel:Edge Config、增量静态再生等

V8 运行时 API

边缘函数运行在 JavaScript V8 引擎上,提供了标准 Web API 的子集,包括 Cache、Crypto、Fetch、Request、Response、Headers、URL 等熟悉的接口。dart_edge 为这些 API 提供了完整的 Dart 绑定。

兼容 Shelf 生态

dart_edge 与 Dart 社区广泛使用的 Shelf Web 框架深度集成。开发者可以使用熟悉的 shelf_router、中间件管道等方式编写代码,然后无缝部署到边缘平台。这大大降低了学习和迁移成本。

前后端代码共享

由于整个技术栈统一为 Dart,开发者可以在 Flutter 前端和边缘函数后端之间共享数据模型、验证逻辑、工具函数等代码,实现真正的全栈 Dart 开发。

技术栈

  • 编程语言:Dart(编译为 JavaScript 部署)
  • 运行时:JavaScript V8 引擎(边缘平台)
  • Web 框架集成:Shelf / Shelf Router
  • 支持平台:Cloudflare Workers、Vercel Edge Functions、Supabase Edge Functions
  • 维护团队:Invertase(FlutterFire 官方维护者)
  • 开源协议:BSD-3-Clause
  • 项目状态:实验性(Experimental)

安装指南

前置要求

  • Dart SDK(建议使用最新稳定版)
  • Flutter SDK(如需与 Flutter 项目集成)
  • 对应平台的 CLI 工具(Wrangler for Cloudflare、Vercel CLI for Vercel)

添加依赖

在 Dart 项目的 pubspec.yaml 中添加对应平台的依赖:

Cloudflare Workers:

yaml
dependencies:
  cloudflare_workers: ^1.0.0

Vercel Edge Functions:

yaml
dependencies:
  vercel_edge: ^1.0.0

Vercel Serverless Functions:

yaml
dependencies:
  vercel_serverless: ^1.0.0

Supabase Edge Functions:

yaml
dependencies:
  supabase_functions: ^1.0.0

所有平台共享核心运行时包 dart_edge: ^1.0.0。添加依赖后运行 dart pub get

快速开始

Cloudflare Workers 示例

创建项目并编写 Worker 代码:

dart
// bin/worker.dart
import 'package:cloudflare_workers/cloudflare_workers.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf.dart';

void main() {
  CloudflareWorkers(fetch: (request) async {
    final app = Router();
    app.get('/hello', (request) async {
      return Response.ok('Hello from the Edge!');
    });
    app.get('/user/<id>', (request, String id) async {
      return Response.ok('Welcome, user $id');
    });
    final handler = const Pipeline()
        .addMiddleware(logRequests())
        .addHandler(app);
    return handler(request);
  });
}

创建 build.yaml 指定入口点:

yaml
targets:
  $default:
    builders:
      cloudflare_workers_builder:
        options:
          entrypoint: bin/worker.dart

构建并部署:

bash
dart run build_runner build
wrangler deploy

Vercel Edge Functions 示例

编写 API 函数:

dart
// api/index.dart
import 'package:vercel_edge/vercel_edge_shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf.dart';

void main() {
  VercelEdgeShelf(
    fetch: (request) async {
      final app = Router();
      app.get('/api/hello', (request) async {
        return Response.ok('Hello from Vercel Edge!');
      });
      app.get('/api/user/<id>', (request, String id) async {
        return Response.ok('{"id": "$id"}',
            headers: {'Content-Type': 'application/json'});
      });
      final handler = const Pipeline()
          .addMiddleware(logRequests())
          .addHandler(app);
      return handler(request);
    },
  );
}

创建 api/build.yaml 并配置 vercel.json

json
{
  "builds": [
    {"src": "api/index.dart", "use": "@vercel/edge"}
  ]
}

构建并部署:

bash
dart run build_runner build --delete-conflicting-outputs
vercel

使用示例

示例一:使用平台特定 API

在 Cloudflare Workers 上访问 KV 存储:

dart
import 'package:cloudflare_workers/cloudflare_workers.dart';

void main() {
  CloudflareWorkers(fetch: (request) async {
    final kv = env['MY_KV_NAMESPACE'] as KvNamespace;
    final value = await kv.get('my-key');
    return Response.ok('Value: $value');
  });
}

示例二:Fetch API 代理请求

dart
import 'package:cloudflare_workers/cloudflare_workers.dart';

void main() {
  CloudflareWorkers(fetch: (request) async {
    final response = await fetch('https://api.example.com/data');
    return Response.json(
      await response.json(),
      headers: {'Access-Control-Allow-Origin': '*'},
    );
  });
}

示例三:结合 Flutter 共享数据模型

dart
// shared/models/user.dart (前后端共享)
class User {
  final String id;
  final String name;
  final String email;
  User({required this.id, required this.name, required this.email});
  Map<String, dynamic> toJson() =>
      {'id': id, 'name': name, 'email': email};
}

// edge_worker/bin/worker.dart (边缘函数使用)
import 'package:cloudflare_workers/cloudflare_workers.dart';
import 'package:my_app/shared/models/user.dart';

void main() {
  CloudflareWorkers(fetch: (request) async {
    final user = User(id: '123', name: 'Dart Developer', email: 'dev@example.com');
    return Response.json(user.toJson());
  });
}

边缘函数的局限性

在使用 dart_edge 之前,需要了解边缘函数与容器化部署的差异:

特性容器化部署边缘函数
生命周期长期运行的进程每次请求独立调用
文件系统访问支持不支持
长连接支持 WebSocket 等部分平台有限制
数据库连接持久连接每次请求需重新建立
部署速度较慢极快
冷启动较长极短

dart_edge 更适合处理无状态的计算密集型任务、API 路由、数据转换等场景,而不适合需要文件系统或持久连接的应用。

项目链接

分享: