使用 electron 开发桌面应用并打包

一、概要

文档

官网:https://www.electronjs.org/
文档:https://www.electronjs.org/docs

环境准备:

安装 node.js

包管理工具 npm

node -v
npm -v

二、创建一个 Electron DEMO

参考文档:https://www.electronjs.org/docs/tutorial/quick-start#prerequisites

项目架构

从开发的角度来看,Electron 应用本质上是一个 Node.js 应用。 这意味着您的 Electron 应用程序的起点将是一个 package.json 文件,就像在其他的Node.js 应用程序中一样。 最小的 Electron 应用程序具有以下结构:

my-electron-app/
├── package.json
├── main.js
├── preload.js
└── index.html
安装 Electron
mkdir my-electron-app && cd my-electron-app

npm init -y

npm install -g electron
创建主进程脚本文件main.js

主脚本指定了运行主进程的 Electron 应用程序的入口(就我们而言,是 main.js 文件)。 通常,在主进程中运行的脚本控制应用程序的生命周期、显示图形用户界面及其元素、执行本机操作系统交互以及在网页中创建渲染进程。 Electron 应用程序只能有一个主进程。

const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  win.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

上面发生了什么?

  • 第 1 行:为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,您从 electron 包导入了 app 和 BrowserWindow 模块 。
  • 第2行: 导入 path 包,该包为操作文件路径提供了实用的功能。
  • 第 4 行:在此之后,你定义一个方法用来创建一个带有预加载脚本的新的浏览器窗口,并加载index.html文件进入该窗口 (第 13 行,我们将在后面探讨这个文件)。
  • 第 16 行:你通过调用 createWindow方法,在 electron app 第一次被初始化时创建了一个新的窗口。
  • 第 18 行:您添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序。
  • 第 25 行:您添加了一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的。
创建网页 index.html

这是应用程序初始化后您想要显示的页面。 此网页代表渲染过程。 您可以创建多个浏览器窗口,每个窗口都使用自己的独立渲染进程。 你可以选择性地从您的预加载脚本中公开额外的 Node.js API 来授予对它们访问权限。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body style="background: white;">
    <h1>Hello World!</h1>
    <p>
        We are using Node.js <span id="node-version"></span>,
        Chromium <span id="chrome-version"></span>,
        and Electron <span id="electron-version"></span>.
    </p>
</body>
</html>

定义一个预加载脚本 preload.js

您的预加载脚本就像是Node.js和您的网页之间的桥梁。 它允许你将特定的 API 和行为暴露到你的网页上,而不是不安全地把整个 Node.js 的 API暴露。 在本例中,我们将使用预加载脚本从process对象读取版本信息,并用该信息更新网页。

window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const type of ['chrome', 'node', 'electron']) {
    replaceText(`${type}-version`, process.versions[type])
  }
})

上面发生了什么?

  • 第 1 行:首先定义了一个事件监听器,当web页面加载完成后通知你。
  • 第 2 行:接着您定义了一个功能函数用来为index.html中的所有placeholder设置文本。
  • 第 7 行:接下来您遍历了您想展示版本号的组件列表。
  • 第 8 行:最终,您调用 replaceText 来查找index.html中的版本占位符并将其文本值设置为process.versions的值。
修改您的 package.json 文件

您的 Electron 应用程序使用 package.json 文件作为主入口(像任何其它的 Node.js 应用程序)。 您的应用程序的主脚本是 main.js,所以相应修改 package.json 文件

{
    "name": "my-electron-app",
    "version": "0.1.0",
    "author": "your name",
    "description": "My Electron app",
    "main": "main.js"
}

注意:如果未设置 main 字段,Electron 将尝试加载包含在 package.json 文件目录中的 index.js 文件。

注意:author 和 description 字段对于打包来说是必要的,否则运行 npm run make 命令时会报错。

默认情况下, npm start 命令将用 Node.js 来运行主脚本。 要使用 Electron 来运行脚本,您需要将其更改为这样:

{
    "name": "my-electron-app",
    "version": "0.1.0",
    "author": "your name",
    "description": "My Electron app",
    "main": "main.js",
    "scripts": {
        "start": "electron ."
    }
}
运行您的应用程序
npm start

以上过程,其实对应的就是官方提供的DEMO,通过以上过程,你基本了解了一个 electron demo 的开发过程。

