前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >electron 踩坑总结

electron 踩坑总结

作者头像
Cell
发布2022-09-23 08:01:33
2.2K0
发布2022-09-23 08:01:33
举报
文章被收录于专栏:Cell的前端专栏

总结一下最近 electron 开发遇到的问题和一些重要知识点。

简介

如果你可以建一个网站,你就可以建一个桌面应用程序。 Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的开源框架,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。

知识点

进程

electron 由两种进程组成,包括主进程和 0 个或 n 个渲染进程

  1. 主进程:承担应用的生命周期(包括启动,退出,准备,正在切换到后台,正在切换到前台等,还负责与原生操作系统 API 通信)
  2. 渲染进程:做 web 页面的 ui,渲染进程之间独立在各自的单线程,渲染进程之间相互隔离,不能直接访问操作系统,需要通信到主线程,在通过主线程操作访问操作形态,一个 BrowserWindow 实例即为一个渲染进程

技术栈

electron 整合了 Node 和浏览器的所有能力,可以随意发挥这些技术栈的特点。由于固定浏览器内核,可以无需考虑兼容性地使用 html/js/css 新特性。

镜像仓库

安装 electron 时,可能因为网络问题导致下载失败,需要使用镜像仓库来下载。

1 2 3 4

# 设置 electron 镜像仓库 # https://registry.npmmirror.com/-/binary/electron # 13.1.7 版本 下载链接可能会拼错导致 404,要设置成 https://registry.npmmirror.com/-/binary/electron/v npm config set electron_mirror=https://npmmirror.com/mirrors/electron/

remote

不要频繁使用 remote, 更多应该手动进行和主进程之间的通信。

使用时需在窗口创建时设置 webPreferences.enableRemoteModuletrue

旧版本的 electron.remote 已经弃用,应该使用依赖 electron/remote 代替。

使用了旧版本的 remote 时会有控制台警告信息:

1

(electron) The remote module is deprecated. Use https://github.com/electron/remote instead.

  • 获取当前窗口:remote.getCurrentWindow()

问题点

打开外部浏览器

electron 的 shell 模块,可以使用 shell.openExternal(url) 在默认浏览器打开链接。

防抖与节流

防抖:短期内大量触发事件时,只执行最后一次。

1 2 3 4 5 6 7 8 9

function debounce(fn) { let timer = null; return function() { clearTimeOut(timer); timer = setTimeOut(() => { fn.applay(this, arguments); }, 300) } }

节流:短期内大量触发事件时,只执行第一次。

1 2 3 4 5 6 7 8 9 10

function throttle(fn) { let timer = null; return function() { if (timer) return; timer = setTimeOut(() => { fn.applay(this, arguments); timer = null; }, 300) } }

devTools

初始化窗口时设置 webPreferences.devToolstrue,然后通过 mainWindow.webContents.openDevTools() 打开开发者工具。

如果只在开发环境启用开发者工具,则需要设置 webPreferences.devToolsprocess.env.NODE_ENV === 'development'

启动白屏

在创建窗口时设置 show: false,在 ready-to-show 事件之后执行 mainWindow.show()

可见官方文档 优雅地显示窗口

启动前 loading

额外创建一个 loading 窗口,该窗口可设置为透明只包含 loading 图标和文字,在 mainWindow.show() 后关闭。

启动后 loading

如果使用了 Vue 框架,在 Vue 初始化之前窗口虽然出现了,但是内容时空白的,可以在 Vue 实例 #app 里写一个 loading, Vue 加载完后会覆盖掉。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

