electron 爬坑记

2,569 阅读3分钟

前言

最近在学习react,打算开发一款压缩图片的客户端工具练练手,于是开始了electron的学习,这过程中遇到了一些坑,就此记录下来。

在浏览器环境中使用 nodejs api

因为开发结合了react,所以会用到webpack,在调试环境下electron打开的是webpack提供的服务器地址:

// Create the browser window.
    mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { webSecurity: false } })
    mainWindow.setMinimumSize(800, 600)
    mainWindow.webContents.openDevTools()

    // and load the index.html of the app.
    //   mainWindow.loadFile('index.html')
    mainWindow.loadURL('http://127.0.0.1:3000')

所以要是在react工程中直接require nodejs的原生包,就会报运行错误,因为nodejs原生包调用了很多的底层api,浏览器当然没有给到这个权限,所以,要想在浏览器中使用nodejs的api,需要用下面这种方式引入原生Nodejs包:

const electron = window.require('electron')
const process = window.require('process')
const fs = window.require('fs')
const Https = window.require('https')

electron将nodejs api挂载在了window对象上,来与底层进行通信,所以需要调用window上的require函数来引入 nodejs 包。

在浏览器环境中使用app对象

在electron主进程中使用app对象直接require electron就行了

const { app } = require('electron')

但是在渲染进程中使用app对象则需要这样引入:

const electron = window.require('electron')
const app = electron.remote.app

哈哈,不知道的话很懵逼吧。

在浏览器环境中使用第三方nodejs包

如果在浏览器中require第三方nodejs包肯定是会报错的,所以需要创建window的时候预先引入第三方依赖包,代码如下

// main.js
mainWindow = new BrowserWindow({ 
    width: 800, 
    height: 600, 
    webPreferences: { 
        webSecurity: false,
        preload: path.resolve(__dirname, './public/renderer.js')
    },
})
// ./public/renderer.js
global.imagemin = require('imagemin')
// window环境下代码
const imagemin = window.imagemin

打包后无法运行二进制文件

这个压缩图片的工具用到了 imagemin这个npm包,在开发的时候压缩图片没任何问题,但是经过electron打包,一旦压缩图片,就会报错,如图所示:

qq20190201-164247 2x

起初我是懵逼的,因为这看不到有效的报错信息啊,但是经过阅读源码网上查找解决方案,最终发现了端倪。在debugger的过程中,发现imagemin是使用二进制可执行文件来对图片进行压缩的,执行二进制的函数是child_process.spawn,这个函数对于文件路径有限制,因为electron打包后,会把依赖项压缩成一个文件,导致这个函数判断路径时报错,对于这个问题,如果是自己的代码中使用了二进制文件,则可以将child_process.spawn替换为child_process.execFile函数来执行二进制文件。

但是我这里引用的是别人的包,如果擅自修改非本源的包,可能会导致项目无法在其他的环境中运行,所以得找例外的解决方案,皇天不负苦心人,终于找到了解决方案,那就是electron打包时,不对依赖项进行压缩,那样就能得到一个正确的路径了。

解决方案

修改package.json中的build选项,这个选项是对electron打包的一系列配置。将其中的 asar 修改为false,就能让electron在打包时,不对依赖进行压缩,如下所示:

"build": {
    "appId": "com.richard.image_compress",
    "mac": {
      "category": "tool"
    },
    "extends": null,
    "files": ["build", "*.js", "public"],
    "asar": false
}

尾声

随着爬完了这一系列的坑,图片压缩的客户端工具终于完成。

git repo: github.com/Richard-Cho…