克隆示例项目的仓库
git clone https://github.com/electron/electron-quick-start
进入这个仓库
cd electron-quick-start
安装依赖并运行
npm install && npm start

以上 npm命令 如果出现错误,就使用 cnpm 代替,因为我本地安装了 cnpm ,然后在使用 npm命令 的时候有时候报错,换成 cnpm 就好了。

cnpm install && cnpm start

程序可以正常运行。

打包应用程序

安装 electron-packager

npm install -g electron-packager

electron-packager -h

	Usage: electron-packager <sourcedir> <appname> [options...]

    Required parameters

    sourcedir          the base directory of the application source

      Examples:        electron-packager ./
                       electron-packager ./ --all

    Optional parameters

    appname            the name of the app, if it needs to be different from the "productName" or "name"
                       in the nearest package.json

    Options

    version            prints the version of Electron Packager and Node, plus the target platform and
                       arch, for bug reporting purposes, and exits immediately

    * All platforms *

    all                equivalent to --platform=all --arch=all
    app-copyright      human-readable copyright line for the app
    app-version        release version to set for the app
    arch               all, or one or more of: ia32, x64, armv7l, arm64, mips64el (comma-delimited if
                       multiple). Defaults to the host arch
    asar               whether to package the source code within your app into an archive. You can either
                       pass --asar by itself to use the default configuration, OR use dot notation to
                       configure a list of sub-properties, e.g. --asar.unpackDir=sub_dir - do not use
                       --asar and its sub-properties simultaneously.

                       Properties supported include:
                       - ordering: path to an ordering file for file packing
                       - unpack: unpacks the files to the app.asar.unpacked directory whose filenames
                         regex .match this string
                       - unpackDir: unpacks the dir to the app.asar.unpacked directory whose names glob
                         pattern or exactly match this string. It's relative to the <sourcedir>.
    build-version      build version to set for the app
    download           a list of sub-options to pass to @electron/get. They are specified via dot
                       notation, e.g., --download.cacheRoot=/tmp/cache
                       Properties supported:
                       - cacheRoot: directory of cached Electron downloads. For default value, see
                         @electron/get documentation
                       - mirrorOptions: alternate URL options for downloading Electron zips. See
                         @electron/get documentation for details
                       - rejectUnauthorized: whether SSL certs are required to be valid when downloading
                         Electron. Defaults to true, use --no-download.rejectUnauthorized to disable
                         checks.
    electron-version   the version of Electron that is being packaged, see
                       https://github.com/electron/electron/releases
    electron-zip-dir   the local path to a directory containing Electron ZIP files
    executable-name    the name of the executable file, sans file extension. Defaults to appname
    extra-resource     a file to copy into the app's resources directory
    icon               the local path to an icon file to use as the icon for the app.
                       Note: Format depends on platform.
    ignore             do not copy files into app whose filenames RegExp.match this string. See also:
                       https://electron.github.io/electron-packager/master/interfaces/electronpackager.options.html#ignore
                       and --no-prune. Can be specified multiple times
    no-deref-symlinks  make sure symlinks are not dereferenced within the app source
    no-junk            do not ignore system junk files from the packaged app
    no-prune           do not prune devDependencies from the packaged app
    out                the dir to put the app into at the end. Defaults to current working dir
    overwrite          if output directory for a platform already exists, replaces it rather than
                       skipping it
    platform           all, or one or more of: darwin, linux, mas, win32 (comma-delimited if multiple).
                       Defaults to the host platform
    prebuilt-asar      path to a prebuilt asar file (asar, ignore, no-prune, and no-deref-symlinks
                       options are incompatible with this option and will be ignored)
    quiet              Do not print informational or warning messages
    tmpdir             temp directory. Defaults to system temp directory, use --no-tmpdir to disable
                       use of a temporary directory.

    * darwin/mas target platforms only *

    app-bundle-id      bundle identifier to use in the app plist
    app-category-type  the application category type
                       For example, `app-category-type=public.app-category.developer-tools` will set the
                       application category to 'Developer Tools'.
    darwin-dark-mode-support
                       forces support for Mojave/10.14 dark mode in the packaged app
    extend-info        a plist file to merge into the app plist
    helper-bundle-id   bundle identifier to use in the app helper plist
    osx-sign           (macOS host platform only) Whether to sign the macOS app packages. You can either
                       pass --osx-sign by itself to use the default configuration, or use dot notation
                       to configure a list of sub-properties, e.g. --osx-sign.identity="My Name"
                       For info on supported values see https://npm.im/electron-osx-sign#opts---options
                       Properties supported include:
                       - identity: should contain the identity to be used when running `codesign`
                       - entitlements: the path to entitlements used in signing
                       - entitlements-inherit: the path to the 'child' entitlements
    osx-notarize       (macOS host platform only, requires --osx-sign) Whether to notarize the macOS app
                       packages. You must use dot notation to configure a list of sub-properties, e.g.
                       --osx-notarize.appleId="foo@example.com"
                       For info on supported values see https://npm.im/electron-notarize#method-notarizeopts-promisevoid
                       Properties supported include:
                       - appleId: should contain your apple ID username / email
                       - appleIdPassword: should contain the password for the provided apple ID
                       - appleApiKey: should contain an App Store Connect API key
                       - appleApiIssuer: should contain the API key's issuer
    protocol           URL protocol scheme to register the app as an opener of.
                       For example, `--protocol=myapp` would register the app to open
                       URLs such as `myapp://path`. This argument requires a `--protocol-name`
                       argument to also be specified.
    protocol-name      Descriptive name of URL protocol scheme specified via `--protocol`
    usage-description  Human-readable descriptions of how the app uses certain macOS features. Displayed
                       in the App Store. A non-exhaustive list of properties supported:
                       - Camera
                       - Microphone

    * win32 target platform only *

    win32metadata      a list of sub-properties used to set the application metadata embedded into
                       the executable. They are specified via dot notation,
                       e.g. --win32metadata.CompanyName="Company Inc."
                       or --win32metadata.ProductName="Product"
                       Properties supported:
                       - CompanyName (default: author name from nearest package.json)
                       - FileDescription (default: appname)
                       - OriginalFilename (default: renamed exe)
                       - ProductName (default: appname)
                       - InternalName (default: appname)
                       - requested-execution-level (user, asInvoker, or requireAdministrator)
                       - application-manifest

