Primate 是最后一个伟大的 Web 框架
我是 Primate 的创造者,所以请以适当的态度看待这个标题。所说的“伟大的 Web 框架”,我指的是一个特定的东西:一个拥有整个栈的工具。路由、渲染、数据、验证、会话、部署目标、运行时支持。各个部分应该设计得相互契合。我是在使用 PHP 框架的过程中成长起来的:主要是 Yii,偶尔使用 Laravel。我喜欢它们的原因并不是 PHP 本身,而是这种框架拥有整个栈的感觉。数据库、模板、路由、验证、像 MVC 这样的模式。你可以在一个连贯的系统内交换各个部分。你可以访问框架的网站,查看官方支持的内容。你知道哪些是熟悉的领域,哪些是超出地图的地方。随着 JavaScript 移向服务器,这种想法大多消失了。JavaScript 生态系统强烈倾向于组合而非凝聚。你选择一个服务器框架,然后选择一个数据库客户端,再选择验证、会话、前端、构建工具,最后把它们拼接在一起。每个部分可能都很优秀,但没有人拥有这些缝合的地方。UNIX 纯粹主义者可能会说这就是正确的模型:每个工具都应该做好一件事。但 Web 应用不仅仅是孤立工具的管道。它们充满了共享的假设:请求形状、验证边界、会话处理、渲染、路由、序列化、部署目标。实际上,事情往往在那些工具交接的地方以微妙的方式失败。元框架改善了这种情况,但只是通过束缚整个世界。Next 给你一个连贯的架构,但它是一个 React 架构。如果你发现了 Solid 并想尝试,它并不是简单地切换视图层。你需要转向一个具有不同习惯、不同路由细节和不同后端假设的不同元框架。这个模式在生态系统中反复出现:文件系统路由加上一个特定的前端,一遍又一遍地重建。React 有一个元框架。Solid 有另一个。Svelte 有另一个。Vue 有另一个。每个框架解决的主要是相同的后端问题,但以稍微不同的方式,你每次都需要重新学习。运行时分裂使情况变得更糟。Node、Deno 和 Bun 都是强大的 JavaScript 运行时,但某些框架现在实际上是特定于运行时的。这意味着你的应用不仅可能与前端绑定,还可能与运行时绑定。当框架表示它“支持” Deno 或 Bun 时,通常只是意味着该运行时足够兼容以运行 Node 代码。这并不一定意味着该框架设计用于使用每个运行时自己的 API 和执行模型。没有理由这样。前端是描述浏览器 UI 的方式。后端是处理请求、数据和应用逻辑的方式。运行时是执行目标。这些东西应该允许独立变化。你应该能够使用 React 编写一个路由,使用 Svelte 编写另一个路由,使用 Marko 编写另一个,并保持相同的后端模型。你应该能够用 TypeScript、Go、Ruby 或 Python 编写后端路由,并将它们组合在一个应用中。你应该能够在 Node、Deno 或 Bun 上运行相同的应用,而不需要更改一行代码或使用特定于运行时的包来弥合差距。框架还应该提供对验证、数据库存储、会话、国际化、路由和渲染的官方支持。这就是 Primate 的构建目标。Primate 是一个不属于一个前端、一个后端语言或一个运行时的 Web 框架。它为你提供一个应用模型,然后让你在每个路由中选择相应的组件。在 React 有意义的地方使用 React。在 Svelte 感觉更好的地方使用 Svelte。为大多数路由使用 TypeScript,但在其生态系统或运行时特性更适合的地方使用 Go、Ruby 或 Python。今天在 Node 上运行,明天在 Deno 上,稍后在 Bun 上。Primate 不是炒作。它不是基准表演。重点不在于新颖性。重点在于消除耦合、锁定和其他人为决策。当你需要时,你仍然可以超出官方栈,但当你停留在栈内时,缝合的地方是 Primate 的责任。一个 Web 框架应该拥有堆栈,而不应拥有你的选择。一个小例子 这里有一个小型应用,已经展示了这一点:一个后端模型,多个前端,没有框架切换。创建一个项目:mkdir primate-demo cd primate-demo npm init -y --init-type=module npm install primate @primate/react @primate/svelte react react-dom svelte 配置前端:// config/app.ts import react from "@primate/react" ; import svelte from "@primate/svelte" ; import config from "primate/config" ; export default config ({ modules: [ react (), svelte (), ], }); 创建一个 React 路由和相关页面:// routes/index.ts import response from "primate/response" ; import route from "primate/route" ; export default route ({ get () { return response. page ({ title: "One app" , links: [ { href: "/react" , label: "React route" }, { href: "/svelte" , label: "Svelte route" }, ], }); }, });
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