Remix + Prisma + MongoDB 全栈应用开发(一):项目设置

955 阅读14分钟

欢迎阅读本系列教程的第一篇文章,在这个教程中你将了解如何使用 MongoDB、Prisma 和 Remix 从零开始构建全栈应用!在本文中,将会对你的项目、MongoDB 实例、Prisma 进行设置,并开始为本系列的下一节做数据建模。

fullstack-mongodb-1.png

介绍

该系列教程的目标是让你能深入了解如何使用下面提到的技术来启动、开发和部署应用程序,并希望通过这些工具提供的丰富功能集来强调这样做是多么容易!

到本系列结束之时,你会创建并发布一个叫做 “Kudos” 的应用,它是一个网站,用户在上面可以创建账户、登录,并可以发送 kudos 给网站的其他用户。最终它会像这样:

kudos-home-complete.png

我们用到的技术栈

在本系列中,你将会用到以下工具来构建此应用:

  • MongoDB 作为数据库
  • Prisma 作为你的对象文档映射器(ODM)
  • Remix 作为 React 框架
  • TailwindCSS 来设置样式
  • AWS S3 来存储用户上传的图片
  • Vercel 来发布应用

本系列覆盖哪些内容

你将深入了解构建此应用的各个方面,包括:

  • 数据库配置
  • 数据建模
  • 基于会话授权进行身份验证
  • 创建、查询、更新和删除(CRUD)操作,以及使用 Prisma 对数据进行过滤和排序
  • 使用 AWS S3 进行图片上传
  • 部署到 Vercel

今天你将学到什么

在首篇文章中,你将经历这些过程:启动 Remix 项目、使用 Mongo 的 Atlas 平台设置 MongoDB 数据库、安装 Prisma 以及开始为本系列下一部分进行建模。到最后,你应该有了一个坚实的基础来继续构建你应用的其余部分。

先决条件

知识准备

虽然本系列教程旨在指导你完成全栈应用的开发,但假设你已经具备以下的知识储备:

  • 在 JavaScript 生态系统中工作的经验
  • 使用 React 的经验,因为 Remix 是基于 React 构建的框架
  • 对 “无模式” 数据库概念有基础了解,尤其是 MongoDB
  • 对使用 Git 有基础了解

开发环境

为了能够跟上提供的示例,你需要

  • 已安装好 Node.js。
  • 已安装好 Git。
  • 已安装好 TailwindCSS VSCode 插件(可选)。
  • 已安装好 Prisma VSCode 插件(可选)。

提示:可选装的插件会给 Tailwind 和 Prisma 带来非常优秀的智能感知和语法高亮功能。

生成 Remix 应用

你要做的第一件事就是初始化一个 Remix 应用。Remix 是一个全栈 web 框架,能让你轻松构建整个 React 应用,而不必担心应用的基础架构。

它能让你更加关注应用程序的开发,而不是花时间分别管理技术栈的各个区域并协调它们的交互。

它还提供了一组不错的工具,你可以使用它们来完成其他繁琐的任务。

要启动 Remix 项目,请在你希望的项目所在目录运行以下命令:

npx create-remix@latest kudos

这将为你搭建一个初始项目并问你几个问题。选择以下选项,让 Remix 知道你想使用 TypeScript 创建一个空白项目,并想要部署到 Vercel 上。

  • What type of app do you want to create? Just the basics
  • Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets. Vercel
  • TypeScript or JavaScript? TypeScript
  • Do you want me to run npm install? Yes

看一下启动项目

项目设置成功后,你就可以继续操作,通过在代码编辑器中直接打开项目或者在目录终端里运行 code . 来使用 VSCode 打开它。

你可以看到生成的模版项目代码结构如下:

│── app
│   ├── entry.client.tsx
│   ├── entry.server.tsx
│   ├── root.tsx
│   └── routes
│       ├── README.md
│       └── index.tsx
├── node_modules
├── package-lock.json
├── package.json
├── public
│   └── favicon.ico
├── remix.config.js
├── remix.env.d.ts
├── server.js
├── tsconfig.json
├── README.md
└── vercel.json

对于本系列的大部分内容,你将在 app 目录中工作,该目录将包含此应用程序的所有业务代码。

./app/routes 下的所有文件都将被转换为路由。比如,假定你的应用程序运行在 localhost:3000,那么 .app/routes/index.tsx 文件将会在 localhost:3000/ 端点生成一个路由。如果你创建了另一个文件 app/routes/home.tsx,Remix 就会在你的站点生成一个 localhost:3000/home 的路由。