<div id="app"> <!-- Display the loading icon and text until Vue initialization is complete --> <style type="text/css"> html,body { height: 100%; margin: 0; } body { display: flex; } #app { margin: auto; display: flex; align-items: center; } @media (prefers-color-scheme: dark) { body { color: #fff; background-color: #202124; }} </style> <svg xmlns="http://www.w3.org/2000/svg" style="margin:auto;background:0 0" width="60" height="60" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" display="block"> <circle cx="50" cy="50" r="20" stroke-width="4" stroke="#a5a5a5" stroke-dasharray="31.416 31.416" fill="none" stroke-linecap="round" transform="rotate(67.21 50 50)"> <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" keyTimes="0;1" values="0 50 50;360 50 50"/> </circle> </svg> <span>加载中 ...</span> </div>

阻止窗口关闭

可以在关闭前一些事件里做拦截,比如:onbeforeunload 等,详见 实例事件

手动关闭窗口

当自定义关闭时,使用 mainWindow.destroy() 来关闭窗口,因为使用 mainWindow.close() 时,windows 系统打开开发者工具时会出现无法关闭窗口的情况。

全局快捷键

当 electron 版本较低时,比如 13.1.7,会出现在 mac 系统上复制粘贴等常用快捷键失效的问题。可通过设置菜单并绑定快捷键的方式解决。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

const main = [ { label: '', submenu: [ { label: '关于', role: 'about' }, { label: '关闭', role: 'close' }, { label: '退出', role: 'quit' } ] }, { label: '编辑', submenu: [ { label: '撤销', role: 'undo' }, { label: '恢复', role: 'redo' }, { type: 'separator' }, { label: '剪切', role: 'cut' }, { label: '复制', role: 'copy' }, { label: '粘贴', role: 'paste' }, { type: 'separator' }, { label: '全选', role: 'selectAll' } ] } ] const dev = [ { label: '开发者', submenu: [ { label: '刷新', role: 'reload' }, { label: '强制刷新', role: 'forcereload' }, { type: 'separator' }, { label: '开发者工具', role: 'toggledevtools' } ] } ] if (process.env.NODE_ENV === 'development') { main.push(...dev) } export default main

1 2 3 4 5 6 7

import memuConfig from './menu' import { Menu } from 'electron' if (process.platform === 'darwin') { const menu = Menu.buildFromTemplate(memuConfig) Menu.setApplicationMenu(menu) }

electron-builder

下载时,可能因为网络问题导致下载失败,可设置 GitHub 下载镜像。

1 2

# GitHub 仓库下载地址前缀镜像 # disturl=https://registry.npmmirror.com/-/binary/

或者去 GitHub 手动下载,然后解压到缓存目录:

  • macOS: ~/Library/Caches/electron-builder/
  • linux: ~/.cache/electron-builder/
  • windows: %LOCALAPPDATA%\electron-builder\cache\

mac 上缓存目录如下,其他可 参考

1 2 3 4 5 6 7

▸ nsis/ ▸ nsis-resources-3.4.1/ ▸ nsis-3.0.4.1/ ▸ winCodeSign/ ▸ winCodeSign-2.6.0/ ▸ wine/ ▸ wine-4.0.1-mac/

windows 打包

windows 系统打包配置,当没有配置签名时,sign 字段应删除或者配置为 null,否则可能导致打包时报错。

1 2 3 4 5 6 7 8

{ "win": { "icon": "static/icons/icon.ico", "verifyUpdateCodeSignature": false, "target": "nsis", "sign": null } }

macOS 打包

问题:mac 升级之后 electron 打包报错 Exit code: ENOENT. spawn /usr/bin/python ENOENT

解决:网上搜到的下载 python 2.7 是治标不治本,正确做法是升级 electron-builder23.0.2 或更高版本,参考 electron-builder#6726

参考链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 知识点
    • 进程
      • 技术栈
        • 镜像仓库
          • remote
          • 问题点
            • 打开外部浏览器
              • 防抖与节流
                • devTools
                  • 启动白屏
                    • 启动前 loading
                    • 启动后 loading
                  • 阻止窗口关闭
                    • 手动关闭窗口
                      • 全局快捷键
                        • electron-builder
                          • windows 打包
                          • macOS 打包
                      相关产品与服务
                      云开发 CLI 工具
                      云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档