Electron 下使用 Prisma 的 SQL
Posted
技术标签:
【中文标题】Electron 下使用 Prisma 的 SQL【英文标题】:SQL with Prisma under Electron 【发布时间】:2021-11-03 09:35:13 【问题描述】:我的主要目标是创建一个电子应用程序 (Windows),将数据本地存储在 SQLite 数据库中。由于类型安全,我选择使用Prisma framework 而不是其他 SQLite 框架。 我接受了this Electron Sample Project,现在尝试加入 Prisma。根据我尝试的不同,确实会出现不同的问题。
1。 PrismaClient 无法在浏览器中运行
我执行了npx prisma generate
,然后尝试通过一个按钮执行这个函数:
import PrismaClient from '@prisma/client';
onSqlTestAction(): void
const prisma = new PrismaClient();
const newTestObject = prisma.testTable.create(
data:
value: "TestValue"
);
在 Electron 中执行此操作时,我得到以下信息:
core.js:6456 ERROR Error: PrismaClient is unable to be run in the browser.
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues
at new PrismaClient (index-browser.js:93)
at HomeComponent.onSqlTestAction (home.component.ts:19)
at HomeComponent_Template_button_click_7_listener (template.html:7)
at executeListenerWithErrorHandling (core.js:15281)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15319)
at HTMLButtonElement.<anonymous> (platform-browser.js:568)
at ZoneDelegate.invokeTask (zone.js:406)
at Object.onInvokeTask (core.js:28666)
at ZoneDelegate.invokeTask (zone.js:405)
at Zone.runTask (zone.js:178)
Prisma 不能在浏览器中运行似乎是合乎逻辑的。但我实际上构建了一个原生应用程序 - 使用嵌入浏览器的 Electron。这似乎是一个漏洞。
2。重大变化:webpack
所以我发现了这个问题:How to use Prisma with Electron
似乎正是我所寻找的。但错误信息不同(未找到 Debian 二进制文件)。
提供的解决方案是将 prisma 工件生成到 src
文件夹而不是 node_modules
- 这会导致 19 个 polyfill 错误。一个例子:
./src/database/generated/index.js:20:11-26 - Error: Module not found: Error: Can't resolve 'path' in '[PATH_TO_MY_PROJECT]\src\database\generated'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: "path": require.resolve("path-browserify") '
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: "path": false
这与其他 18 个模块重复。由于开始的错误消息不同,我也怀疑这是要走的路。
【问题讨论】:
【参考方案1】:我终于想通了。我需要了解的是,所有 Electron 应用程序都由两部分组成:前端 Web 应用程序(在嵌入式 Chromium 中运行)和 Node 后端服务器。这两个部分分别称为IPC Main 和IPC Renderer,它们可以相互通信。而且由于 Prisma 只能在作为后端的主进程上运行,我必须将我的 SQL 操作发送到 Electron 后端并在那里执行它们。
我的最小例子
在前端(我使用 Angular)
// This refers to the node_modules folder of the Electron Backend, the folder where the main.ts file is located.
// I just use this import so that I can use the prisma generated classes for type safety.
import TestTable from '../../../app/node_modules/.prisma/client';
// Button action
onSqlTestAction(): void
this.electronService.ipcRenderer.invoke("prisma-channel", 'Test input').then((value) =>
const testObject: TestTable = JSON.parse(value);
console.log(testObject);
);
我使用的示例项目已经有这个服务来提供 IPC Renderer:
@Injectable(
providedIn: 'root'
)
export class ElectronService
ipcRenderer: typeof ipcRenderer;
webFrame: typeof webFrame;
remote: typeof remote;
childProcess: typeof childProcess;
fs: typeof fs;
get isElectron(): boolean
return !!(window && window.process && window.process.type);
constructor()
// Conditional imports
if (this.isElectron)
this.ipcRenderer = window.require('electron').ipcRenderer;
this.webFrame = window.require('electron').webFrame;
this.childProcess = window.require('child_process');
this.fs = window.require('fs');
// If you want to use a NodeJS 3rd party deps in Renderer process (like @electron/remote),
// it must be declared in dependencies of both package.json (in root and app folders)
// If you want to use remote object in renderer process, please set enableRemoteModule to true in main.ts
this.remote = window.require('@electron/remote');
然后在 Electron 后端,我首先将 "@prisma/client": "^3.0.1"
添加到 package.json
(用于 Electron 后端而不是前端)。然后我在main.ts
中添加了这个函数来处理来自渲染器的请求:
// main.ts
ipcMain.handle("prisma-channel", async (event, args) =>
const prisma = new PrismaClient();
await prisma.testTable.create(
data:
value: args
);
const readValue = await prisma.testTable.findMany();
return JSON.stringify(readValue);
)
这种在main.ts
文件中简单地添加IPC Main 处理程序的方式当然是一个很大的代码味道,但作为最小示例很有用。我想我会继续使用this article 中提出的架构概念。
【讨论】:
以上是关于Electron 下使用 Prisma 的 SQL的主要内容,如果未能解决你的问题,请参考以下文章
使用 GraphQL、Nexus 和 Prisma 优化 SQL 查询
Prisma Client 在电子打包所有内容后找不到查询引擎
如何使用 Prisma 编写等效的 SQL MERGE 语句?