Jacky's Blog Jacky's Blog
  • 首页
  • 关于
  • 项目
  • 大事记
  • 留言板
  • 友情链接
  • 分类
    • 干货
    • 随笔
    • 项目
    • 公告
    • 纪念
    • 尝鲜
    • 算法
    • 深度学习
  • 4
  • 0

Electron 跨平台桌面应用开发与打包

Jacky
18 7 月, 2021
目录
  1. 开发
    1. 包管理器
    2. 初始化
      1. vue.config.js 配置优化打包
      2. 安装依赖包
      3. 运行调试
  2. 打包

去年写 ProfileCounter 的时候就是用的这套架构进行开发和打包,前后用了几天时间,一直想找机会写个总结,终于在这个暑假有时间来写了。

Electron 允许你使用 HTML, JavaScript, CSS 来开发一个桌面级应用,它在打包时加入了 Chrome 的内核 Chromium,这样就可以运行 Node.js 构建好的网页,同时 Electron 还带来了特殊的 API,允许调用操作系统的功能,更多使用文档请参考 https://www.electronjs.org/docs。

本文以 Vue 为示例,将编写好的利润计算网页分别打包成 x86 架构下 64 位的 Windows、Mac 应用,以及 arm64 架构下的 Mac 应用(原生支持 M1)。

开发

包管理器

强烈推荐使用 yarn 作为默认的包管理器,使用 npm 的话在国内需要替换镜像源,部分源可能版本号缓存的方式与 Electron 的版本号管理方式不同,造成依赖安装出错等各种奇怪的问题。

初始化

可以在 vue ui 中创建项目,或直接新建文件夹,并使用 vue create <项目名> 进行初始化。

修改 packages.json 的内容:

"author": "你の名字",
"scripts": {
        "lint": "vue-cli-service lint",
        "build": "vue-cli-service electron:build --mac --win --x64 --arm64",
        "start": "vue-cli-service electron:serve",
        "postinstall": "electron-builder install-app-deps",
        "postuninstall": "electron-builder install-app-deps"
},
"main": "background.js",
"appId": "cn.jackyu.profitcounter",
"copyright": "Copyright © year ${author}",

在 devDependencies 对象中增加

"electron": "^13.1.6",
"electron-devtools-installer": "^3.1.0",
"vue-cli-plugin-electron-builder": "^2.0.0",
"electron-builder": "22.10.4"

electron-builder@22.10.4 (这个版本截止到撰写本文时可以正常在 M1 上编译,并不意味着其他版本不行,这里只是给个参考)

在 src 目录下新建 background.js 文件并写入以下内容

'use strict'

import {app, protocol, BrowserWindow} 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'

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
    {scheme: 'app', privileges: {secure: true, standard: true}}
])

async function createWindow() {
    // Create the browser window.
    const win = new BrowserWindow({
        width: 1750,
        height: 700,
        //resizable: false,
        webPreferences: {
            // Use pluginOptions.nodeIntegration, leave this alone
            // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
            //nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
            enableRemoteModule: true,
            nodeIntegration: true,
            contextIsolation: false // fix 13.x require issue
        }
    })

    if (process.env.WEBPACK_DEV_SERVER_URL) {
        // Load the url of the dev server if in development mode
        await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
        if (!process.env.IS_TEST) win.webContents.openDevTools()
    } else {
        createProtocol('app')
        // Load the index.html when not in development
        win.loadURL('app://./index.html')
    }
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
    if (isDevelopment && !process.env.IS_TEST) {
        // Install Vue Devtools
        try {
            await installExtension(VUEJS_DEVTOOLS)
        } catch (e) {
            console.error('Vue Devtools failed to install:', e.toString())
        }
    }
    createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
    if (process.platform === 'win32') {
        process.on('message', (data) => {
            if (data === 'graceful-exit') {
                app.quit()
            }
        })
    } else {
        process.on('SIGTERM', () => {
            app.quit()
        })
    }
}

vue.config.js 配置优化打包

