我参与的 node 项目中,使用了 prisma 作为 ORM,但是在打包后运行时出现了问题,具体报错信息是这样的:
PrismaClientInitializationError: Prisma Client could not locate the Query Engine for runtime "linux-musl-openssl-3.0.x".
clickhouse-1 | This is likely caused by a bundler that has not copied "libquery_engine-linux-musl-openssl-3.0.x.so.node" next to the resulting bundle.
clickhouse-1 | Ensure that "libquery_engine-linux-musl-openssl-3.0.x.so.node" has been copied next to the bundle or in "node_modules/.pnpm/@prisma+client@5.11.0_prisma@5.11.0/node_modules/.prisma/client".
有用的报错就以上这么多。
这东西有点坑,主要是在网上搜不太到解决方法。
根据搜到的仅有的几个解决方案,试了一下,在创建client的时候加入binaryTargets = [“native”, “linux-musl-openssl-3.0.x”],但是没什么效果。
主要问题在于,prisma 代理连接和操作数据库不只是通过后面生成的 client,而是通过 client 和他自己的一个SDK libquery_engine-debian-openssl-3.0.x.so.node 完成,这个东西在安装 prisma 的时候会被一起下载到 node_modules 里。
npm 和 pnpm 下载,这个东西会放在不同的地方:
- npm 下载会存在于 node_modules/.prisma 下的一个地方
- pnpm 下载会存在于 node_modules/.pnpm/ 下关于 prisma 的几个目录下
报错中有一个地方是这么说的:
Ensure that "libquery_engine-linux-musl-openssl-3.0.x.so.node" has been copied next to the bundle or in "node_modules/.pnpm/@prisma+client@5.11.0_prisma@5.11.0/node_modules/.prisma/client".
所以可能是打包后找不到这个东西导致的,但是把它复制到打包后 js 文件的同级目录下没啥用,需要将其复制到后面的那个目录中,这个 node_modules 不是项目的,而是需要在打包输出的 js 文件同级目录下手动创建,最后复制到里面。
还有个比较坑的地方是,不同的 node 或 npm 环境,要复制到的目的地址不一样,要根据报错信息修改一下,不注意的话很可能出现本地打包、复制之后能跑,容器运行又报错的情况。