问题
我试图在电子渲染程序过程中使用一个名为nedb的纯JS数据库。它在基于浏览器的存储系统中使用字段 in package.json进行交换。这导致我的数据库实际上不会被持久化为文件。
背景
我使用Next.js作为我的视图框架,它的Webpack是为呈现线程的"target": "electron-renderer"配置的。这显然导致Webpack处理那些浏览器指令,尽管渲染程序进程应该同时访问浏览器和节点API。这种行为并没有得到真正的记录,所以我不知道如何覆盖它。
我试过的
我已经确认,如果我手动编辑出本地browser副本上的node_modules/nedb/package.json字段,问题就解决了。
作为一种暂时的解决办法,我已经指出了我自己的nedb分叉就是这样做的。但这是相当不令人满意的。
其他研究
奇怪的是,对于电子vue来说,这似乎不是一个问题,它的文档显式演示使用来自渲染程序的nedb。实际上,这个框架似乎在Webpack配置中使用了Webpack配置。
有没有解决这个问题的办法,也许是Webpack的配置?
发布于 2019-04-07 19:03:36
正如您在问题中所述,并按照Github问题上的nedb包,问题的根本原因是webpack的文件解析过程读取package.browser键,以便在target构建为browser或将导致它检查package.browser属性的其他值时,将特定的文件路径别名到不同的位置。
electron-vue在回避webpack捆绑问题看来是将所有NPM依赖项作为externals来处理,这样它们就不会被拖进应用程序包中,而是会通过其他方式在global上定义。您也可以在webpack配置中将nedb指定为外部版本,并通过脚本标记或以其他方式在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]
}
}发布于 2019-04-01 19:25:11
您不需要在呈现程序进程上运行数据库,而是可以在主进程上运行其他您想要的数据库,比如sql、sqlite、mongodb等等。
如果您不介意切换数据库,以下是如何实现这一目标。在电子存在中有一个名为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
}) 这不是你想要的,而是一种解决办法。
关于更多信息,我建议你去:
https://stackoverflow.com/questions/55389659
复制相似问题