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/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 上了,後面還要繼續,和文中可能會有差異。
版權聲明
本文爲 [程序員錚錚] 所創,轉載請帶上原文鏈接,感謝
https://cdmana.com/2021/11/20211126154131610t.html
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://cdmana.com/2021/11/20211126154131610t.html