记一次在 electron 中使用 sqlite3 和 sequelize 的经历

electron:https://www.electronjs.org

sqlite3:https://github.com/mapbox/node-sqlite3

sequelize:https://github.com/sequelize/sequelize

解决方案参考:https://blog.csdn.net/hsany330/article/details/104927772

https://www.cnblogs.com/alex96/p/12180296.html

安装 sqlite3

electron 是一个 使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序 的框架,支持调用系统原生资源,因此受到广大跨平台开发者的喜爱。

由于 electron 也是基于 Node.js 的,所以安装 sqlite3 和在 Node.js 中一致。

执行

npm i -S sqlite3 

即可。

如果安装失败,可以考虑以下几步:

# 安装node-gyp
npm install -g node-gyp

以管理员身份运行 powershell 或者 cmd 否则以下指令会报错

npm install --global --production windows-build-tools

然后重新安装 sqlite3 。

在 electron 中编译 sqlite3

在成功安装 sqlite3 后,我们会发现 sqlite3 依旧无法在 electron 中使用,因为 sqlite3 是原生模块,无法直接在 electron 中调用。所以需要先编译一遍再使用。

安装electron-rebuild 并重新编译:

npm install --save-dev electron-rebuild 

# 每次运行"npm install"后,也运行这条命令
./node_modules/.bin/electron-rebuild 

# 在windows下如果上述命令遇到了问题,尝试这个:
.\node_modules\.bin\electron-rebuild.cmd

完成编译后就能在 electron 中调用了。

安装和修复 sequelize

接下来是安装 sequelize。

sequelize 是一个 orm 框架,可以简化操作数据库的流程。

执行

npm i -S sequelize 

此时注意到报错:

App threw an error during load
Error: Please install sqlite3 package manually
    at ConnectionManager._loadDialectModule (webpack:///./node_modules/sequelize/lib/dialects/abstract/connection-manager.js?:81:15)
    at new ConnectionManager (webpack:///./node_modules/sequelize/lib/dialects/sqlite/connection-manager.js?:24:21)
    at new SqliteDialect (webpack:///./node_modules/sequelize/lib/dialects/sqlite/index.js?:15:30)
    at new Sequelize (webpack:///./node_modules/sequelize/lib/sequelize.js?:340:20)

提示我们要手动安装 sqlite3 ,但是我们上面已经安装了 sqlite3,这是怎么回事呢?

经过一番搜寻,我注意到 sequelize 在导入第三方数据库模块时使用了动态导入的方法,因此 webpack 在打包时无法正确分析出依赖关系。

在根据错误提示定位到相关文件后,修改以下内容。

// src\dialects\sqlite\connection-manager.js 第22行
this.lib = this._loadDialectModule('sqlite3');
// 改为以下内容
this.lib = require('sqlite3'); 

简单来讲就是既然动态导入出错那就静态导入。

重新执行 tsc 编译后虽然报一堆错但 lib 文件夹还是成功生成了。

.gitignore 文件中的 lib 去掉后上传生成的 lib 文件到 git 服务器。

接下来再把项目中的 sequelize 依赖的版本号改为

{
    "sequelize": "git+https://gitee.com/caomeiyouren/sequelize.git"
}

重新执行

npm i -S sequelize 

即可。

本人已经 fork 了一个版本到 码云,如果有人需要可以参考一下。

最后到 electron 中测试发现可用了。

另外,sqlite3 等原生模块也只能在主进程中调用,在渲染进程中会报错的,可以使用进程间通信来解决问题。

后记

本次可以说是踩了 Node.js 中的两个大坑:原生模块编译和修复第三方模块。如果说原生模块编译只是麻烦的话,那修复第三方模块可就真的是件麻烦事了。也不是每个第三方模块都能看一眼就能修复,有些写的十分复杂的模块也只能提个 issue 等作者来修复。但如果等不到作者的话,就只能自己 fork 一份来修改了。在网上搜索解决问题的方案中我注意到已经有人研究的很深入了,已经注意到了是动态导入的问题,但却没有去翻看源码,去找到问题的根源。我觉得有时候还是得多看下源码,有些问题也并没有那么难以修复,我想还是得有修改源码的勇气才行。