部署SvelteKit到生产VM时Prisma客户端相关问题咨询
SvelteKit + Prisma 部署问题与解答
背景场景
我正在构建SvelteKit应用并部署到VM,使用如下发布脚本(手动复制prisma.schema到VM并执行npx prisma generate):
host="XXX" app_name="dashboard" # NAVIGATE TO THE PROJECT ROOT cd ../../ # # BUILD THE PACKAGE npm run build --MODE=production # # DELETE THE CONTENT OF THE REMOTE FOLDER ssh root@$host 'rm -rf /home/dashboard/*' # # COPY THE PACKAGE TO THE REMOTE MACHINE scp -r package.json package-lock.json prisma/schema.prisma root@$host:/home/dashboard/ ssh root@$host bash -s << HERE cd /home/dashboard/ # npm ci --omit dev npm i npx prisma generate pm2 stop /home/dashboard/build/index.js --name $app_name 2>/dev/null pm2 delete /home/dashboard/build/index.js --name $app_name HOST=127.0.0.1 PORT=3000 pm2 start /home/dashboard/build/index.js --name $app_name --log-date-format 'MMM DD HH:mm:ss' HERE
但运行时出现Prisma找不到DATABASE_URL的错误:
26|dashboard | May 19 15:18:06: error: Environment variable not found: DATABASE_URL. 26|dashboard | May 19 15:18:06: --> schema.prisma:9 26|dashboard | May 19 15:18:06: | 26|dashboard | May 19 15:18:06: 8 | provider = "mysql" 26|dashboard | May 19 15:18:06: 9 | url = env("DATABASE_URL") 26|dashboard | May 19 15:18:06: |
疑问解答
1. 为何Vite无法在构建时将Prisma客户端一同打包?
- Prisma Client不是通用的静态JS/TS模块,它是基于你的schema文件动态生成的专属代码,包含对应数据库的适配逻辑,还依赖特定的Prisma引擎二进制文件。
- Vite的打包逻辑是静态分析代码依赖并编译,但Prisma Client的生成需要读取schema、生成适配代码、下载对应架构的引擎,这整个过程无法被Vite的静态打包流程覆盖,必须单独执行
prisma generate来完成。
2. 在SvelteKit中使用import { DATABASE_URL } from '$env/static/private';,如何将该变量提供给schema.prisma文件?
- Prisma读取环境变量的逻辑独立于SvelteKit的
$env系统:Prisma只会直接读取系统环境变量、项目根目录的.env文件,或者启动时传入的环境变量,不会识别SvelteKit通过$env导出的变量。 - 可行的解决方法:
- 方法一:在VM的
/home/dashboard/目录下创建.env文件,写入DATABASE_URL=你的数据库连接字符串,Prisma会自动读取该文件。 - 方法二:在PM2启动命令中直接传入环境变量,修改脚本中的启动行:
HOST=127.0.0.1 PORT=3000 DATABASE_URL=你的数据库连接字符串 pm2 start /home/dashboard/build/index.js --name $app_name --log-date-format 'MMM DD HH:mm:ss' - 方法三:在部署脚本中添加一行,将本地的生产环境配置文件(比如
.env.production)上传到VM:scp .env.production root@$host:/home/dashboard/.env
- 方法一:在VM的
3. 当前部署流程较为繁琐,是否有更优的实现方案?
可以从以下几个方向优化:
- 简化依赖与文件传输
- 用
npm ci --omit dev替代npm i:npm ci严格按照package-lock.json安装依赖,速度更快且版本一致,省略dev依赖能减少安装体积和时间。 - 无需删除整个远程目录,只清理旧的构建产物和依赖目录,保留
.env这类配置文件,避免重复配置。
- 用
- 自动化Prisma操作
- 本地提前执行
npx prisma generate,然后将生成的node_modules/.prisma目录一起传到VM,这样就不用在VM上再次执行prisma generate(注意:本地和VM的操作系统架构必须一致,否则Prisma引擎二进制文件会不兼容)。
- 本地提前执行
- 引入CI/CD工具
- 使用GitHub Actions、GitLab CI等工具自动化构建、测试、部署流程,代码提交后自动触发部署,完全替代手动执行脚本的操作。
- 优化后的示例脚本片段
host="XXX" app_name="dashboard" cd ../../ npm run build --MODE=production npx prisma generate # 本地生成Prisma客户端 # 仅清理旧的构建产物和依赖 ssh root@$host 'rm -rf /home/dashboard/build/ /home/dashboard/node_modules/' # 传输必要文件,包含生成的prisma目录和环境配置 scp -r package.json package-lock.json build/ node_modules/.prisma/ prisma/schema.prisma .env.production root@$host:/home/dashboard/ ssh root@$host bash -s << HERE cd /home/dashboard/ mv .env.production .env # 替换为生产环境变量 npm ci --omit dev pm2 stop $app_name 2>/dev/null pm2 delete $app_name 2>/dev/null HOST=127.0.0.1 PORT=3000 pm2 start build/index.js --name $app_name --log-date-format 'MMM DD HH:mm:ss' HERE
内容的提问来源于stack exchange,提问作者Duncan
相关产品推荐
相关产品推荐