这就是 Remix 的神奇部分之一,它让开发变得如此简单。当然,在这个基础示例中还有很多更强大的功能。如果你感到好奇,可以查看它们关于路由功能的文档

提示:你可以在此处阅读关于 Remix 路由的更多信息。在后续的系列中,你可能也会用到其他路由功能,诸如嵌套路由资源路由

如果你使用 npm run dev 来启动该项目并前往 http://localhost:3000/,你会看到基础入门应用。

remix-starter.png

恭喜!你的基本项目已启动,Remix 已经搭建了许多你通常必须手动设置的部分,诸如路由和构建过程。现在你将前往设置 TailwindCSS,来让你的应用变得好看。

设置 TailwindCSS

TailwindCSS 提供了一组强大的基础类和函数,可以帮助你快速构建精美的用户界面,这些界面可轻松定制,以满足你的定制设计需求。你将在该应用中全程使用 TailwindCSS 来设置样式。

Tailwind 有一个很好的指南,介绍了在 Remix 项目中配置它的步骤。

在开始使用 Tailwind 之前,你需要先安装一些依赖:

npm install -D tainwindcss postcss autoprefixer concurrently

该命令将会安装以下开发依赖包:

  • tailwindcss:该命令行工具(CLI)允许你初始化 Tainwind 配置。
  • postcss:TailwindCSS 是一个 PostCSS 插件,并且依靠 PostCSS 来进行构建。
  • autoprefixer:一个 PostCSS 插件,用来给生成的 CSS 自动添加浏览器前缀。这是TailwindCSS 所必须的。
  • concurrently:它能让你的 Tailwind 构建过程和 Remix 的构建过程一起运行。

安装完成之后,你就可以在项目中初始化 Tailwind 了:

npx tailwindcss init -p

这将生成两个文件:

  • tailwind.config.js:你可以在这里调整和扩展 TailwindCSS。在此处查看所有配置项。
  • postcss.config.js:PostCSS 是一个 CSS 转译器。你可以在这里添加插件。

当运行构建时,Tailwind 会扫描代码库以确定需要将哪些基础类绑定到其生成的输出中。你需要让 Tailwind 知道哪些文件需要被监控。在 tailwind.config.js 中,将以下全局匹配模式添加到 content健:

// tailwind.config.js
module.exports = {
    content: [
+     "./app/**/*.{js,ts,jsx,tsx}",
    ],
  theme: {
    extend: {},
  },
  plugins: [],
}

这将告诉 Tailwind,应扫描 app 文件夹内具有提供的扩展名的所有文件,来查找 Tailwind 将选择的关键字和类名,并生成其输出文件。

接下来,在 package.json 中更新你的 scripts 部分,以在构建应用和运行开发服务时包含 Tailwind 的构建过程。添加以下脚本:

// package.json
{
  "scripts": {
    "build": "npm run build:css && remix build",
    "build:css": "tailwindcss -m -i ./styles/app.css -o app/styles/app.css",
    "dev": "concurrently \"npm run dev:css\" \"remix dev\"",
    "dev:css": "tailwindcss -w -i ./styles/app.css -o app/styles/app.css"
  }
}

你也许注意到了一些脚本指向了一个不存在的文件 ./styles/app.css。这将是 Tailwind 构建时的源文件,你将在其中导入 Tailwind 要用到的各种函数和指令

继续并创建 ./styles/app.css 源文件,并使用 @tailwind 指令来添加 Tailwind 的各个[层](Go ahead and create that source file at ./styles/app.css):

