前言

感谢 Jonny 的指导,尝试摸着石头过河。自己手写一个简单的图书管理系统作为我的入门项目。不知道能不能成功,也许中途就放弃也有可能。(毕竟人很懒)

技术栈

可能不太准确,毕竟还没太搞清楚。后续若有误会进行勘误。

前端

使用 Lit + TypeScript + Stylus + Pug 配合 Vite 打包器构建前端。

后端

使用 TypeScript + MySQL 数据库构建后端。

项目初始化

项目结构
  • Library
    • node_modules
    • serve
      • dist
      • node_modeles
      • src
        • index.ts
      • package-lock.json
      • package.json
      • tsconfig.json
    • web
      • node_modeles
      • scripts
        • index.ts
      • index.html
      • package-lock.json
      • package.json
      • tsconfig.json
      • vite.config.json
    • .gitignore
    • biome.json
    • package-lock.json
    • package.json
    • README.md
    • tsconfig.json

安装 MySQL 数据库

请移步至文章了解 MySQL 数据库

下载依赖

总体依赖

代码格式化工具 biome

1
npm install --save-dev @biomejs/biome

初始化 biome ,会生成一个 biome.json 文件,可以在其中进行配置

1
npx @biomejs/biome init

首先在扩展商店下载 biome 插件,然后进入 setting.json 设置保存自动格式化

1
2
3
4
5
6
7
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.biome": "explicit"
}
}
若出现奇怪原因 biome 报错,可以尝试重启 biome 解决
  1. 在 VS Code 中按 Ctrl+Shift+P。
  2. 输入 Biome: Restart Biome Server。

后端依赖

安装 TypeScript 和 @types/node

1
npm install -D typescript @types/node

安装 TS 运行工具,支持热更新

1
npm install -D tsx

安装 MySQL2 驱动

1
npm install mysql2

添加脚本

1
2
3
4
5
"scripts": {
"dev": "tsx watch src/app.ts",
"build": "tsc",
"serve": "node dist/app.js"
}

配置 tsconfig.json 文件,运行以下代码生成中文注释的配置文件

1
tsc --init --locale zh-CN

前端依赖

添加脚本

1
2
3
4
5
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "vite",
"build": "vite build"
},

配置 tsconfig.json 文件,运行以下代码生成中文注释的配置文件

需要自行创建 vite.config.ts 文件,将配置写入其中

1
tsc --init --locale zh-CN

安装 lit 核心框架

1
npm install lit

安装类型定义

1
npm install -D @types/node

安装 styule 预处理器

1
npm install -D stylus

安装 vite 插件用于支持 pug

1
npm install -D vite-plugin-pug

安装 Vite 打包器,支持热更新

1
npm install -D Vite

创建 vite.config.ts 配置文件,写入配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { defineConfig } from "vite";
import pugVite from "vite-plugin-pug";

const HOST = "127.0.0.1";
const PORT = 5600;

export default defineConfig({
plugins: [pugVite()],
// server:{
// proxy:{
// "^/api/.*":"http://localhost:3000",
// }
// },
server: {
port: PORT,
strictPort: true,
host: HOST,
// hmr: {
// protocol: 'ws',
// // host: HOST,
// port: PORT + 1,
// },
},
build: {
// 打包输出到 dist 目录,server.js 会将此目录作为静态根目录
outDir: "dist",
emptyOutDir: true,
// 入口文件
rollupOptions: {
input: "index.html", // 将根目录的 index.html 作为入口
},
},
});

实现功能: 向数据库中存入数据

前端部分语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  ...
try {
const response = await fetch("http://127.0.0.1:3000/api/addUser", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: this.username,
password: this.password,
}),
});
} catch (e) {
this.error = e instanceof Error ? e.message : "未知错误";
}
...

后端部分语句

  1. 路由处理
1
2
3
4
5
 ...
if (urlPath === "/api/addUser" && method === "POST") {
addUser(req, res);
}
...
  1. 处理数据并发送结果 (其实不管成不成功都会发送结果)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let buffer = Buffer.alloc(0);
req.on("data", (chunk) => {
buffer = Buffer.concat([buffer, chunk]);
});
req.on("end", () => {
try {
const body = buffer.toString();
const data = JSON.parse(body);
const { username, passworld } = data;
addAccount(username, passworld);
res.writeHead(200, { "content-type": "application/json" });
res.end(
JSON.stringify({
message: "Add succesfully",
}),
);
} catch (e) {
res.writeHead(400, { "content-type": "application/json" });
res.end(JSON.stringify({ error: `Invalid JSON :${e}` }));
}
});
  1. 向数据库插入信息
1
2
3
4
5
6
export async function addAccount(username: string, password: string) {
await pool.query(`
INSERT INTO library_db.user (username, passworld)
VALUE ('${username}','${password}');
`);
}

结语

有好多东西都不懂…边做边学吧 (;′⌒`)

本篇文章未完结,持续更新中…

~哪天不更新了这篇文章也见不到了 (゜▽゜)☆