SQL 在 Electron 下使用 Prisma
SQL with Prisma under Electron
我的主要目标是创建一个 Electron 应用程序 (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 < 5 用于包含 polyfills
所以我发现了这个问题:How to use Prisma with Electron
似乎正是我要找的。但错误消息不同(未找到 Debian 二进制文件)。
提供的解决方案是将 prisma 工件生成到 src
文件夹而不是 node_modules
- 这会导致 19 个 polyfills 错误。举个例子:
./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 个模块重复。由于开始的错误消息不同,我也怀疑这是要走的路。
我终于明白了。我需要了解的是,所有 Electron 应用程序都由两部分组成:前端 Web 应用程序(运行ning 在嵌入式 Chromium 中)和一个 Node 后端服务器。这两个部分称为 IPC Main and 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 应用程序 (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 < 5 用于包含 polyfills
所以我发现了这个问题:How to use Prisma with Electron
似乎正是我要找的。但错误消息不同(未找到 Debian 二进制文件)。
提供的解决方案是将 prisma 工件生成到 src
文件夹而不是 node_modules
- 这会导致 19 个 polyfills 错误。举个例子:
./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 个模块重复。由于开始的错误消息不同,我也怀疑这是要走的路。
我终于明白了。我需要了解的是,所有 Electron 应用程序都由两部分组成:前端 Web 应用程序(运行ning 在嵌入式 Chromium 中)和一个 Node 后端服务器。这两个部分称为 IPC Main and 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 中提出的架构概念。