发布于 2026-01-06 0 阅读
0

JStack + Appwrite:现代 Web 开发的绝配!DEV 的全球展示挑战赛由 Mux 呈现:展示你的项目!

JStack + Appwrite:现代 Web 开发的完美组合

由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!

如果每次有 YouTuber 发布自己的技术栈我都能得到一分钱,那我总共也就两分钱,虽然不多,但奇怪的是这种情况发生了两次。

我指的是大家喜爱的Theo之前推出的T3 Stack ,但最近市场上出现了一个新的竞争者,名为JStack,由Upstash的首席开发工程师Josh开发。公平地说,它其实也不算新,但一如既往。 我来晚了。我通常会给框架一些时间去完善,并收集社区的反馈意见,然后再进行尝试。

那么,我更喜欢 JStack 还是 T3 Stack?它与我最喜欢的后端提供商 Appwrite 的兼容性如何?它能否托管在 Appwrite Sites 上?让我们一探究竟。

入门

让我们从初始化项目开始:

bunx create-jstack-app@latest
Enter fullscreen mode Exit fullscreen mode

已选选项:

┌   jStack CLI 
◇  What will your project be called?
│  testing-jstack-appwrite
◇  Which database ORM would you like to use?
│  None
◇  Should we run 'bun install' for you?
│  Yes

Using: bun

✔ testing-jstack-appwrite scaffolded successfully!
Enter fullscreen mode Exit fullscreen mode

我们先快速运行一个开发服务器,看看它能提供什么功能:

cd cd testing-jstack-appwrite
bun dev
Enter fullscreen mode Exit fullscreen mode

JStack 登录页面

项目初始化

即使跳过 ORM 选项,该堆栈仍然会创建一个/src/server包含示例文章路由的文件夹。但它只是使用一个不会持久化的数组来模拟数据库:

// Mocked DB
interface Post {
  id: number
  name: string
}

const posts: Post[] = [
  {
    id: 1,
    name: "Hello World",
  },
]
Enter fullscreen mode Exit fullscreen mode

我们跳过了 ORM 选项,因为 Appwrite 通过其 SDK 提供了内置的模式管理功能,无需单独的 ORM 层。要开始使用,请访问https://cloud.appwrite.io设置我们的项目。

如果您是第一次使用 Appwrite,我强烈建议您查看我们的Web 入门文档

以下是快速设置指南:

  • 创建新项目 -

新项目模型(Appwrite)

  • 添加一个新的 Web 平台并选择 Next.js -

新平台屏幕(Appwrite)

  • 前往项目概览页面,获取项目 ID 和区域特定端点:

项目 ID 和端点(Appwrite)

  • .env在项目目录中创建一个新文件,并将这些值粘贴到该文件中:
NEXT_PUBLIC_APPWRITE_PROJECT_ID=686a271700323696d223
NEXT_PUBLIC_APPWRITE_ENDPOINT=https://fra.cloud.appwrite.io/v1
NEXT_PUBLIC_APP_DOMAIN=localhost # we will change it later
Enter fullscreen mode Exit fullscreen mode
  • 现在,让我们使用以下命令在项目中初始化 Appwrite SDK:
bun add appwrite
Enter fullscreen mode Exit fullscreen mode

以上介绍了如何在普通的 Next.js 项目中初始化 Appwrite。现在我们需要根据项目配置 Appwrite 数据库。在本演示中,我们将创建一个Posts集合,把 JStack 示例中使用的模拟数据库迁移到 Appwrite。

定义模式

  • 转到 Appwrite 控制台 > 数据库 > 创建数据库。我们将它命名为 ` main<database_name>`,并将其 ID 保留为 `<main>`:

创建数据库(Appwrite)

  • 同样地,创建一个集合posts并将其 ID 保存为posts
  • Appwrite 中的每个文档都已附加一个唯一的 ID,因此name目前我们只需要以下属性:

创建字符串属性(Appwrite)

  • 最后,您需要定义谁可以访问您的集合。要了解更多信息,请查看Appwrite 权限文档。现在,我们将其设置为“任何用户”:

创建权限

同步类型

好了,Appwrite 控制台的配置已经全部完成。现在让我们把它应用到项目中。我还会借助 Appwrite CLI 来加快配置速度。您可以参考安装文档了解更多安装信息。

完成后,运行:

appwrite init project

? How would you like to start? Link directory to an existing project
? Choose your organization 67610b8ee51f147ca943
? Choose your Appwrite project. [object Object]
✓ Success: Project successfully linked. Details are now stored in appwrite.json file.
Would you like to pull all resources from project you just linked? Yes
Enter fullscreen mode Exit fullscreen mode

完成后,让我们利用最后一个类型生成功能来同步我们定义的类型:

appwrite types src/types       

