为了账号安全,请及时绑定邮箱和手机立即绑定

在电子渲染器过程中将nedb坚持到磁盘

在电子渲染器过程中将nedb坚持到磁盘

守着星空守着你 2021-04-01 18:15:19
问题我正在尝试在Electron渲染器进程中使用一个名为nedb的纯JS数据库。它使用browser领域中的package.json要交换基于浏览器的存储系统。这导致我的数据库实际上未持久保存到文件中。背景我使用Next.js作为我的视图框架,并且"target": "electron-renderer"为渲染线程配置了它的Webpack 。即使渲染器进程应该有权访问浏览器和Node API,这显然也会导致Webpack处理那些浏览器指令。此行为并未真正记录,因此我不知道如何覆盖它。我尝试过的我已经确认,如果我手动编辑browser的本地副本上的字段node_modules/nedb/package.json,则问题将消失。作为临时的解决方法,我已经指出了自己的能力nedb。但是,这是非常不令人满意的。其他研究奇怪的是,这似乎对电子战来说不是问题,电子战的文档明确演示nedb了渲染器过程中对电子战的使用。实际上,该框架似乎确实"target": "electron-renderer"在其Webpack config中使用。是否可以通过Webpack配置解决此问题?
查看完整描述

2 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

正如您在问题中所述以及软件包上的这个Github问题所指出的那样,问题nedb的根本原因是webpack的文件解析过程会读取package.browser密钥,以便在target构建为browser或其他值时将特定文件路径别名到另一个位置使它检查package.browser财产。


electron-vue似乎通过将所有NPM依赖项视作避开了webpack捆绑问题,externals这样它们就不会被拉入应用程序捆绑包,而是期望global通过其他某种方式进行定义。您可以类似地nedb在webpack配置中将其指定为外部,然后通过脚本标签或以global其他方式定义对它的引用,将Node版本拉入您的应用程序。


另一个解决方案是创建一个webpack解析器插件,以覆盖问题的要求"./lib/customUtils.js"和"./lib/storage.js"解决方式,从而绕过检查package.browser的那些文件路径别名的解决步骤。


有关如何在Webpack配置中传递自定义解析器插件的信息,请参阅webpack文档。有关如何定义插件以及它们如何工作的wepback/enhanced-resolve更多详细信息,请参见文档。


本质上,插件是具有apply方法的对象,该方法采用resolver实例并执行文件解析过程的某些步骤。在下面的示例中,我们测试以查看当前要解析的文件是否在nedb软件包中,以及它是否是两个有问题的浏览器别名之一。如果是这样,我们将使用正确的文件路径退出解析过程。否则,我们将不执行任何操作,并遵循正常的解决程序。


// Prevents nedb from substituting browser storage when running from the

// Electron renderer thread.

const fixNedbForElectronRenderer = {

  apply(resolver) {

    resolver

      // Plug in after the description file (package.json) has been

      // identified for the import, which makes sure we're not getting

      // mixed up with a different package.

      .getHook("beforeDescribed-relative")

      .tapAsync(

        "FixNedbForElectronRenderer",

        (request, resolveContext, callback) => {

          // When a require/import matches the target files, we

          // short-circuit the Webpack resolution process by calling the

          // callback with the finalized request object -- meaning that

          // the `path` is pointing at the file that should be imported.

          const isNedbImport = request.descriptionFileData["name"] === "nedb"


          if (isNedbImport && /storage(\.js)?/.test(request.path)) {

            const newRequest = Object.assign({}, request, {

              path: resolver.join(

                request.descriptionFileRoot,

                "lib/storage.js"

              )

            })

            callback(null, newRequest)

          } else if (

            isNedbImport &&

            /customUtils(\.js)?/.test(request.path)

          ) {

            const newRequest = Object.assign({}, request, {

              path: resolver.join(

                request.descriptionFileRoot,

                "lib/customUtils.js"

              )

            })

            callback(null, newRequest)

          } else {

            // Calling `callback` with no parameters proceeds with the

            // normal resolution process.

            return callback()

          }

        }

      )

  }

}


// Register the resolver plugin in the webpack config

const config = {

  resolve: {

    plugins: [fixNedbForElectronRenderer]

  }

}


查看完整回答
反对 回复 2021-04-08
?
Helenr

TA贡献1780条经验 获得超4个赞

您无需在渲染器进程上运行数据库,而是可以在主进程上运行其他想要的数据库,例如sql,sqlite,mongodb等。


如果您不介意切换数据库,可以通过以下方法实现此目的。在Electron中存在一个名为ipcMain和ipcRenderer的类,该类用于使渲染器进程和主进程通信。您可以使用ipc发送/接收任何类型的数据。


这是一个例子:


Renderer.js


const btnSave = document.getElementById('btn-save')


// Get any data from forms, etc



btn.addEventListener('click', () => {

     // ipcRender sends the data via 'receive-data-to-save-in-database' channel, you

     // you can send any type of data, and have has many args you want. In this case I 

     // sent a a empty object

     ipcRenderer.send('receive-data-to-save-in-database', {})              

})

Main.js


// ipcMain listens to channel 'receive-data-to-save-in-database'

ipcMain.on('receive-data-to-save-in-database', (event, args) => {

    // Code to save in database

    // The empty object will be received in args parameter

}) 

这不是您想要的,而是一种解决方法。


查看完整回答
反对 回复 2021-04-08
  • 2 回答
  • 0 关注
  • 274 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号