Vinetx初探之订阅管理系统subflare的开发

前言

前段时间, Cloudflare的工程师借助Claude和OpenCode花了$1,100 开发出了Vinext. 在此之前Next.js都是与Vercel之家的Turbopack高度绑定的, 有了Vinext之后就可以用Vite来构建Next.js应用了. Cloudflare关于vinext的相关博文: https://blog.cloudflare.com/vinext/ !!! 目前vinext仍处于早期阶段, 不推荐生产环境使用并且本文中的一些内容在你看到时可能已经过时.

创建项目

目前vinext没有提供初始化项目的脚手架, 但是提供了从Next.js项目迁移到vinext的agent skill, 所以目前建议是使用next-app来创建一个标准的Next.js项目, 然后在vibe coding 工具里使用skill迁移.

pnpm create next-app@latest my-app --yes
npx skills add cloudflare/vinext

然后在Claude code/codex 中告诉ai:

migrate this project to vinext

与Cloudflare 集成

通过上一步AI做的迁移后, 已经可以通过vinext dev 或者 vinext start 脚本将服务跑在标准Node.js环境中了, 但是如果要部署到Cloudflare worker并且使用Cloudflare KV, D1等平台集成的功能的话还需要做点额外的配置

1. 安装cloudflare/vite-plugin 和 wrangler 依赖

pnpm add -D vite @cloudflare/vite-plugin wrangler

2. 编辑 vite.config.ts

import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
  plugins: [
    vinext(),
    // 加入这个
    cloudflare({
      viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
    }),
  ],
});

3. 编辑wrangler.jsonc

修改main字段定义worker的入口:

"main": "vinext/server/app-router-entry",

定义要用到的binding(以d1数据库为例子):

"d1_databases": [
    {
            "binding": "DB",
        "database_id": "<your_d1_id>",
    }
],

4. 在代码里使用KV, D1等binding

参考: https://github.com/cloudflare/vinext/issues/195

import { env } from "cloudflare:workers";

export default async function Page() {
  const result = await env.DB.prepare("SELECT * FROM posts").all();
  return <div>{JSON.stringify(result)}</div>;
}

5. 特殊情况,比如使用cron trigger, 需要自定义worker入口

vinext的博客和项目主页目前都没有写如何使用worker的cron trigger, 于是翻了下兄弟项目opennext的文档, 在里面找到了需要自定义worker入口: i. 在项目内的任意位置定义一个worker.ts

// worker/worker.ts
import { runCron } from "@/lib/cron";
import handler from "vinext/server/app-router-entry";

export default {
    fetch: handler.fetch,
    // 定时任务
    async scheduled() {
        await runCron();
    },
};

ii. 修改wrangler.jsonc里的main字段为入口文件路径:

"main": "worker/worker.ts",
可以在Cloudflare面板里查看cron事件的运行情况:
vinext目前官方没有很详细的文档, 更多的使用案例可以参考官方仓库的examples: https://github.com/cloudflare/vinext/tree/main/examples

成果

本着学习Next.js的目的, 试着用Next.js实现了 SubsTracker 这个项目里的功能, 并能通过vinext部署到Cloudflare. 新项目命名为subflare, 项目开源地址: https://github.com/Merack/subflare-vinext, 可以点击下面的按钮一键部署: Deploy to Cloudflare实际上我还写了个基于Opennext的版本, 但是它的getCloudflareContext 函数貌似有点问题, 导致cron任务获取DB时会报错, 折腾了好久都不行就暂时把仓库private了, 等后续Opennext修复了再open出来 最后展示一下使用vinext构建的, 跑在Cloudflare worker上订阅管理系统的一些截图:

后记

Cloudflare的博客里介绍说vinext基本上是vibe coding出来的, 工程师甚至没有完整review过里面的代码但是用ai生成了很多测试来确保功能正常. 我实际使用起来感觉vinext对于Next.js 16的支持甚至比老牌的Next.js适配项目opennext更好, 比如在Next.js 16中官方已将middleware.ts重命名为了proxy.ts, 在vinext中用新的写法运行正常但在opennext中却不支持,要换回middleware.ts才能通过(至少现在是这样); 除此之外opennext获取worker环境binding的函数getCloudflareContext()在某些情况下也有问题,个人使用下来感觉vinext好像更好一点.