ℹ Info: Detected language: ts
ℹ Info: Directory: src/types does not exist, creating...
ℹ Info: Found 1 collections: posts
ℹ Info: Found 1 attributes across all collections
ℹ Info: Added types to src/types/appwrite.d.ts
✓ Success: Generated types for all the listed collections
Enter fullscreen mode Exit fullscreen mode

结果大致如下:

import { type Models } from 'appwrite';

/**
 * This file is auto-generated by the Appwrite CLI. 
 * You can regenerate it by running `appwrite types -l ts src/types`.
 */

export type Posts = Models.Document & {
  name: string;
}
Enter fullscreen mode Exit fullscreen mode

目前看来这个功能还很小,但随着项目扩展和定义更多集合,它将是一个非常有用的功能。

配置代码

最后一步是将 Appwrite 后端与我们的技术栈连接起来。为此,让我们appwrite.ts在文件夹中创建一个简单的文件src/lib

import { Client, Databases, ID } from "appwrite";

const client = new Client()
    .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
    .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!);

const databases = new Databases(client);

export { client, databases };
Enter fullscreen mode Exit fullscreen mode

现在,我们可以修改原始post-router.ts文件以使用已定义的数据库:

import { z } from "zod";
import { j, publicProcedure } from "../jstack";
import { databases } from "@/lib/appwrite";
import { type Posts } from "@/types/appwrite";
import { ID } from "appwrite";

const DATABASE_ID = "main";
const POSTS_COLLECTION_ID = "posts";

export const postRouter = j.router({
  recent: publicProcedure.query(async ({ c }) => {
    const posts = await databases.listDocuments<Posts>(
      DATABASE_ID,
      POSTS_COLLECTION_ID,
    );
    return c.superjson(posts.documents.at(-1) ?? null);
  }),

  create: publicProcedure
    .input(z.object({ name: z.string().min(1) }))
    .mutation(async ({ c, input }) => {
      const post = await databases.createDocument<Posts>(
        DATABASE_ID,
        POSTS_COLLECTION_ID,
        ID.unique(),
        {
          name: input.name,
        },
      );

      return c.superjson(post);
    }),
});
Enter fullscreen mode Exit fullscreen mode

完成!现在您的 JStack 应用程序正在使用 Appwrite 作为其后端提供程序。

测试

  • 如果开发服务器尚未启动,请运行以下命令启动它:
bun run dev
Enter fullscreen mode Exit fullscreen mode
  • 您的应用程序应该已在以下地址启动:http://localhost:3000/
  • 创建新帖子。
  • 你应该能在最近的帖子中看到它:

最新帖子图片

  • 此外,数据应该会显示在您的 Appwrite 控制台中:

Appwrite 控制台显示数据

部署您的应用程序

直到最近,部署 Next.js 应用的选择还非常有限。但现在情况不同了,Appwrite Sites让这一切成为可能。现在,您可以将后端和前端都托管在 Appwrite 上。

请查看以下文档,了解如何开始使用 Sites 功能 - https://appwrite.io/docs/advanced/self-hosting/sites

让我们使用 Sites 部署您的应用程序:

  • 转到 Appwrite 控制台 > 站点 > 创建站点。
  • 您可以直接上传 tar 文件,或者连接到 GitHub 存储库(我更喜欢使用 GitHub 选项进行自动部署)。
  • 选择存储库:

选择存储库屏幕

  • 您可以保留所有默认设置,只需确保上传我们之前定义的环境变量即可:

添加环境变量屏幕

  • 根据您被分配/计划使用的领域,您还需要更新APP_DOMAIN我们之前定义的变量。对我来说,我会保留它:
NEXT_PUBLIC_APP_DOMAIN=jstack-appwrite-template.appwrite.network
Enter fullscreen mode Exit fullscreen mode
  • 点击部署。

搞定!您的申请应该已经生效了🎉

部署成功截图

您可以在这里查看演示应用程序 - https://jstack-appwrite-template.appwrite.network/

结论

让我们先来回答博客开头提出的问题:我更喜欢 JStack 还是 T3 Stack?抱歉了,Theo,但我确实更喜欢 JStack。

JStack解决了我在使用Next.js时遇到的根本问题:

T3 Stack 和 JStack 最显著的区别在于它们的轻量级,这主要归功于 T3 Stack 内置了 tRPC 协议。虽然 JStack 也使用了 tRPC,但它的实现方式似乎要简单得多。大多数项目并不需要 tRPC 带来的复杂性,而且在我看来,它反而会使代码的维护难度增加十倍。

所以,如果你正在启动一个新项目(或者想花一个周末将现有技术栈迁移到 JStack),不妨试试 JStack。特别感谢Josh创建了这个出色的技术栈。最后,也请尝试一下 Appwrite,它或许能成为你下一个一体化的云平台,满足你的后端和前端需求。

资料来源:

文章来源:https://dev.to/chiragagg5k/jstack-appwrite-a-match-made-in-heaven-for-modern-web-development-1cln