Remix.run novice tutorial

Posted by seanko on Sat, 27 Nov 2021 00:23:35 +0100

Recently, I just saw Remix. Run (hereinafter referred to as Remix) in JavaScript Weekly preparing to release version 1.0 open source. Within two days, I saw Remix soar to the first place in the Github Trending trend list. I think it's already hot. I don't know how to compare with Next.js in the follow-up. But it doesn't seem too complicated. Many things are encapsulated and the syntax is very light. So prepare to study and take some study notes by the way.

Create project

Download the latest version of remix from npm and build the project.

npx create-remix@latest

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

I'm going to make a Web application to display my resume and dynamically display my project experience. This is still a little demand. Otherwise, it's just a Demo. After all, I can't study deeply without demand. Moreover, the feature of SSR(Server Side Render) is to facilitate SEO. It is most suitable to be an application that shows dynamic data classes. Name 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
    Of course, choose the original Remix App Server

? TypeScript or JavaScript?
TypeScript

  • JavaScript
    I chose TypeScript. In fact, TypeScript is generally not selected for my personal projects, but I still need to learn the following this time, so I'll try to simulate it more formally. For individual developers, TypeScript does more harm than good. Although it can effectively reduce errors and the time cost of finding errors, it takes more time to define types and start projects. There is also the risk that the cold library that is hard to find does not support TS.

? Do you want me to run npm install? Y
Finally, install it.

Start project

Enter project directory

cd my-cv

Start up and have a look

npm run dev

Here, Node version 12 will report an error, and 16 is OK.

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

Can access http://localhost:3000 Yes.
There is a Demo directly, which shows various routing states, such as 404401, and routes with parameters. You can keep it for reference or delete it.

Create page

This Demo style is OK, so keep it. Anyway, writing your own style is not of great significance for learning Remix. So I changed the navigation to Chinese, and then changed the second page to a new route, which can be created later to display my resume. Then the connection of the third Github is changed to its own.

<ul>
  <li>
    <Link to="/">home page</Link>
  </li>
  <li>
    <Link to="/resume">resume</Link>
  </li>
  <li>
    <a href="https://github.com/tychio">GitHub</a>
  </li>
</ul>

Then, create the corresponding page.

mkdir app/routes/resume
touch app/routes/resume/index.tsx

Then fill in some static text, name and introduction. There are also skills. This can be done by loading dynamic data. First do the front-end part and return directly from the literal value. Use useLoaderData to return data.

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>
  );
}

Note: the loader here is called by the back-end API hook useLoaderData, so it can't be used

I also defined the ResumeData type for the dynamic data of the page, which contains skills.

Using database ORM

Next, find an ORM and put the data completely in the database. I chose Prisma,

npm install --save-dev prisma

npm install @prisma/client

Initialize ORM

npx prisma init --datasource-provider mysql

I chose mysql. You can directly use SQL Lite NPX prism init -- datasource provider SQLite.

Then set database in the added. env file_ URL

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

Then execute npx prisma db pull to read the database and automatically generate the schema.

Then execute NPX prism generate to generate the client.
In this way, ORM can be used through the following code.

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

Create table

I created the skills table in advance, so when I pull ed just now, there was a model in the prisma/schema.prisma file.

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

If there is no table in the database, first write the model schema here, and then execute npx prisma db push to create the corresponding table in the database.

Remember to add. env to. gitignore. If SQLite is used, there is also / prisma/xxx.db.

insert data

Create the prisma/seed.ts file for the initial data.

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'
    },
    ...
  ]
}

Install the TS node package and execute seed.

npm install --save-dev ts-node

For convenience, add in package.json

"prisma": {
  "seed": "ts-node prisma/seed.ts"
},

Then execute seed

npx prisma db seed

Use data

Create the utils directory and the file utils/db.server.ts in the app directory

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 };

The difference in the development environment is that the connection instance is cached so that it does not restart every time

Use it on the previous resume/index.tsx page.

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

~It is configured in tsconfig.json in Remix's template by default and represents the app directory.

Update loader method

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

In this way, the basic Remix process goes through. From database to page.

In addition, I also replaced the original logo. Google graphics Making svg is very useful.

code Put it on Github and continue later. It may be different from the text.

Topics: Javascript node.js Front-end React