Keywords: angular-electron | custom-electron-titlebar
这类问题的解决思路在Angular-Electron
框架上基本可以看作一个通用的解决方案。
简单阐述下怎么出现的问题:
开发项目的过程中,我使用了插件custom-electron-titlebar
,正常在项目根目录下下载,并按照官方文档,在主进程main.ts
文件中进行配置后。在dev
环境下,一切正常,但是build
项目,安装exe
可执行程序之后发现,我双击打开客户端软件时直接提示我:
A JavaScript error occurred in the main process
继续看错误详情发现:
Uncaught Exception:
Error: cannot find module 'custom-electron-titlbear/main'
Require stack:
xxxx/xxx/xxx/app.asar/main.js
有用的错误信息就这两个了,找不到这个模块,以及在哪里没找到。
那,不禁就要问了,为啥我dev
运行没有问题,build
之后会有问题?
我去网上搜索了一下,一个有用的答案是——没有答案,没什么卵用,还得自己分析。
Angular-Electron
使用了two-package.json
的项目结构:
package.json
,一个为渲染进程服务,一个为主进程服务dev
环境下,项目将所有的依赖都集中放到了一个公共区域,谁用谁取,由于这个区域是公共的,所以主进程中使用的依赖依然可以正确找到自己对应的模块。build
时,却分开了,也就是各自打包各自的,分开到了不同的区域,主进程找主进程的,子进程找子进程的,所以production
环境下,主进程找不到模块了。这么说可能不准确,但是简单的理解下这个意思还是可以的。
关于这块我们可以验证下,根据错误信息中的Require stack
,我们可以发现这个模块是在app.asar/main.js
中没找到,那我们可以解压下这个asar
文件,一个简单的方法是在electron-builder.json
配置中加上asar:false
配置,这样最终生成出来的app.asar
就不是一个压缩文件,而是一个正常的文件夹。
我们可以在build
之后看下release
打包输出文件夹的win-unpack
文件夹,这个是免安装文件夹,方便我们查看,可以很明显的看到app.asar
生成的nodeModules
依赖中并没有custom-electron-titlebar
包。
破案了!
分析出了原因,解决方案显而易见了,那就在app/package.json
这个依赖区中下载一下custom-electron-titlebar
呗。这样我们再build
时,就能正常的把这个包打进去了,主进程就可以用了。
值得注意的是,如果某个插件包,不仅在主进程中用了,在渲染进程中也用了,那可能两个package.json
中都要下载一遍。
没什么问题的话,到这一步基本就解决问题了,但是也会有一些额外的问题,这个就需要具体问题具体分析了,我这里提供一个我遇到的问题:
我在主进程的package.json
下载custom-electron-titlebar
之后,由于这个包依赖electron
,我使用的Angular-Electron
框架呢,也是依赖electron
的,很不幸就依赖冲突了。
因为在渲染进程的package.json
中下载这个包时,根据npm
的规则,nodeModules
中出现的包不会重复下载不同的版本,会进行复用,所以不会出现依赖冲突,但是当你下载到主进程的package.json
中时,主进程中可没有electron
的依赖项,所以在下载custom-electron-titlebar
时,不可避免的会再去下载一遍electron
,而且electron
下载的版本可不是深度绑定的,默认下载的是最新版本。
so
,如果下载的electron
版本和渲染进程中依赖的electron
版本不一致,啧啧,依赖冲突不可避免。
那显而易见,最简单的解决方案是啥,统一版本呗。
看看
custom-electron-titlebar
下载的electron
版本是多少,然后把我们渲染进程中依赖的electron
版本进行升/降级。
是个好方法,但是问题太大,版本的升降会带来一些不可预知的意外错误,而且,一旦electron
发布了新版,啧啧,你又得统一一次,所以这个方案不是很可取。
比较好的方案是使用对等依赖来解决因为依赖项版本问题导致的冲突。
angular
的版本必须是13.0.0
,那你安装angular
依赖时,如果不是13.0.0
,那就不会安装成功。所以回到我们这个问题上,我们只需要在主进程的package.json
中指定electron
依赖的版本必须是x.x.x
(渲染进程中eletron
依赖项的版本),那我们在下载依赖项时就能避免依赖冲突的问题。
对等依赖在package.json
配置如下:
"peerDependencies": {
"electron": "21.1.1"
}
至此,完结。