#29 Electron 打包应用程序

今天我们来用 electron-forge 打包程序。

新增 electron-forge 到专案

npm i -D @electron-forge/cli

然後执行:

npm exec --package=@electron-forge/cli -c "electron-forge import"

这样它就会自动帮你把需要的都安装好了。

你的 package.json 也会增加一些关於 electron-forge 的设定。
然後它会把之前写的 start script 改掉,但不用担心。

"scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make"
},

它会把 start package make 都弄好,开发时要启动还是一样 npm start 就可以了。

make

现在只需要执行 npm make 它就会帮你生成安装档了。

在 package.json 中我们可以看到有个 makersconfig.forge 里:

"makers": [
    {
        "name": "@electron-forge/maker-squirrel",
        "config": {
            "name": "click_serve"
        }
    },
    {
        "name": "@electron-forge/maker-zip",
        "platforms": [
            "darwin"
        ]
    },
    {
        "name": "@electron-forge/maker-deb",
        "config": {}
    },
    {
        "name": "@electron-forge/maker-rpm",
        "config": {}
    }
]

这就是它会打包的各种东东。
但要在「目标」的作业系统上打包喔。

这样我们就打包好我们的程序了!

松鼠闪闪

然後就可以双击安装!

接着发现安装时程序闪来闪去...

因为 Squirrel 会在安装时开关几次程序。

为了预防闪瞎使用者,我们用 electron-squirrel-startup 来阻止安装时的启动。

npm i electron-squirrel-startup

然後在 main.js 中 app.whenReady 的部分加上:

if (require("electron-squirrel-startup")) return;

createWindow 前结束就可以解决这个问题了。

复制范例网站到安装後的资料夹

还记得我们的程序预设的网站资料夹是程序执行位置旁的 www 吧。
我们不希望使用者刚开程序什麽都不设定直接执行的时候是显示 Not Found。
所以我们会在安装的目录资加范例 www 资料夹。

理论上是可以在 package.json 中设定 afterExtract 来自动复制的。
但我不知道为什麽 Squirrel 没包含它...

但没关系,因为我们有 Source,所以我们在程序启动时检查资料夹存在与否,如果不存在就复制。

一样是在 main.js 的 app.whenReady 中加上:

if (process.platform === "win32") copyExample();

copyExample

其实就是递回复制档案。

function copyExample() {
    const fs = require("fs");
    const path = require("path");

    if (!fs.existsSync(path.join(process.cwd(), "www")) && fs.existsSync(path.join(process.cwd(), "resources", "app", "www")))
        copyFolderSync(path.join(process.cwd(), "resources", "app", "www"), path.join(process.cwd()));

    function copyFileSync(source, target) {
        let targetFile = target;
        if (fs.existsSync(target) && fs.lstatSync(target).isDirectory()) targetFile = path.join(target, path.basename(source));
        fs.writeFileSync(targetFile, fs.readFileSync(source));
    }

    function copyFolderSync(source, target) {
        const targetFolder = path.join(target, path.basename(source));
        if (!fs.existsSync(targetFolder)) fs.mkdirSync(targetFolder);

        if (fs.lstatSync(source).isDirectory()) {
            fs.readdirSync(source).forEach((file) => {
                const curSource = path.join(source, file);
                if (fs.lstatSync(curSource).isDirectory()) copyFolderSync(curSource, targetFolder);
                else copyFileSync(curSource, targetFolder);
            });
        }
    }
}

这样我们的程序在安装後不设定启动就会用我们的 Example 网站罗!

明天呢

明天就是最後一天了!看看要不要简单说一下 TypeScript 或 Deno。


每日铁人赛热门 Top 10 (1012)

以 10/12 20:00 ~ 10/13 20:00 文章观看数增加值排名

  1. +176 23 - 建立结构化的 Log (1/4) - Elastic Common Schema 结构化 Log 的规范
    • 作者: 乔叔
    • 系列:乔叔带你上手 Elastic Stack - 探索与实践 Observability
  2. +127 [职场]新工程师报到,如何协助他成为有效战力
    • 作者: 宝宝出头天
    • 系列:全端工程师生存笔记
  3. +124 [访谈] APCS x 自学生 Jason
    • 作者: skyhong2002
    • 系列:深入高中程序设计能力指标 APCS
  4. +124 除了刷题之外的事 - Software Engineering
    • 作者: WeiYuan
    • 系列:LeetCode 双刀流:Python x JavaScript
  5. +120 Day 24: 人工智慧在音乐领域的应用 (AI作曲- RNN作曲)
    • 作者: fd2
    • 系列:人工智慧在音乐领域的应用
  6. +119 Day 22: 人工智慧在音乐领域的应用 (AI作曲-基因演算法五 基於规则(Rule-Based)的Fitness Function)
    • 作者: fd2
    • 系列:人工智慧在音乐领域的应用
  7. +118 Day 27: 人工智慧在音乐领域的应用 (索尼-Flow Machine、谷歌-Magenta )
    • 作者: fd2
    • 系列:人工智慧在音乐领域的应用
  8. +112 Day 23: 人工智慧在音乐领域的应用 (AI作曲-基因演算法六 总要敬老尊贤吧?)
    • 作者: fd2
    • 系列:人工智慧在音乐领域的应用
  9. +107 LeetCode 双刀流:62. Unique Paths
    • 作者: WeiYuan
    • 系列:LeetCode 双刀流:Python x JavaScript
  10. +99 Day_30:让 Vite 来开启你的Vue之 内牛满面 的 完赛感言
    • 作者: Winnie Wu
    • 系列:前端黑洞计画 (一) : 让 Vite 来开启你的Vue

再次恭喜 Sky 同学进到每日前十!


<<:  [Day28] 正规表达式 Regular Expression

>>:  [Day_29]函式与递回_(8)

[ Day 04 ] Virtual DOM ? ReactDOM ?

还记得我们在 Day 02 的时候有跟大家提到 React.js 是使用 Virtual DOM ...

Day 16 | 元件状态:预载 及 延迟载入 Prefetch & Defer Loading

今天因为这两个功能都比较简单,因此合在一起讲。分别是 预载(Prefetching) 与 延迟载入(...

Day 11 : psycopg2 操作

今天拉回 python 来介绍 psycopg2,这个套件可以跟 postgres 进行互动。我们依...

Day 3 - Android Studio 的设置

Day 3 -Android Studio 的设置 听了前面那些介绍,想必大家已经很迫不期待的想要开...

离职倒数10天:做产品才知道政治敏感不只存在两岸之间

我第一次在微软 release 产品时,学到一件很意外的事是:这世界上政治敏感区域原来不只有台湾跟中...