写点什么

Remix.run 新手教程

作者:程序员铮铮
  • 2021 年 11 月 26 日
  • 本文字数:2675 字

    阅读完需:约 9 分钟

Remix.run 新手教程

最近刚在 JavaScript Weekly 看到了 Remix.run(以下简称 Remix)准备开源发布 1.0 版本。没过两天就看到 Remix 飙到 Github Trending 趋势榜第一了。感觉是已经火了啊,不知道后续跟 Next.js 比怎么样。不过看起来不算太复杂,很多东西都封装起来了,语法很轻。所以准备学习一下,顺便做点学习笔记。

创建项目

从 npm 下载 remix 最新版并生成项目。

npx create-remix@latest


? Where would you like to create your app? my-cv

我准备做个展示简历的 Web 应用,动态显示项目经历,这样还算有点需求,不然单纯只是个 Demo,毕竟没有需求就没法好好深入学习。而且 SSR(Server Side Render 服务端渲染)的特色就是方便 SEO,做个展示动态数据类的应用是最适合的。命名my-cv


? Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets.

  • Remix App Server

  • Express Server

  • Architect (AWS Lambda)

  • Fly.io

  • Netlify

  • Vercel

  • Cloudflare Workers

当然选择原汁原味的 Remix App Server 了


? TypeScript or JavaScript?

  • TypeScript

  • JavaScript

我选择了 TypeScript。其实我个人的项目一般不选择 TypeScript,不过这次还需要学习以下,就尽量模拟的更正式一些。对于个人开发者来说 TypeScript 弊大于利,虽然确实可以有效减少错误,和找错误的时间成本,但是定义类型等启动项目时准备的时间更多,还有好不容易找到的冷门库不支持 TS 的风险。


? Do you want me to run npm install? Y

最后安装就行了。

启动项目

进入项目目录

cd my-cv

启动起来看看

npm run dev

这里 Node 版本 12 会报错,16 没问题。

"Could not locate @remix-run/serve. Please verify you have it installed to use the dev command."

可以访问http://localhost:3000了。直接带有一个 Demo,展示了路由的各种状态,404,401 之类的,还有带参数的路由。可以留着参考,也可以删掉。

创建页面

这个 Demo 样式还行,就留着了,反正自己写样式对于学习 Remix 没有太大意义。所以我把导航改成中文,然后第二个页面改成一个新路由,一会可以创建它,用来展示简历。然后第三个 Github 的连接改成自己的了。

<ul>  <li>    <Link to="/">首页</Link>  </li>  <li>    <Link to="/resume">简历</Link>  </li>  <li>    <a href="https://github.com/tychio">GitHub</a>  </li></ul>复制代码
复制代码

然后,创建对应的页面。

mkdir app/routes/resumetouch app/routes/resume/index.tsx复制代码
复制代码

然后填入一些静态文本,名字和介绍。还有技能,这个可以用载入动态数据来做,先做前端部分,直接从字面量返回。利用useLoaderData返回数据。

import type { LoaderFunction } from "remix";import { useLoaderData, json } from "remix";type ResumeData = {  skills: Array<{ name: string }>;};export const loader: LoaderFunction = () => {  const data: ResumeData = {    skills: [      'JavaScript', 'CSS/HTML', 'React', 'Remix'    ]  };  return json(data);}
export default function ResumeIndex() { const resume = useLoaderData<ResumeData>(); return ( <div> <h1>Zhang Zhengzheng</h1> <p> A full-stack developer, Senior consultant, Freelancer. </p> <p> {resume.skills.map((skill, index) => ( <span>{index !== 0 ? ', ' : ''}{skill.name}</span> ))} </p> </div> );}复制代码
复制代码

注意:这里的loader是被后端 API 钩子useLoaderData调用的,所以看不到使用

我还定义了ResumeData类型用于该页面的动态数据,它包含了skills

使用数据库 ORM

下一步,找一个 ORM,把数据彻底放在数据库里。我选择了 Prisma,

npm install --save-dev prisma

npm install @prisma/client

初始化 ORM

npx prisma init --datasource-provider mysql

我选择了 mysql,你可以直接使用 SQL Lite npx prisma init --datasource-provider sqlite

然后在添加的.env文件里设置DATABASE_URL

mysql://<username>:<password>@<host | localhost>:<port>/<database_name>

然后执行 npx prisma db pull 读取数据库并自动生成 schema。

再执行npx prisma generate生成客户端。这样就可以通过以下代码使用 ORM。

import { PrismaClient } from '@prisma/client'const prisma = new PrismaClient()复制代码
复制代码

创建表

我提前创建了 skills 表,所以刚才 pull 的时候,在prisma/schema.prisma文件里就有了 model。

model skills {  id   Int     @id @default(autoincrement())  name String? @db.VarChar(30)}复制代码
复制代码

如果数据库中没有的表,先在这里写上 model schema,再执行npx prisma db push就可以在数据库中创建对应的表。

记得在.gitignore里添加.env。如果使用的 SQLite,还有/prisma/xxx.db

插入数据

创建prisma/seed.ts文件,用于最初的数据。

import { PrismaClient } from "@prisma/client";let db = new PrismaClient();
async function seed() { await Promise.all( getSkills().map(joke => { return db.skills.create({ data: joke }); }) );}
seed();
function getSkills() { return [ { name: 'JavaScript' }, ... ]}复制代码
复制代码

安装ts-node包执行 seed。

npm install --save-dev ts-node

方便起见,在package.json中加入

"prisma": {  "seed": "ts-node prisma/seed.ts"},复制代码
复制代码

然后执行 seed

npx prisma db seed

使用数据

在 app 目录下创建 utils 目录,以及文件utils/db.server.ts

import { PrismaClient } from "@prisma/client";
let db: PrismaClient;
declare global { var __db: PrismaClient | undefined;}
if (process.env.NODE_ENV === "production") { db = new PrismaClient(); db.$connect();} else { if (!global.__db) { global.__db = new PrismaClient(); global.__db.$connect(); } db = global.__db;}
export { db };复制代码
复制代码

development环境的区别是缓存了连接实例,这样不会每次重启

在之前的resume/index.tsx页面使用它。

import { db } from "~/utils/db.server";

~是默认在 Remix 的模板中 tsconfig.json 配置的,代表 app 目录。

更新 loader 方法

export const loader: LoaderFunction = async () => {  const data: ResumeData = {    skills: await db.skills.findMany()  };  return data;}复制代码
复制代码

这样基本的 Remix 流程就走通了。从数据库到页面。

另外我还替换了原来的 logo。谷歌绘图 制作 svg 还挺好用。



代码放到 Github 上了,后面还要继续,和文中可能会有差异。

发布于: 26 分钟前阅读数: 7
用户头像

还未添加个人签名 2021.11.23 加入

还未添加个人简介

评论

发布
暂无评论
Remix.run 新手教程