这是 my-bookmark 项目的重构版本。
新版本将后端改为 Fastify + Prisma + SQLite + TypeScript,并把前端静态资源直接收拢到当前项目中的 public/ 目录里。
浏览器自带的书签虽然够用,但在实际使用里经常会遇到这些问题:
- 重装系统或者更换浏览器之后,书签迁移很麻烦
- 多台设备、多种浏览器之间的书签难以统一
- 收藏的网址越来越多,后续查找效率会越来越低
- 想按分类、关键字、时间范围快速搜索并不方便
- 希望在任意一台联网设备上都能访问自己的书签
- 除了书签之外,还希望顺手记录一点备忘信息
这个项目的目标,就是把这些零散的网址、标签和备忘录统一收拢起来,让你在任何能联网的地方都能打开自己的书签系统。
- 支持账号注册、登录和鉴权
- 支持书签新增、编辑、删除、搜索和分类管理
- 支持书签公开/私有
- 支持导入浏览器导出的书签 HTML 文件
- 支持导出书签
- 支持备忘录功能
- 支持全局快捷链接配置
- 增加Chrome插件,可在任意界面快速添加书签至系统。如果你无法访问该插件,可以按照Chrome如何安装插件(开发版本/自制)方法安装插件,插件请到bookmark-plugin下载。
- 适配手机平板,手机端请访问mb.lucq.fun。
- Fastify: 后端 Web 框架
- Prisma: 数据模型与数据库访问层
- SQLite: 默认数据存储
- TypeScript: 后端与脚本统一使用 TS
- Vitest: 测试框架
- Prettier: 代码格式化
bookmark/
├── public/ 前端静态资源,唯一前端来源
├── src/ 后端源码
│ ├── lib/ 通用工具与辅助函数
│ ├── plugins/ Fastify 插件
│ └── routes/ 路由定义
├── prisma/ Prisma schema、migration、seed
├── scripts/ 数据迁移与校验脚本
├── test/ Vitest 测试
├── data/ 本地数据目录
│ ├── app.db 默认 SQLite 数据库
│ ├── backup/ 导出文件与本地备份
│ └── upload/ 预留上传目录
├── dist/ TypeScript 编译产物
├── package.json 项目脚本与依赖
└── README.md 项目说明文件
npm install项目默认读取根目录下的 .env:
DATABASE_URL="file:./data/app.db"
JWT_SECRET="bookmark-secret"npm run dev开发模式下使用 tsx 直接运行 src/server.ts。
npm run build
npm run start服务启动成功后,终端会打印访问地址,例如:
Local: http://localhost:8157
Network: http://127.0.0.1:8157
已发布镜像:
- Docker Hub:
luchenqun/mybookmark
docker pull luchenqun/mybookmark:latest项目默认监听 8157 端口,默认 SQLite 数据库位于容器内的 ./data/app.db。实际部署时建议把数据目录挂载到宿主机,避免容器重建后数据丢失。
docker run -d \
--name mybookmark \
-p 8157:8157 \
-e JWT_SECRET='请改成你自己的密钥' \
-e DATABASE_URL='file:./data/app.db' \
-v $(pwd)/data:/app/data \
luchenqun/mybookmark:latest启动后可通过以下地址访问:
http://localhost:8157
查看日志:
docker logs -f mybookmark停止容器:
docker stop mybookmark删除容器:
docker rm -f mybookmarkdocker pull luchenqun/mybookmark:latest
docker rm -f mybookmark
docker run -d \
--name mybookmark \
-p 8157:8157 \
-e JWT_SECRET='请改成你自己的密钥' \
-e DATABASE_URL='file:./data/app.db' \
-v $(pwd)/data:/app/data \
luchenqun/mybookmark:latestnpm run dev
npm run build
npm run startnpm test
npm run test:watchnpm run format
npm run format:checknpm run prisma:generate
npm run prisma:migrate
npm run prisma:studio
npm run prisma:seed- 默认数据库文件位于
data/app.db - 前端静态资源位于
public public/是当前项目的唯一前端来源
当前项目的数据迁移方向是:
MySQL -> SQLite
如果你可以直接访问旧项目的 MySQL,那么直接连接旧库迁移即可,不需要先导出 dump。
迁移前先确认这些参数:
MYSQL_HOSTMYSQL_PORTMYSQL_USERMYSQL_PASSWORDMYSQL_DATABASE
项目已经内置迁移命令,可以直接从旧 MySQL 读取数据并写入当前项目的 SQLite:
MYSQL_HOST=你的主机 \
MYSQL_PORT=你的端口 \
MYSQL_USER=你的账号 \
MYSQL_PASSWORD=你的密码 \
MYSQL_DATABASE=你的数据库名 \
npm run migrate:mysql默认会把数据写入当前项目的:
常用环境变量如下:
MYSQL_HOST:MySQL 主机,默认127.0.0.1MYSQL_PORT:MySQL 端口,默认3306MYSQL_USER:MySQL 用户,默认rootMYSQL_PASSWORD:MySQL 密码,默认123456MYSQL_DATABASE:旧 MySQL 数据库名,默认mybookmarksMIGRATION_DATABASE_URL:迁移目标 SQLite,默认写入当前项目的DATABASE_URL
迁移完成后,执行:
MYSQL_HOST=你的主机 \
MYSQL_PORT=你的端口 \
MYSQL_USER=你的账号 \
MYSQL_PASSWORD=你的密码 \
MYSQL_DATABASE=你的数据库名 \
npm run verify:migration这个命令会:
- 重新读取旧 MySQL 数据
- 对比 SQLite 中的导入结果
- 输出各表数量是否一致
迁移完成后,通常会生成这些文件:
其中:
app.db是最终 SQLite 数据库migration-report.json是迁移统计报告suspicious-bookmark-urls.json是迁移过程中标记出的可疑 URL 列表,方便人工复核
建议完整流程按这个顺序执行:
# 1. 安装依赖
npm install
# 2. 构建项目
npm run build
# 3. 连接旧 MySQL 执行迁移
MYSQL_HOST=你的主机 \
MYSQL_PORT=你的端口 \
MYSQL_USER=你的账号 \
MYSQL_PASSWORD=你的密码 \
MYSQL_DATABASE=你的数据库名 \
npm run migrate:mysql
# 4. 校验迁移
MYSQL_HOST=你的主机 \
MYSQL_PORT=你的端口 \
MYSQL_USER=你的账号 \
MYSQL_PASSWORD=你的密码 \
MYSQL_DATABASE=你的数据库名 \
npm run verify:migrationpublic/是唯一前端来源node_modules/、dist/、data/*.db不提交到 git- 代码格式化使用
Prettier - 编辑器风格由
.editorconfig统一