electron开发踩坑
# 打包时只会将 denpendencies 的依赖打包到主进程
所以主进程使用到的依赖,必须安装到 denpendencies 中,否则会报模块不存在。同时,渲染进程使用到的依赖,都打包到 devDependencies,以便将来分离主进程和渲染进程时处 理方便。
# 渲染进程调用 Node API
默认是不能调用的,需要开启设置。见文档 (opens new window)。
new BrowserWindow({
height: 800,
useContentSize: true,
width: 600,
webPreferences: {
contextIsolation: false,
nodeIntegration: true, // 渲染进程可以使用Node API
webSecurity: false,
// 如果是开发模式可以使用devTools
devTools: process.env.NODE_ENV === 'development',
// 在macos中启用橡皮动画
scrollBounce: process.platform === 'darwin'
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 打包后,mac 下无法识别 shell 命令
/bin/sh: node: command not found
见issue (opens new window) 社区的解决方案是fix-path (opens new window)。不过要注意,在 render 进程使用 fix-path 仍会报错,暂时无法解决,只能在 main 进程中使用。
import fixPath from 'fix-path'
fixPath()
await runCommand(projectInfo.buildSript, projectInfo.path)
2
3
4
# Error: Module "path" has been externalized for browser compatibility. Cannot access "path.join" in client code.
看到这个错,以为渲染进程不支持 Node API,其实并不是。测试下其他模块,如:
const childProcess = require('child_process')
childProcess.spawn('npm', ['-v'], { stdio: 'inherit', shell: true })
2
这里出现一个小插曲,控制台报错。
ncaught Error: spawn npm ENOENT
找到类似的问题,见issue (opens new window)
打印process.env
,发现竟然只有项目配置的环境变量,原来的 Node 环境变量居然没有,然后发现是在vite.config.js
中配置了。
export default defineConfig({
mode: process.env.NODE_ENV,
root,
define: {
'process.env': process.env.NODE_ENV === 'production' ? userConfig.build.env : userConfig.dev.env,
},
})
2
3
4
5
6
7
改下为
export default defineConfig({
define: {
'process.env': process.env.NODE_ENV === 'production' ? { ...process.env, ...userConfig.build.env } : { ...process.env, ...userConfig.dev.env },
},
})
2
3
4
5
恢复正常,控制台输出 npm 版本号。
6.14.15
然后进入正题,为啥不支持 path 模块。
网上很多文章提示要安装path-browserify (opens new window),比 如vite 不支持 node 内置模块 (opens new window)。原来 webpack 已内置支持,但 vite 不支持。
安装试试。
npm install path-browserify -D
import 'path' from 'path-browserify'
可以正常使用了。继续往下看。果然很快又报错了,如下:
Error: Module "fs" has been externalized for browser compatibility.
这下没有对应的库做兼容性处理了。不过 vite 社区也有相关插件,处理将 require 转为 import 的写法。 见vite-plugin-commonjs-externals (opens new window)。果然可以,反过来想想,它只是做了支持 import 代替 require,那 之前的 import 引入,是不是直接用 require 就可以了,比如:
import { join, resolve } from 'path'
改为
const { join } = require('path')
果然是可以的,不过既然vite-plugin-commonjs-externals
很香,那就继续用吧。
# renderer 打包后如何获取本地 static 文件
打包之后,process.cwd()与开发环境不同,表现为:
- 开发位于项目根目录
- 打包位于 dist/electron/renderer 目录