【问题标题】:SQL with Prisma under ElectronElectron 下使用 Prisma 的 SQL
【发布时间】: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 个模块重复。由于开始的错误消息不同,我也怀疑这是要走的路。

【问题讨论】:

    标签: sqlite electron prisma


    【解决方案1】:

    我终于想通了。我需要了解的是,所有 Electron 应用程序都由两部分组成:前端 Web 应用程序(在嵌入式 Chromium 中运行)和 Node 后端服务器。这两个部分分别称为IPC MainIPC 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 中提出的架构概念。

    【讨论】:

      猜你喜欢
      • 2021-01-13
      • 2021-11-18
      • 2021-08-30
      • 2021-12-15
      • 2021-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      相关资源
      最近更新 更多