今天我们来用 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
就可以了。
现在只需要执行 npm make
它就会帮你生成安装档了。
在 package.json 中我们可以看到有个 makers
在 config.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();
其实就是递回复制档案。
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。
以 10/12 20:00 ~ 10/13 20:00 文章观看数增加值排名
+176
23 - 建立结构化的 Log (1/4) - Elastic Common Schema 结构化 Log 的规范
+127
[职场]新工程师报到,如何协助他成为有效战力
+124
[访谈] APCS x 自学生 Jason
+124
除了刷题之外的事 - Software Engineering
+120
Day 24: 人工智慧在音乐领域的应用 (AI作曲- RNN作曲)
+119
Day 22: 人工智慧在音乐领域的应用 (AI作曲-基因演算法五 基於规则(Rule-Based)的Fitness Function)
+118
Day 27: 人工智慧在音乐领域的应用 (索尼-Flow Machine、谷歌-Magenta )
+112
Day 23: 人工智慧在音乐领域的应用 (AI作曲-基因演算法六 总要敬老尊贤吧?)
+107
LeetCode 双刀流:62. Unique Paths
+99
Day_30:让 Vite 来开启你的Vue之 内牛满面 的 完赛感言
再次恭喜 Sky 同学进到每日前十!
<<: [Day28] 正规表达式 Regular Expression
还记得我们在 Day 02 的时候有跟大家提到 React.js 是使用 Virtual DOM ...
今天因为这两个功能都比较简单,因此合在一起讲。分别是 预载(Prefetching) 与 延迟载入(...
今天拉回 python 来介绍 psycopg2,这个套件可以跟 postgres 进行互动。我们依...
Day 3 -Android Studio 的设置 听了前面那些介绍,想必大家已经很迫不期待的想要开...
我第一次在微软 release 产品时,学到一件很意外的事是:这世界上政治敏感区域原来不只有台湾跟中...