Next.js 风格路由内置?Bun FileSystemRouter 凭啥这么香

bash 复制代码
// pages/index.ts
export default () => new Response("首页");
bash 复制代码
// server.ts
import { FileSystemRouter } from "bun";
const r = new FileSystemRouter({ dir: "./pages" });
Bun.serve({
  fetch: async (req) => {
    const m = r.match(req);
    return m ? (await import(m.filePath)).default(req, m) : new Response("404");
  },
});

bun run server.ts 就跑起来了。访问 / 返回"首页"。再加个 pages/about.ts/about 就有了。文件名,就是路由。

痛点:手写路由表,写了十几年

写电商、写 OA、写 CRM。php、java、js、nodejs、bunjs、ts、python,全用过。

每个项目,第一件事就是写路由表:

bash 复制代码
// express
app.get("/", home);
app.get("/user/:id", user);
app.post("/user", createUser);
app.use("/api", apiRouter);

几十个路由,加一个写一行。改路径名,全局搜替换。拼错一个字母,线上 404。

Next.js 出来后,省事了。pages/about.ts 就是 /about。不用注册,不用配置。

但 Next.js 太重了。react、ssr、webpack、babel...就为个文件路由,整个全家桶拉起来。

bun 给了个轻量选项。

FileSystemRouter 是啥?

bun 内置模块,零依赖。

就是把"文件路径"映射成"URL"。

不绑定 react,不绑定 ssr。不绑定任何框架。

配合 Bun.serve 单独跑。

bash 复制代码
import { FileSystemRouter } from "bun";

const router = new FileSystemRouter({
  style: "nextjs",
  dir: "./pages",
  origin: "https://mydomain.com",
  assetPrefix: "_next/static/",
  fileExtensions: [".ts", ".tsx", ".js", ".jsx"],
});

style 固定 "nextjs",这是唯一支持的风格。dir 是扫描目录,必填。origin 用于拼 src 字段。assetPrefix 是静态资源前缀。fileExtensions 控制识别哪些后缀,默认是常见 web 后缀。

匹配规则:

  • /pages/index.ts

  • /aboutpages/about.ts

  • /user/123pages/user/[id].ts

  • /blog/a/bpages/blog/[...slug].ts

跟 Next.js 一模一样。

动态路由怎么写?

跟 Next.js 一样,方括号包参数。

目录:

bash 复制代码
pages/
  index.ts
  user/
    [id].ts
  blog/
    [...slug].ts

[id].ts 是单个参数。[...slug].ts 是通配,吃多级路径。

代码:

bash 复制代码
// pages/user/[id].ts
export default (_req, params) => {
  return Response.json({
    id: params.id,
    name: `用户${params.id}`,
  });
};

params.id 直接拿到 123

通配:

bash 复制代码
// pages/blog/[...slug].ts
export default (_req, params) => {
  return Response.json({
    slug: params.slug, // "a/b/c"
  });
};

/blog/a/b/cparams.slug 就是 "a/b/c"

可选通配(双层方括号):

bash 复制代码
// pages/[[...slug]].ts
export default (_req, params) => {
  return Response.json({
    slug: params.slug ?? "", // 没匹配上时是 undefined
  });
};

/foo/bar 走它,/ 也走它。

新增文件要 reload

路由是在初始化时扫一次。后面加文件、改文件名,必须手动 reload:

bash 复制代码
import { FileSystemRouter } from "bun";

const router = new FileSystemRouter({
  style: "nextjs",
  dir: "./pages",
});

// 加了 pages/new.ts 后,调一下:
router.reload();

Bun.serve({
  fetch: async (req) => {
    const m = router.match(req);
    return m ? (await import(m.filePath)).default(req, m) : new Response("404");
  },
});

自己写个文件 watcher 监听 pages 目录,调 reload() 就行。

完整跑起来

目录结构:

bash 复制代码
api/
  index.ts
  user/
    [id].ts

api/index.ts

bash 复制代码
export default () => Response.json({
  name: "api",
  version: "1.0.0",
});

api/user/[id].ts

bash 复制代码
export default (_req, params) => Response.json({
  id: params.id,
  orders: [],
});

server.ts

bash 复制代码
import { FileSystemRouter } from "bun";

const r = new FileSystemRouter({
  style: "nextjs",
  dir: "./api",
});

Bun.serve({
  port: 3000,
  fetch: async (req) => {
    const m = r.match(req);
    if (!m) return new Response("404", { status: 404 });
    const mod = await import(m.filePath);
    return mod.default(req, m);
  },
});

bun run server.ts,搞定。/api 返回版本信息。/api/user/123 返回用户信息。

零配置,零路由表。

跟 Next.js 比,差啥?

差远了。

Next.js 包含:

  • • 文件路由

  • • react ssr

  • • 静态生成

  • • 图片优化

  • • middleware

  • • api routes

  • • 完整 dev 工具链

FileSystemRouter 只有:

  • • 文件路由

就这一项。

所以别拿它当 Next.js 替代品。

正确用法:

  • • api 服务

  • • bff 层

  • • 边缘函数

  • • 小工具后台

这些场景,不需要 react。一个 bun runtime 全搞定。

启动速度差几百倍。冷启动几毫秒。next.js dev 启动几十秒。

跟 Bun.serve HTML 路由配合

Bun.serve 自己也支持 HTML 路由:

bash 复制代码
Bun.serve({
  routes: {
    "/": new Response("首页"),
    "/health": new Response("ok"),
  },
});

这是手动写死。FileSystemRouter 是扫文件。

两个能配合:

bash 复制代码
Bun.serve({
  port: 3000,
  routes: {
    "/health": new Response("ok"),
  },
  fetch: async (req) => {
    const m = router.match(req);
    if (!m) return new Response("404", { status: 404 });
    const mod = await import(m.filePath);
    return mod.default(req, m);
  },
});

固定路由走 routes。文件路由走 fetch。两个不冲突。

写代码小细节

详细参数看 bun 官方文档。

工具而已,对号入座

FileSystemRouter 不是什么银弹。就是一个文件路由的小工具。

不替代 next.js。不替代 nuxt。不替代任何前端框架。

用在合适的场景:

  • • 写个 api 服务

  • • 写个 bff 中间层

  • • 写个边缘函数

  • • 写个内部工具

启动快,配置少,文件即路由。

要 ssr、要 react、要生态链,老老实实 next.js。要轻量、要简单、要快,FileSystemRouter 够用。

工具而已,对号入座。

相关推荐
小林ixn2 小时前
别再背八股了!从 5 个真实场景彻底搞懂 JavaScript 的 this
javascript
东风破_2 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
巴勒个啦2 小时前
D3.js 入门实战:用力导向图可视化项目依赖关系
javascript
不好听6133 小时前
JavaScript 的 this 到底指向谁?
javascript·面试
触底反弹3 小时前
🔥 2026 年爆火的 Harness Engineering 到底是什么?从原理到实战一文讲透
javascript·人工智能·程序员
mONESY3 小时前
一文搞定JavaScript不同场景中 this 的指向问题
javascript
用户298698530143 小时前
在 React 中使用 JavaScript 合并 Excel 文件
前端·javascript·react.js
大流星3 小时前
LangChainJs之基础模型(一)
javascript·langchain
橘子星3 小时前
JavaScript this 指向全解实战指南
前端·javascript