最近刚在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 runnpm 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上了,前面还要持续,和文中可能会有差别。