笔记贴:突然要用,每次都忘,记录下过程。没有使用
electron-packager打包的原因是测试过打包后体积上100M太大,暂时放弃。
node -v
v10.16.3
electron -v
v6.0.9
npm -v
6.9.0
文件夹结构 单package.json结构 ,因参考官方文档显示:
Since version 8 electron-builder rebuilds only production dependencies, so, you are not forced to use two package.json structure.
二个文件夹说明
修改如下 注释需手动自己删掉才可运行:
{
"name": "appTest",
"version": "1.0.1",
"main": "main.js",
"author":"human",
"scripts": {
"start": "electron .",
"builder": "electron-builder"
},
"build": {
"appId": "com.ideal.app",
"productName": "一个测试",
"copyright" :"Copyright © 2019 ${author}",
"asar": false, //asar 是否生成取决于配置项"asar": false不生成asar文件, 需要的话改为true
"compression":"store",
"directories": {
"output": "../builds" //输出打包文件的目录
},
"publish": [
{
"provider": "generic",
"url": "http://127.0.0.1:8080" //更新服务器地址
}
],
"win": {
"icon": "./assets/favicon.ico",
"target": [
"nsis",
"zip"
],
"artifactName": "${productName}_setup_${version}.${ext}",
"timeStampServer": "http://timestamp.digicert.com"
},
"nsis": {
"oneClick": false,
"perMachine": true,
"allowToChangeInstallationDirectory": true, //是否可以更改安装文件夹
"allowElevation": true,
"installerIcon": "favicon.ico",
"installerSidebar":"./assets/installerSidebar164X314.bmp",
"createDesktopShortcut": true,
"runAfterFinish": true,
"installerIcon": "./assets/favicon.ico",
"uninstallerIcon": "./assets/favicon.ico",
"license":"license.txt"
}
},
"devDependencies": {
"electron": "^6.0.9",
"electron-builder": "^22.1.0"
},
"dependencies": {
"electron-updater": "^4.2.0"
}
}
const {app, BrowserWindow ,Tray ,Menu,ipcMain} = require('electron')
// 注意这个autoUpdater不是electron中的autoUpdater
const { autoUpdater } = require("electron-updater" )
const path = require('path')
// 一些自定义配置
const package = {
version:"1.0.1",
productEnv:"development",// development products
feedUrl:'http://127.0.0.1:8080/'
};
const uploadUrl = 'http://127.0.0.1:8080/'
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
function updateHandle() {
let message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载……',
updateNotAva: '现在使用的就是最新版本,不用更新',
};
const os = require('os');
autoUpdater.setFeedURL(uploadUrl);
autoUpdater.on('error', function (error) {
console.log(error);
sendUpdateMessage(message.error)
});
autoUpdater.on('checking-for-update', function () {
console.log(message);
sendUpdateMessage(message.checking)
});
autoUpdater.on('update-available', function (info) {
console.log(message);
sendUpdateMessage(message.updateAva)
});
autoUpdater.on('update-not-available', function (info) {
sendUpdateMessage(message.updateNotAva)
});
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
mainWindow.webContents.send('downloadProgress', progressObj)
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
ipcMain.on('isUpdateNow', (e, arg) => {
//
console.log("开始更新");
//some code here to handle event
autoUpdater.quitAndInstall();
});
mainWindow.webContents.send('isUpdateNow')
});
ipcMain.on("checkForUpdate",()=>{
//执行自动更新检查
autoUpdater.checkForUpdates();
})
}
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
function createWindow () {
Menu.setApplicationMenu(null)
//const appIcon = new Tray('icon.ico')
mainWindow = new BrowserWindow({width:1000, height:800, title:'打包测试',icon: path.join(path.join(__dirname, 'assets'), 'favicon.ico'),webPreferences: {
nodeIntegration: true
}})
mainWindow.loadURL(`file://${__dirname}/view/index.html`)
mainWindow.on('closed', function () {
mainWindow = null
})
if(package.productEnv == "development") mainWindow.webContents.openDevTools() // 开启调试
mainWindow.webContents.on('did-finish-load', () => { // 使用通信 版版本信息发送到渲染进程
mainWindow.webContents.send('staticData', {"version":package.version});
})
updateHandle(); // 初始化更新相关监听
}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到myWindow这个窗口
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
app.on('ready', function(){
createWindow();
Menu.setApplicationMenu(null);// 屏蔽electron 默认菜单栏
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X 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 (mainWindow === null) {
createWindow()
}
})
}
因入口文件定义为mainWindow.loadURL(
file://${__dirname}/view/index.html)
index.html文件放在app/view/下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>最新版本:v<span id="update-version"></span>!</h1>
自动更新
<progress id="update-progress" value='0' max='100'></progress>
</body>
</html>
<script crossorigin sssrc="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script>if (typeof module === 'object') {window.jQuery = window.$ = module.exports;};</script>
<script>
const ipcRenderer = require('electron').ipcRenderer
var Upd_version = document.getElementById("update-version");
var Upd_progress = document.getElementById("update-progress");
var Upd_percent = 0;
ipcRenderer.on("staticData",function(event,data){
// 获取配置项数据
console.log(data)
if(data.version) {
Upd_version.innerText = data.version;
if(typeof window.updateVerson == 'function') _app.innerText = data.version;
}
})
ipcRenderer.send("checkForUpdate");
ipcRenderer.on("message", (event, text) => {
console.log(text);
this.tips = text;
});
ipcRenderer.on("downloadProgress", (event, progressObj)=> {
console.log(progressObj);
this.downloadPercent = progressObj.percent || 0;
Upd_progress.value = Number(progressObj.percent);
Upd_percent = Number(progressObj.percent);
});
ipcRenderer.on("isUpdateNow", () => {
ipcRenderer.send("isUpdateNow");
});
</script>
electron-builder官方文档多参考
npm run builder
运行效果:
查看builds文件夹,看是否打包成功, 点击exe安装测试一遍,没有问题代表打包成功
点击exe安装截图:
桌面图标:
// app.js
var express = require('express')
var fs = require('fs')
const path = require('path')
app.use(express.static(path.join(__dirname, './')))
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
node app.js
Example app listening at http://:::8080
检测到新版下载更新, 下载的临时文件存放路径:
查看builds文件夹下win-unpacked\resources\app-update.yml
provider: generic
url: 'http://127.0.0.1:8080'
updaterCacheDirName: apptest-updater
输出的latest.yml中releaseDate总是显示: '2019-11-22T02:42:48.634Z’非当地时间戳,强迫症要调整一下,哈哈
先测试下node的时间输出:
> new Date().toISOString() //The time zone [offset] is always UTC, denoted by the suffix Z
'2019-11-22T02:42:48.634Z'
> new Date().toGMTString()
'Fri, 22 Nov 2019 02:44:25 GMT'
> new Date().toLocaleString()
'2019-11-22 10:44:31 AM'
找到electron-builder所用到的打包模块文件 修改时间为new Date().toLocaleString()
修改后
输出的latest.yml中releaseDate为当地时间 : ‘2019-11-22 10:45:52 AM’
参考:https://blog.csdn.net/Wonder233/article/details/80563236
https://www.jianshu.com/p/15bde714e198