You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署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
      

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:45:00