打包命令:

electron-packager <sourcedir> <appname> [options...]

以上命令:

  • 将目录切换到项目所在路径,或者使用参数sourcedir指定。
  • 参数 appname 是打包后的名字。
  • 参数 plateform 确定了你要构建哪个平台的应用(Windows、Mac 还是 Linux),windows是win32。
  • 参数 arch 决定了使用 x86 还是 x64 还是两个架构都用。
  • 参数 app-version 标记版本号,值应该是0.0.1,而不是v0.0.1,否则会报错rcedit.exe failed with exit code 1. Fatal error: Unable to parse version string for FileVersion
  • 第一次打包应用需要比较久的时间,因为所有平台的二进制文件都需要下载,之后打包应用会比较快了。

示例:

electron-packager ./  electronDemo --platform=win32 --arch=x64 --app-version=0.0.1 --icon=./favicon.ico --overwrite --out=./bin

报错

(node:39648) ExperimentalWarning: The fs.promises API is experimental
Cannot find module 'electron' from 'D:\dev\php\magook\trunk\server\electron\electron-quick-start'

第一个错误是版本低了

升级 npm

npm install npm@latest -g
npm -v
7.11.1

下载新版nodejs,重新安装

node -v
v14.16.1

运行程序cnpm install && cnpm start可以正常运行。

重新打开cmd,执行打包命令,发现没有出现上面的两个问题,但是出现了新的问题

read ECONNRESET

这是连接超时,再次执行,发现又没有报错了,提示正在下载electron-v12.0.5-win32-x64.zip,但是速度很慢,最终还是断开了。

尝试修改源的地址

npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/

还是没有效果。

由于未知原因,electron-packger / electron-builder 在真实打包时并不识别npm的镜像地址,此时,你需要修改环境变量

ELECTRON_MIRROR = http://npm.taobao.org/mirrors/electron/

在这里插入图片描述

还别说,快多了。

终于打包完成了。

在这里插入图片描述

但是在resources\app下面居然看到完整的项目代码,这就有点过分吧。而且打包后的总大小177M,其中可执行文件125M,大的离谱!!

双击electronDemo.exe,能正常运行。

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值