使用Next.js+ TypeScript+ AWS Amplify+ Recoil来创建ToDo列表
本文将介绍如何使用Next.js+TypeScript+AWS Amplify+Recoil创建现代化的ToDo列表。

希望您能在GitHub上查找并报告任何问题或不恰当的实现。请随时提交Issue或Pull-Request,非常感谢。
背景概述
平时我个人使用Ruby on Rails进行开发。说实话,JavaScript我还不太擅长。
Rails以其快速开发应用的特点而吸引人,但在需要与移动应用程序集成或要求丰富用户界面的项目中,不得不采用前后端分离的架构。
在这种架构下,反而觉得Rails过于复杂,我一直想尝试使用像AWS Amplify这样快速构建后端的服务。
因此,我决定使用Next.js和AWS Amplify来创建一个简单的应用程序,并尝试学习所谓的现代应用开发技巧。
应用的技术要素
-
- Next.js(React.js)
-
- AWS Amplify
-
- TypeScript
-
- Recoil
- React Hook Form
创建项目
由于Next.js的examples中已经发布了with-typescript-eslint-jest,我以此为基础进行了开发。
$ create-next-app
✔ What is your project named? … next-ts-amplify-recoil-todolist
✔ Pick a template › Example from the Next.js repo
✔ Pick an example › with-typescript-eslint-jest
# 省略
放大器的安装
接下来,我们将安装AWS Amplify。
初始化
运行amplify init进行初始化。
$ cd next-ts-amplify-recoil-todolist
$ amplify init
? Enter a name for the project todolist
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you\'re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: out
? Build Command: npm run-script build
? Start Command: npm run-script start
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use (使用するprofile)
为了避免在托管时出现问题,我们将分发目录路径设置为”out”。详细信息请参阅这篇文章。
托管(包括CI/CD)
基于经验,若在后期添加托管,则难以进行故障排除,因此建议尽早使用CI/CD设置托管。
❯ amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository
# ブラウザでAWS Amplify Consoleが表示されるので諸々設定をした後、Enterを入力
Amplify hosting urls:
┌──────────────┬──────────────────────────────────────────────┐
│ FrontEnd Env │ Domain │
├──────────────┼──────────────────────────────────────────────┤
│ master │ https://master.d14mfq14xzgfle.amplifyapp.com │
└──────────────┴──────────────────────────────────────────────┘
为了将 build 输出目录更改为 out,您需要在本地环境中修改 package.json 的一部分。
请参考此文章以获取更多详细信息。
另外,在Amplify控制台的“构建配置”中,将amplify.yml文件修改为以下内容。
version: 1
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- yarn install
build:
commands:
- yarn run build
artifacts:
baseDirectory: out
files:
- '**/*'
cache:
paths:
- node_modules/**/*
此外,需要在「构建设置」→「构建镜像设置」→「编辑」→「实时软件包更新」中将Amplify CLI设置为latest。如果不这样做,部署将会失败,因此请务必注意。

当部署完成后,访问显示的URL即可查看页面。

身份验证体系
使用以下命令添加认证基础设施。
$ amplify add auth
? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings? No, I am done.
# 省略
$ amplify push
✔ Successfully pulled backend environment production from the cloud.
Current Environment: production
| Category | Resource name | Operation | Provider plugin |
| -------- | -------------------- | --------- | ----------------- |
| Auth | besttodolistf818478c | Create | awscloudformation |
| Hosting | amplifyhosting | No Change | |
? Are you sure you want to continue? Yes
# 省略
GraphQL API
GraphQL API
我会提前创建GraphQL的模式文件。
type Todo @model {
id: ID!
name: String!
completed: Boolean!
timestamp: AWSTimestamp!
}
用以下的命令添加后端的GraphQL API。
$ amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: todolist
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? Yes
? Provide your schema file path: ./schema.graphql
# 省略
为了预防起见,我会启动一个模拟服务器进行操作确认。
这时,客户端的代码也会被生成。
$ amplify mock api
# 省略
Running GraphQL codegen
? Choose the code generation language target typescript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.ts
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
? Enter the file name for the generated code src/API.ts
? Do you want to generate code for your newly created GraphQL API Yes
# 省略
AppSync Mock endpoint is running at http://xxx.xxx.xxx.xxx:20002
当您访问所提供的URL时,将显示Graphiql界面,您可以在此界面上测试GraphQL请求。

如果没有特别的问题的话,我们可以执行amplify push。
❯ amplify push
✔ Successfully pulled backend environment production from the cloud.
Current Environment: production
| Category | Resource name | Operation | Provider plugin |
| -------- | -------------------- | --------- | ----------------- |
| Api | bestTodolist | Create | awscloudformation |
| Hosting | amplifyhosting | No Change | |
| Auth | besttodolistf818478c | No Change | awscloudformation |
? Are you sure you want to continue? Yes
# 省略
? Do you want to update code for your updated GraphQL API Yes
? Do you want to generate GraphQL statements (queries, mutations and subscription) based on your schema types?
This will overwrite your current graphql queries, mutations and subscriptions Yes
# 省略
前端实现
安装npm包
请使用以下命令进行安装。
$ yarn add @material-ui/core @material-ui/icons aws-amplify @aws-amplify/ui-react react-hook-form recoil
添加对 Lint/Formatter 中的ignore 的忽略
下面的文件由Next.js导出,或由AWS Amplify自动生成的代码将被排除在Lint/Formatter的检查范围之外。
**/node_modules/*
**/out/*
**/.next/*
src/aws-exports.js
node_modules
.next
yarn.lock
package-lock.json
public
out
实现页面的概览
请将以下文件复制并粘贴到指定的目录中。
页面 (mian4yi3)
需要基于 _app.tsx 和 _document.tsx 进行开发。
据我所知,目前 _document.tsx 不支持以函数组件的方式编写。
以下是需要用中文重述的链接:
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/pages/_app.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/pages/_document.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/pages/index.tsx
组件
我們將創建成為每個頁面元件的組件。
请将以下内容用中文本地化,只需提供一种翻译选项:
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Header.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Footer.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Todo.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Header.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Footer.tsx
https://github.com/yuuu/next-ts-amplify-recoil-todolist/blob/master/src/component/Todo.tsx
商店
如果只是普通的任务清单级别,就没必要使用存储了,但是我决定尝试一下一直想用的 Recoil。
主题
定义用于Material UI的基本主题。
确认行动
当CI/CD顺利完成,当访问页面时将显示登录界面。

创建一个帐户后,就能够进行登录。成功地显示了列表画面。

其他屏幕的实施
注册页面

将下一个文件添加到页面中。
为了在编辑界面上也能使用该表单,我们将其组件化。
详细画面

将下一个文件添加到页面中。
编辑界面

将下一个文件添加到页面中。
总结
在本地环境下开发应用,并成功地对屏幕进行了调整,但在持续集成/持续交付(CI/CD)过程中遇到了许多困难,让我苦不堪言。
如果环境一直保持这样,我觉得以后可以高速地进行开发。
请务必试试看。