
ohne 发布零依赖免构建 TypeScript Web 框架
来源标题:Show HN: Nobuild TypeScript web framework with zero dependencies
ohne 是一个零依赖、无需构建的 TypeScript Web 框架,开发者声明字段后框架自动生成管理后台,字符串、选项和关联均可按语言本地化。它借助 Node 直接剥离类型运行 .ts 文件,没有打包器和 dist 目录,并支持多层叠加、就近覆盖。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
声明你的字段。ohne 围绕这些字段生成管理后台——每个字符串、下拉选项和关联都可按语言翻译,无需任何同步维护。
当你运行代码、叠加一个层、声明一个集合,或请求另一种语言时,会发生什么。
Node 会剥离你 .ts 文件中的类型并直接运行它们。仪表盘拿到的是同样的文件,按需进行类型剥离。无需打包器,没有 dist 文件夹。
你写什么,就运行什么 常规做法会先把 app.ts 构建到 dist/ 再运行。使用 ohne 时,Node 剥离 app.ts 的类型后直接运行。常规做法app.tsbuilddist/runohneapp.tstitle: string = 'Hi'runrunNode 剥离类型 02叠加层,覆盖任何内容 一个层就是一组集合、路由和消息的打包。把你的层叠加在应用之下。越近的层优先,而你的应用优先级最高。
叠加层 三个层像纸片一样叠放:ohnejs/base 提供 Users 和 /login,@acme/blog 提供 Posts 和 /feed,而你的应用提供自己的 /login。运行时每个位置取自最近一个填充它的层,因此你的 /login 会替换掉 ohnejs/base 中的那个。你的应用@acme/blogohnejs/base/loginPosts/feedUsers/login运行时Users/loginPosts/feed越近的层优先 03集合变成表 每个集合就是一张表,而关联列表会拥有自己的链接表。无论读取两行还是两百行,开销都是同样几次查询。
集合变成表 一个带有 title 和 tags 的 Posts 集合会变成一张带有 title 列的 Posts 表,通过 Posts_tags 表关联到 Tags 表。读取帖子及其标签需要 3 次查询,每张表一次,无论 2 行还是 200 行。Posts.tstitle:field('text'),tags:field('records', {collection:'Tags',}),PoststitlePosts_tagsTagsquery('Posts').populate('tags').findMany()2 行20 行200 行3 次查询 04一条记录,所有语言 翻译字段位于记录旁边,每种语言一行。读取时会连接你请求的语言。缺失的语言读到 null,绝不猜测。
一条记录,所有语言 Posts 行把翻译保存在 Posts__translations 中,每种语言一行:en 为 Welcome,de 为 Willkommen。请求 de 读到 title 为 Willkommen。请求 bs(没有对应行)读到 title 为 null,不会静默回退。PostsslugwelcomePosts__translationsenWelcomedeWillkommen.locale('de').locale('bs') title: 'Willkommen' title: null不静默回退 你写什么,就运行什么 常规做法会先把 app.ts 构建到 dist/ 再运行。使用 ohne 时,Node 剥离 app.ts 的类型后直接运行。常规做法app.tsbuilddist/runohneapp.tstitle: string = 'Hi'runrunNode 剥离类型叠加层 三个层像纸片一样叠放:ohnejs/base 提供 Users 和 /login,@acme/blog 提供 Posts 和 /feed,而你的应用提供自己的 /login。运行时每个位置取自最近一个填充它的层,因此你的 /login 会替换掉 ohnejs/base 中的那个。你的应用@acme/blogohnejs/base/loginPosts/feedUsers/login运行时Users/loginPosts/feed越近的层优先集合变成表 一个带有 title 和 tags 的 Posts 集合会变成一张带有 title 列的 Posts 表,通过 Posts_tags 表关联到 Tags 表。读取帖子及其标签需要 3 次查询,每张表一次,无论 2 行还是 200 行。Posts.tstitle:field('text'),tags:field('records', {collection:'Tags',}),PoststitlePosts_tagsTagsquery('Posts').populate('tags').findMany()2 行20 行200 行3 次查询一条记录,所有语言 Posts 行把翻译保存在 Posts__translations 中,每种语言一行:en 为 Welcome,de 为 Willkommen。请求 de 读到 title 为 Willkommen。请求 bs(没有对应行)读到 title 为 null,不会静默回退。PostsslugwelcomePosts__translationsenWelcomedeWillkommen.locale('de').locale('bs') title: 'Willkommen' title: null不静默回退 实践 一个集合、两条路由、一个 hook 和一个仪表盘页面。每个都是约定目录中的普通 TypeScript 文件,ohne dev 会监视它们全部。 import { defineCollection, field } from 'ohnejs'; export default defineCollection({ api: true, fields: { title: field('text', { translatable: true, max: 120 }), status: field('select', { choices: ['draft', 'published'], default: 'draft' }), author: field('record', { collection: 'Users' }), body: field('text', { multiline: true }), }); 保存文件后,API 会重新加载,表也一并就位。无需迁移文件,无需 SQL,且同步会拒绝任何可能导致数据丢失的更改。api: true 会在角色检查之后,将其挂载到 /collections/posts 下提供服务。 以下所有内容都随 ohnejs 提供。叠加 ohnejs/uploads 以获得文件功能,或叠加 ohnejs/ai 以获得助手功能,也可以编写你自己的层。 集合与字段 字段类型 查询 翻译 模式同步 路由 集合 API Hooks 认证 消息 仪表盘 CLI 层 上传 助手 部署 开始使用 回答几个提示。你会得到一个已安装其唯一依赖的新项目。 启动 API 和仪表盘。打开 localhost:9000 查看。类型会重新生成,每次保存时 API 都会重新加载。 创建 collections/Posts.ts 并列出其字段。保存时,ohne 会创建表,你的查询会知道其字段,仪表盘会列出 Posts。构建你的第一个应用 ohne 的每个部分都有指南:项目、数据库、HTTP API、认证、国际化、仪表盘和生产环境。
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。