前言
最近在学习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打包,一旦压缩图片,就会报错,如图所示:
起初我是懵逼的,因为这看不到有效的报错信息啊,但是经过阅读源码网上查找解决方案,最终发现了端倪。在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…