使用 React、TypeScript 和 GraphQL 构建全栈应用程序
介绍
Web 开发可能会让人不知所措。市面上有无数的库和框架,想要将各种技术拼凑起来构建一个完整的全栈 Web 应用并非易事。经过反复尝试,我找到了一套适合自己的 Web 应用开发技术栈和开发流程。希望我的分享能给你一些启发。
我们将介绍的内容
在这篇文章中,我将概述我使用的库和框架。我将解释我的项目结构,并讲解我典型的开发工作流程。我的目标是向你展示所有部分是如何组合在一起的。
我们不会涉及的内容
我不会深入讲解任何特定的技术。相反,我会提供更详细的文档和文章链接,方便您了解更多信息。如果您想全面深入地了解如何使用 React 构建全栈 Web 应用程序,我推荐您查看 Wes Bos 的“高级 React”课程。
目录
建筑学
前端
- React - 用于构建用户界面的 JavaScript 库
- Next.js - 使用 React 构建服务器渲染应用程序的框架
- Emotion - 一个使用 JavaScript 编写 CSS 样式的库
- Styled Components是使用 JavaScript 编写 CSS 样式的另一种流行选择。
- Apollo Client - JavaScript 应用程序的 GraphQL 客户端和状态管理库
- GraphQL 代码生成器- 从 GraphQL 模式生成代码
后端
- Prisma - 用于现代应用程序开发的数据库工具
- Nexus - 代码优先、类型安全、GraphQL 模式构建
- GraphQL Yoga - 功能齐全的 GraphQL 服务器
- Apollo Server是另一个流行的 GraphQL 服务器。
部署
文件夹结构
以下是我构建项目的方式:
frontend/ # Where all the frontend code lives
package.json # Manifest file with a list of package dependencies for frontend
next.config.js # Config file for Next.js
pages/ # Each file in this folder becomes a page with a URL based on its path
graphql/ # GraphQL queries and mutations
components/ # React components
lib/ # Miscellaneous utility functions
__generated__/ # Auto-generated React components and TypeScript types
backend/ # Where all the backend code lives
package.json # Manifest file with a list of package dependencies for backend
src/
index.ts # Entrypoint for the GraphQL server
schema.ts # Schema definition for GraphQL Server
__generated__/ # Auto-generate TypeScript types
prisma/ # Prisma datamodel and config files
注意:我使用Yarn Workspaces轻松管理依赖项并运行和的
frontend
脚本backend
。
工作流程
为了说明我的典型开发工作流程,让我们逐步介绍在应用程序上添加显示帖子列表的过程:
1.启动开发服务器
要开始本地开发,我们可以yarn dev
从根目录运行。
yarn dev
这将在上运行前端开发服务器localhost:3000
,并在上运行 GraphQL API 服务器localhost:4000
。
2. 更新数据模型
接下来,在中backend/prisma/datamodel.prisma
,我们需要创建一个Post
类型:
type Post {
id: ID! @id
createdAt: DateTime! @createdAt
updatedAt: DateTime! @updatedAt
author: String!
title: String!
content: String!
}
这是 Prisma 中用于定义数据模型的特殊语言。它类似于定义 GraphQL 模式的方式。
3. 部署数据模型变更
在对新的 Post 类型进行任何操作之前,我们必须部署我们的更改:
prisma deploy
这将自动运行数据库迁移并生成一个 GraphQL API,允许我们对帖子执行 CRUD 操作。它还会生成我们可以在 GraphQL API 中使用的 TypeScript 类型。
4.更新 GraphQL API
接下来,我们需要更新 GraphQL API,使前端能够显示和编辑帖子。由于 Prisma 的 GraphQL API 已经公开了帖子的 CRUD 操作,因此我们只需代理这些字段即可。以下是使用 Nexus 的操作方法:
const Query = prismaObjectType<'Query'>({
name: 'Query',
definition(t) {
t.prismaFields([
+ 'post',
+ 'posts',
])
},
})
const Mutation = prismaObjectType<'Mutation'>({
name: 'Mutation',
definition(t) {
t.prismaFields([
+ 'createPost',
+ 'updatePost',
+ 'deletePost',
])
}
})
5. 编写 GraphQL 查询
我们使用该frontend/graphql
目录来集中管理前端使用的所有查询和修改。因此,让我们getPosts.graphql
在此目录中创建一个名为 的文件,并编写一个查询来获取帖子列表:
query getPosts {
posts {
id
createdAt
title
content
}
}
6. 生成 GraphQL 类型和组件
在使用此查询之前,我们需要为其生成 React 组件和 TypeScript 类型。这时GraphQL 代码生成器就派上用场了。只需一个命令,我们就可以为.graphql
项目中的所有文件生成 React 组件和类型:
gql-gen
生成的输出将被放置在 中frontend/__generated/graphql.tsx
。
7.更新前端
在任何 React 组件中,我们现在可以导入由 GraphQL 代码生成器生成的代码并使用它来显示帖子列表:
import { GetPostsComponent } from '../__generated__/graphql'
export default function App() {
return (
<GetPostsComponent>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return (
<ul>
{data.posts.map(post => (
<li key={post.id}>{post.title}</li>
)}
</ul>
)
}}
</GetPostsComponent>
)
}
8.部署
现在,我们已经完成了显示帖子所需的所有前端和后端更改。是时候部署这些更改了。使用Now,我们只需运行一个命令:
now
现在将应用程序部署到唯一的 URL(例如my-app-f9shcvmf1.now.sh
)。
演示
如果您有兴趣在实际项目中了解此技术堆栈和工作流程,请访问https://github.com/colebemis/dasher。