pluginOptions: {
        electronBuilder: {
            nodeIntegration: true,
            builderOptions: {
                win: {
                    icon: 'src/assets/icon.ico',
                    // 图标路径 windows系统中icon需要256*256的ico格式图片,更换应用图标亦在此处
                    target: [{
                        // 打包成一个独立的 exe 安装程序
                        target: 'nsis',
                        // 这个意思是打出来32 bit + 64 bit的包,但是要注意:这样打包出来的安装包体积比较大,所以建议直接打32的安装包。
                        'arch': [
                            'x64',
                            // 'ia32'
                        ]
                    }]
                },
                mac: {
                    icon: 'src/assets/icon.png',
                    target: {
                        target: 'dmg',
                        arch: [
                            'x64',
                            'arm64'
                        ]
                    }
                },
                files: ['**/*'],
                //asar: false,
                nsis: {
                    // 是否一键安装,建议为 false,可以让用户点击下一步、下一步、下一步的形式安装程序,如果为true,当用户双击构建好的程序,自动安装程序并打开,即:一键安装(one-click installer)
                    oneClick: false,
                    // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
                    allowElevation: true,
                    // 允许修改安装目录,建议为 true,是否允许用户改变安装目录,默认是不允许
                    allowToChangeInstallationDirectory: true,
                    // 安装图标
                    installerIcon: 'src/assets/icon.ico',
                    // 卸载图标
                    uninstallerIcon: 'src/assets/icon.ico',
                    // 安装时头部图标
                    installerHeaderIcon: 'src/assets/icon.ico',
                    // 创建桌面图标
                    createDesktopShortcut: true,
                    // 创建开始菜单图标
                    createStartMenuShortcut: true
                }
            }
        }
    }

安装依赖包

yarn install

运行调试

yarn start

稍后,调试 App 启动成功

Electron 跨平台桌面应用开发与打包-Jacky's Blog
Hello World

接下来就可以进行常规的 Vue 开发了!

打包

先说一下环境

OS: macOS 11.4
CPU: Apple M1
node version: 16.5.0
electron-builder: 22.10.4

如果打包时出现的错误不是由于网络引起的,比如

Error: editions-autoloader-edition-incompatible: editions-autoloader-edition-incompatible: The edition [TypeScript compiled against ES2019 for web browsers with Import for modules] is not compatible with this environment.

可以尝试将 node 降级到 15.14.0

npm install -g n
sudo n 15.14.0

这个 n 可以切换不同的 node 版本,n use <version>,更多用法参考 n -h

注:node 16.x 是目前原生支持 Apple Silicon 的首个大版本,15.x 为 Intel 架构。

以下是打包产物,可以进行分发。

Electron 跨平台桌面应用开发与打包-Jacky's Blog
打包产物

以上就是本文的全部内容,欢迎讨论。

文章最后修订于 2021年8月19日

4
本文系作者 @Jacky 原创发布在 Jacky's Blog。未经许可,禁止转载。
selenium 与 ChromeDriver 入门
上一篇
20
下一篇

评论 (0)

再想想
暂无评论

近期评论

  • Jacky 发表在《留言板》
  • 菜鸟 发表在《留言板》
  • merlin 发表在《留言板》
  • orz 发表在《Xcode 中使用 Clang-format》
  • Jacky 发表在《关于》
4
Copyright © 2016-2025 Jacky's Blog. Designed by nicetheme.
粤ICP备16016168号-1
  • 首页
  • 关于
  • 项目
  • 大事记
  • 留言板
  • 友情链接
  • 分类
    • 干货
    • 随笔
    • 项目
    • 公告
    • 纪念
    • 尝鲜
    • 算法
    • 深度学习

搜索

  • Mac
  • Apple
  • OS X
  • iOS
  • macOS
  • Linux
  • 阿里云
  • WordPress
  • 运维
  • macOS Sierra

Jacky

Go Python C C++ | 弱冠之年 | 物联网工程
183
文章
192
评论
267
喜欢