最近在开发一个桌面客户端。心血来潮想用Node.js来做。然后就跳进了坑了。天天在爬坑。开篇博文记录一下最几天遇到的各种坑。

1.Electron安装的坑

在使用vue的时候,安装electron不能选用原装的electron,也不要使用网上很多人说的SimulatedGREG/electron-vue,使用原装electron的话,配置是个大坑,我折腾了半天没搞定。使用SimulatedGREG/electron-vue的话,版本太老,跟现在新版vue的兼容性不是太好。应该使用vue的electron插件。直接在项目目录下执行

vue add electron-builder

即可

2.Electron打包的坑

主要是中文路径的问题。具体参见我的另一篇博文
https://blog.csdn.net/kyq0417/article/details/111266776

3.Asar打包的坑

electron打包的时候,默认会使用asar将资源打包成一个压缩包。但是在使用的过程中,我发现一部分图片不能正确加载了。注意,是一部分,不是所有。经过各种尝试和排查,最终发现,问题出在路径的大小写上。没有打包的资源文件路径,是不区分大小写的。但是打包成asar压缩包后,资源路径是大小写敏感的,也就是说不能正确加载的那部分图片,是因为路径里的大小写错了导致的。

4.使用require(‘XXXXX’)加载的坑

在electron环境下,渲染进程中使用require(‘XXXXX’)加载插件,会报错。原因没有太深入研究。解决方案如下
首先是background.js中创建窗口时,要打开两个选项。这两个选项的具体含义自行查文档吧。

    win = new BrowserWindow({
        webPreferences: {
            nodeIntegration: true,
            enableRemoteModule: true, 
        }
    })

其次,在页面上使用require(‘XXXXX’)的时候,改为

window.require('XXXXX')

5.使用Edge调用C# 代码的坑

1). 不要使用原装Edge

会报错。类似下面这样
[Error: The edge module has not been pre-compiled for node.js version v12.4.1. You must build a custom version of edge.node. Please refer to https://github.com/tjanczuk/edge for building instructions.]

初步怀疑是因为Edge太久不更新。不支持现在版本的nodejs导致的。使用electron-edge-js可解决
https://github.com/agracio/electron-edge-js

2).引入C#类库时不要使用netcore版本。

Edge的文档里提到支持.net core,但是我在使用的时候,引入类库,调用时会报错

未能加载文件或程序集“System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件

原因未知,即使我将这个dll复制过来,还是报错。目前没有找到解决方案,如果谁知道答案我们可以讨论一下。
所以我目前只能引入.net framework 4.6版本的类库

3).引入类库,初始化方法时报错

错误内容如下

Loading non-context-aware native module in renderer: '\\?\{{我的项目文件夹}}\node_modules\electron-edge-js\lib\native\win32\x64\12.14.1\edge_nativeclr.node', but app.allowRendererProcessReuse is true. See https://github.com/electron/electron/issues/18397.

解决方法:
在background.js中,将app.allowRendererProcessReuse设置为false,代码示例如下

'use strict'

import { app, protocol, BrowserWindow , globalShortcut} from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
//import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
app.allowRendererProcessReuse = false;//在此处设置为false即可

4).C#方法定义和传参的坑

这个问题严格意义上不算是坑,在edge的文档中有提到,只是写的有点模糊,我一开始理解错了。
定义方法必须是

  public async Task<object> MyMethod(dynamic P)

注意,
首先,这里的返回值必须是Task,不能是Task或者Task或者其他的什么,否则会报错。
其次,参数数量只能是1个。不能写多个参数
再次,参数如果是简单类型,例如int,string是可以的。但是当参数类型是自定义的类型,那么方法参数必须写dynamic 类型。不能是其他类型。即使是写成object也不行。也会报错。

关于这个问题,更详细的参见edge文档
https://github.com/tjanczuk/edge#how-to-marshal-data-between-c-and-nodejs

6.发布后,无法加载模块electron-edge-js的坑

发布后,会报错

Cannot find module 'electron-edge-js'

这个坑不知道是electron-edge-js还是electron的。所以单独拿出来写一条。
解决方案也很简单。但是找到这方案却十分困难。
方案是在vue.config.js中添加配置项。

externals: ['electron-edge-js']

但是要注意的是,这个配置项是electronBuilder的属性,不是electronBuilder.builderOptions的属性。
我的vue.config.js全文如下

module.exports = {
    chainWebpack: config => {
        config
            .plugin('html')
            .tap(args => {
                args[0].title = "XXXXXXXXXXXXXXX"
                return args
            })
    },
    pluginOptions: {
        electronBuilder: {
            builderOptions: {
                appId: "XXXXXXXXXXXXXXX",
                productName: "XXXXXXXXXXXXXXX",
                asar: false,
                extraFiles: 'XXXXXXXXXXXXXXX',
                directories: {
                    output: 'XXXXXXXXXXXXXXX'
                },
                win: {
                    target: ["dir"]
                }
            },
            externals: ['electron-edge-js']
        }
    }
}; 

最终这个问题的答案是来自
electron-vue跨平台桌面应用开发实战教程(八)——edgejs调用C# dll

文章最后提到了这个问题。但是对于需要加的这个配置项的位置没有详细说明。我加了几次都没加对。最后也是在他的源码里才找到正确位置。源码链接如下
electron-vue-demos

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