/* ./styles/app.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

现在,当应用程序运行或者构建时,你的 scripts 也同时会启动 Tailwind 的扫描和构建过程。结果将会被输出到 app/styles/app.css

该文件就是你将导入到 Remix 应用中的文件,有了它就可以在你的代码中使用 Tailwind。

在 app/root.tsx 中,导入已生成的样式表,并导出一个 links 函数,来让 Remix 知道当你的应用开始构建时,你有一个所有模块都需要引入的资源:

// ./app/root.tsx
// 1
import type { MetaFunction, LinksFunction } from "@remix-run/node";

// 2
import styles from './styles/app.css';

// ...

// 3
export const links: LinksFunction = () => {
  return [{ rel: 'stylesheet', href: styles }]
}

// ...

以上代码将会:

  1. 导入 Remix links 函数的类型。
  2. 导入生成的样式表。
  3. 导出一个名为 links 的函数,它遵循 Remix 采用的规范,并用于将资源导入所有模块。

提示:如果你在单独的路由文件导出一个 links 函数,而不是在 root.tsx 文件,它将仅加载在该路由上返回的资源。想要了解更多关于资源文件的导入和规范的信息,请查阅 Remix 文档

现在,我们打开 ./app/routes/index.tsx 文件,并将其内容替换为以下示例代码,以确保 Tailwind 设置正确:

// ./app/routes/index.tsx
export default function Index() {
  return (
    <div className="h-screen bg-slate-700 flex justify-center items-center">
      <h2 className="text-blue-600 font-extrabold text-5xl">TailwindCSS Is Working!</h2>
    </div>
  )
}

你应该看到如下所示的屏幕:

tailwind-css-checkpoint.png

提示:如果你没有看到 Tailwind 的样式被应用到你的页面,你可能需要重启你的开发服务。

如果看起来不错,那么意味着你已经成功配置好了 TailwindCSS,可以继续下一步,配置数据库!

创建 MongoDB 实例

在本项目中,你将使用 Prisma 和 MongoDB 数据库进行交互。在你配置 Prisma 之前,毫无疑问,你需要一个 MongoDB 实例来连接它。

你将使用 Mongo Atlas 云数据平台来设置一个 MongoDB 集群。

提示:当然,你也可以使用任何你喜欢的方式来设置一个 MongoDB 实例。但是 Atlas 能提供最简单快捷的体验。对 Prisma 来说唯一的要求是你的 MongoDB 要使用复制集来部署。

通过以上链接前往 Atlas 主页。如果你还没有账户,你需要先创建一个。

你应该在屏幕上看到几个选项。选择其中 Free项。然后点击 Create 按钮:

mongodb-free-tier.png

当你选择之后,会跳转到另一个页面,这里允许你配置将要生成的集群。对于你的应用,你可以使用默认配置。然后在页面下方点击 Create Cluster 按钮。

mongodb-default-settings.png

这将启动配置并部署你的 MongoDB 集群。现在你只需一个数据库用户和一种链接数据的方式。幸运的是,MongoDB 将在其快速入门过程中引导你完成这些设置。

你会看到一些提示来帮你完成这些设置。按照提示来创建一个新用户。

mongodb-user-setup.png

然后,在 **Where would you like to connect from?**部分,点 Add My Current IP Address 将你的开发机器的 IP 地址列入白名单,允许它链接数据库。

mongodb-ip-setup.png

在完成这些步骤几分钟后,你的数据库应该完成了它的启动过程,并准备好和你一起工作了!

设置 Prisma

现在你已经有了一个 MongoDB 数据库可连接,是时候设置 Prisma 了!

初始化并配置 Prisma

首先,你要安装 Prisma CLI 作为开发依赖包。这将让你能够运行各种 Prisma 命令。

npm i -D prisma

要在项目中初始化 Prisma,简单运行:

npx prisma init --datasource-provider mongodb

这将在你的项目中生成一些不同的文件。你会看到一个 prisma 文件夹,里面有 schema.prisma 文件。这就是你定义你的 schema 和数据建模的地方。

同样的它也会自动生成一个包含简单环境变量的 .env 文件(如果之前不存在的话),它将保存你的数据库连接字符串。

如果你打开 ./prisma/schema.prisma,你应该看到 Prisma schema 的默认初始模版。

// ./prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

提示:该文件是用 PSL(Prisma Schema Language)写的,它允许你映射你的 schema。要了解更多关于 Prisma schemas 和 PSL 的信心,请查阅 Prisma 文档

datasource 区域的 url 一项,它使用 PSL 提供的 env() 函数,从 .env 文件中引用了DATABASE_URL 环境变量。Prisma 在后台使用 dotenv 将这些变量暴露给 Prisma。

设置你的环境变量

现在你将在环境变量中为 Prisma 提供正确的连接字符串,以便它能够连接到数据库。

要在 Atlas 仪表盘上找到你的连接字符串,请点击 Connect 按钮。

mongodb-connection-button.png

这会弹出一个弹窗。点击 Connect your application 选项。

mongodb-connection-modal.png

这里应该会展示一些信息。你需要关心的部分是连接字符串。

mongodb-connection-string.png

在你的 .env 文件中,用你的 MongoDB 连接字符串替换默认的连接字符串。该字符串应该是如下格式:

mongodb+srv://USERNAME:PASSWORD@HOST:PORT/DATABASE

在你粘贴完连接字符串并修改为以上格式之后,你的字符串应该看起来像这样:

mongodb+srv://sadams:<password>@cluster0.vv1we.mongodb.net/kudos?retryWrites=true&w=majority

提示:注意 kudos 是数据库名字。你可以在这为你的数据库放任何你想要的名字。MongoDB 会自动创建一个新的数据库,如果他不存在的话。

要了解更多关于连接 MongoDB 数据库的细节,请查阅此文档

数据建模

现在你可以开始考虑数据建模,开始为你的数据库映射集合。请注意,在本文中你不会对整个数据集进行建模。相反,你将在整个系列中迭代地构建 Prisma schema。

对于本节,我们先创建一个用户模型,你将在本系列的下一节中使用它来处理身份验证。

prisma/prisma.schema 里,添加一个名为 User 的新模型。这就是你定义用户在数据库中结构的地方。

// ./prisma/schema.prisma
model User {

}

提示:MongoDB 是一个为灵活构建数据而生的无模式数据库,因此为存储在其中的数据定义“schema”似乎违反直觉。然而,随着无模式数据库的数据增长和时间推移,问题就会出现,要追踪到哪些数据存在于何处,同时还要考虑遗留数据的形态,会变得越来越难。因此,从长远来看,定义schema 可能会省去一些麻烦。

每个 Prisma 模型都需要一个唯一的 id 字段。

// ./prisma/schema.prisma
model User {
  id String @id @default(auto()) @map("_id") @db.ObjectId
}

以上代码将会创建一个 id 字段,并通过 @id 属性让 Prisma 知道这是一个唯一表示。因为 MongoDB 会为所有数据集自动创建一个 _id 字段,所以你要通过使用 @map 属性让 Prisma 知道,你在 schema 中定义的 id 字段,它应该映射到数据库的 _id 字段上。

该代码同时也为你定义好了 id 字段的数据类型,并设置默认值为 auto(),这将允许你使用 MongoDB 自动生成的唯一 ID。

提示:当你使用 Prisma 和 MongoDB 时,所有模型必须有一个唯一标识字段,它必须要完全像这样去定义以正确映射到 MongoDB 生成的 _id 字段。在该字段的定义中,你的 schema 中唯一可能有所不同的部分就是你为映射到底层 _id 字段的字段起的名。

现在你已经有了 id 字段,接着继续为 User 模型添加一些其他有用的数据。

// ./prisma/schema.prisma
model User {
  id        String   @id @default(auto()) @map("_id") @db.ObjectId
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  email     String   @unique
  password  String
}

如上所见,你将添加两个 DateTime 类型的字段,来记录用户创建时间和更新时间。每当用户更新时,@updatedAt 属性将使用当前时间戳自动更新该字段。

它还将添加一个类型为 Stringemail 字段,该字段必须唯一,由 @unique 属性指示。这意味着没有其他用户可以拥有相同的邮件。

最后,你将拥有一个密码字段,它只是一个纯字符串。

这就是目前你的 User 模型所需的所有字段!你可以现在就把 schema 推送到 MongoDB,然后你就可以看到它创建的数据集了。

推送 shcema 变更

对我们的 schema 进行更改后,你可以运行以下命令:

npx prisma db push

这将把你的 schema 变更推送到 MongoDB,创建一些新的数据集或者你定义的索引。比如,当你按原样推送 schema 时,你应该在输出中看到以下内容:

Applying the following changes:

[+] Collection `User`
[+] Unique index `User_email_key` on ({"email":1})

因为 MongoDB 是无模式的,所以没有真正意义上的迁移。无模式数据库的数据可以随着应用程序范围的扩大和变化而流畅地变化和发展。此命令只是创建定义好的数据集和索引。

user-collection.png

总结 & 后续

在本文中,你已经启动并运行你的Remix 应用和 MongoDB 实例。另外在你的应用里,你也设置好了 Prisma 和 TailwindCSS,同时也已经开始对下一节要用到的数据进行了建模。

在下篇文章里你将了解:

  • 在 Remix 中设置基于会话的身份验证
  • 使用 Prisma 和 MongoDB 储存和修改用户数据
  • 构建一个登录表单
  • 构建一个注册表单

原文标题:Build A Fullstack App with Remix, Prisma & MongoDB: Project SetupBuild A Fullstack App with Remix, Prisma & MongoDB: Project Setup

原文作者:Sabin Adams

发布时间:2022年4月25日

原文连接:www.prisma.io/blog/fullst…