乐趣区

关于javascript:Remixrun-新手教程

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

退出移动版