【前端分享】Node.js 后端与前端全栈开发趋势!

Node.js 后端与前端全栈开发趋势

1. 问题概述

全栈开发正在成为前端开发者的主流方向。Next.js、Nuxt、Remix、Astro 等框架模糊了前后端边界,Node.js 运行时也在快速发展(Bun、Deno 等)。了解全栈开发的最新趋势对前端开发者至关重要。

2. 全栈框架格局

2.1 Next.js(React)

复制代码
// 同一项目中编写前后端代码
// app/api/posts/route.ts
exportasyncfunctionGET() {
const posts = await db.post.findMany()
returnResponse.json(posts)
}

// app/posts/page.tsx
asyncfunctionPostsPage() {
const posts = awaitfetch('/api/posts').then(r => r.json())
return posts.map(p =><PostCard key={p.id} post={p} />)
}

2.2 Nuxt 4(Vue)

复制代码
<!-- server/api/posts.ts -->
export default defineEventHandler(async () => {
  return await db.post.findMany()
})

2.3 Remix(React Router 生态)

复制代码
export async function loader() {
  return json(await db.post.findMany())
}

export default function Posts() {
  const posts = useLoaderData<typeof loader>()
}

2.4 Astro(内容型网站)

复制代码
---
// 服务端代码
const posts = await Astro.db.find('posts')
---
<ul>
  {posts.map(post => <li>{post.title}</li>)}
</ul>

2.5 SvelteKit(Svelte)

复制代码
// +page.server.ts
export async function load() {
  return { posts: await db.post.findMany() }
}

3. 运行时选择

运行时 特点 包管理 适用场景
Node.js 最成熟稳定 npm/pnpm/yarn 通用
Bun 极快、All-in-one bun 开发/简单服务
Deno 安全优先、TS 原生 deno 安全敏感项目
WinterJS Wasm 兼容 - 边缘计算

4. 数据库与 ORM

4.1 Prisma

复制代码
// schema.prisma
model Post {
  id      Int     @id @default(autoincrement())
  title   String
  content String?
}

4.2 Drizzle ORM

复制代码
// 零运行时、类型安全、SQL-like
const posts = await db
  .select()
  .from(postsTable)
  .where(eq(postsTable.status, 'published'))

4.3 对比

ORM 特点 性能 学习曲线
Prisma DX 极佳、迁移工具好 中 低
Drizzle 零运行时、接近 SQL 高 中
Kysely 类型安全 SQL 构建器 高 中高

5. 部署平台

平台 特点 免费额度
Vercel Next.js 原生、边缘函数 慷慨
Cloudflare Workers 边缘计算、全球分布 慷慨
Railway 简单部署、数据库内置 有限
Fly.io 全球边缘部署 有限
自建 VPS 完全控制 按需

6. 全栈开发趋势

  1. Server Actions 普及:表单处理直接在组件中,无需 API 路由

  2. 边缘计算增长:边缘数据库(如 Turso、Neon、PlanetScale)让数据更贴近用户

  3. RSC 改变架构:服务端组件成为主流,减少客户端 JS

  4. TypeScript 端到端:前后端类型共享,tRPC/Zod 实现全链路类型安全

  5. Bun 生态成熟:替代 Node.js 的潜力,内置打包、测试、包管理

  6. Rust 工具链渗透:SWC、Rspack、Oxc 等 Rust 工具提升构建性能

7. 端到端类型安全实战

7.1 tRPC 模式

复制代码
// server/trpc.ts
import { initTRPC } from'@trpc/server';
import { z } from'zod';

const t = initTRPC.create();

exportconst appRouter = t.router({
posts: {
    list: t.procedure.query(() => db.post.findMany()),
    byId: t.procedure.input(z.string()).query(({ input }) =>
      db.post.findUnique({ where: { id: input } })
    ),
    create: t.procedure
      .input(z.object({ title: z.string().min(3), content: z.string() }))
      .mutation(({ input }) => db.post.create({ data: input })),
  },
});

exporttypeAppRouter = typeof appRouter;

// app/posts/page.tsx - 前端使用
'use client';
import { trpc } from'@/lib/trpc';

functionPostList() {
const { data, isLoading } = trpc.posts.list.useQuery();
const createPost = trpc.posts.create.useMutation({
    onSuccess: () => {
      // 自动刷新列表
    },
  });

if (isLoading) return<div>Loading...</div>;

return (
    <div>
      {data?.map(post => <PostCard key={post.id} post={post} />)}
    </div>
  );
}

7.2 共享类型定义

复制代码
// shared/types.ts - 前后端共享
exportinterfacePost {
id: string;
title: string;
content: string;
createdAt: Date;
author: User;
}

// 后端直接使用
importtype { Post } from'@/shared/types';
asyncfunctiongetPost(id: string): Promise<Post> { ... }

// 前端也使用同一类型
importtype { Post } from'@/shared/types';
const [post, setPost] = useState<Post | null>(null);

8. 认证与授权方案

8.1 NextAuth.js / Auth.js

复制代码
// app/api/auth/[...nextauth]/route.ts
importNextAuthfrom'next-auth';
importGitHubfrom'next-auth/providers/github';
importGooglefrom'next-auth/providers/google';

exportconst { handlers, auth, signIn, signOut } = NextAuth({
providers: [GitHub, Google],
callbacks: {
    asyncsession({ session, token }) {
      // 扩展 session 信息
      session.user.id = token.sub!;
      return session;
    },
  },
});

// Server Component 中获取会话
import { auth } from'@/auth';

exportdefaultasyncfunctionDashboard() {
const session = awaitauth();
if (!session) return<div>请先登录</div>;

return<div>欢迎, {session.user?.name}</div>;
}

8.2 中间件保护

复制代码
// middleware.ts
export { auth as middleware } from '@/auth';

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*'],
};

9. 数据库与 ORM 深入

9.1 Drizzle ORM 实战

复制代码
// db/schema.ts
import { pgTable, serial, text, timestamp, integer } from'drizzle-orm/pg-core';

exportconst posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: text('title').notNull(),
content: text('content'),
authorId: integer('author_id').references(() => users.id),
createdAt: timestamp('created_at').defaultNow(),
updatedAt: timestamp('updated_at').defaultNow(),
});

exportconst users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
email: text('email').unique().notNull(),
});

// db/queries.ts
import { db } from'./index';
import { posts, users } from'./schema';
import { eq, desc, and } from'drizzle-orm';

exportasyncfunctiongetRecentPosts(limit = 10) {
return db
    .select({
      id: posts.id,
      title: posts.title,
      authorName: users.name,
      createdAt: posts.createdAt,
    })
    .from(posts)
    .leftJoin(users, eq(posts.authorId, users.id))
    .orderBy(desc(posts.createdAt))
    .limit(limit);
}

10. 部署与运维

10.1 Docker 化

复制代码
# Dockerfile
FROM node:20-alpine AS base
WORKDIR /app

FROM base AS deps
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

FROM base AS builder
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN pnpm build

FROM base AS runner
ENV NODE_ENV production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE3000
CMD ["node", "server.js"]

10.2 环境变量管理

复制代码
# .env.local(不提交到 Git)
DATABASE_URL="postgresql://localhost:5432/mydb"
AUTH_SECRET="your-secret-key"

# .env.example(提交到 Git,作为模板)
DATABASE_URL="postgresql://localhost:5432/mydb"
AUTH_SECRET="generate-a-random-secret"

11. 参考资源

  • Next.js 文档:

  • Astro 文档

  • Bun 官方

  • Drizzle ORM 文档