环境: macOS Big Sur 11.6.8 M1,
目录结构:
your-app/
├── package.json
├── code // vue或react打包生成的代码
├── favicon.ico
├── favicon.png
├── main.js
├── preload.js
├── dist // exe打包后生成的文件
├── preload.js
└── renderer.js // 这个文件是空代码,待研究
注意事项:
1、路由模式是hash;
2、如果vue或react项目,尽量不要把文件放在public目录下,比如fonts,因为它会直接索引到根目录导致找不到文件;
3、如果是umi项目打包,记得修改.umirc.ts中publicPath: './';
1、安装插件【一定要安装在dev】
yarn和npm 两种安装方式 各取所需
npm i electron --save-dev
yarn add --dev electron
npm i electron-builder --save-dev
yarn add --dev electron-builder
2、package.json的配置
{
"name": "test",
"version": "1.0.0",
"description": "test",
"main": "main.js",
"build": {
"appId": "com.test.app",
"copyright": "test",
"files": [
"!out/**/*","!dist/**/*"
],
"mac": {
"target": [
"dmg",
"zip"
]
},
"win": {
"icon": "./favicon.ico",
"target": [
"nsis",
"zip"
],
"signingHashAlgorithms": [
"sha1",
"sha256"
]
},
"nsis": {
"oneClick": false,
"perMachine": true,
"shortcutName": "test",
"createDesktopShortcut": true,
"allowToChangeInstallationDirectory": true
}
},
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"dist": "electron-builder",
"make": "electron-forge make",
"build": "electron-builder --win --x64"
},
"repository": "https://github.com/electron/electron-quick-start",
"keywords": [
"Electron",
"demo"
],
"author": "dh",
"license": "CC0-1.0",
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.65",
"@electron-forge/maker-deb": "^6.0.0-beta.65",
"@electron-forge/maker-rpm": "^6.0.0-beta.65",
"@electron-forge/maker-squirrel": "^6.0.0-beta.65",
"@electron-forge/maker-zip": "^6.0.0-beta.65",
"electron": "^17.1.0",
"electron-builder": "^23.3.3"
},
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "electron_quick_start"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
]
}
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0"
}
}
3、main.js的配置
// Modules to control application life and create native browser window
const {app, BrowserWindow, Menu} = require('electron')
const path = require('path')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
},
fullscreen: true
})
Menu.setApplicationMenu(null)
// and load the index.html of the app.
// mainWindow.loadFile('index.html')
mainWindow.loadFile(`${__dirname}/code/index.html`)
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// 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.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// 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()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
4、路由是history模式时,增加配置;
(1)、增加express;
npm i express --save-dev
yarn add --dev express
(2)、修改main.js;
// Modules to control application life and create native browser window
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
const express = require('express');
const application = express();
const START_PORT = 50001; // 不同的项目,不同的端口,要不然会报错
let localServer;
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
},
fullscreen: true
})
// and load the index.html of the app.
// mainWindow.loadFile('index.html')
// mainWindow.loadFile(`${__dirname}/code/index.html`)
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// 启动一个node服务也就是用node部署打包后的文件
proxys().then((res) => {
Menu.setApplicationMenu(null)
mainWindow.loadURL(`http://127.0.0.1:${START_PORT}`);
});
}
// 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.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// 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()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
localServer.close();
if (process.platform !== 'darwin') app.quit()
})
function proxys() {
return new Promise((resolve, reject) => {
// 这一步是用户前端项目是history路由比如写的相关配置
application.use(express.static(path.resolve(__dirname, 'code')));
application.get('*', function (request, response) {
response.sendFile(path.resolve(__dirname, 'code', 'index.html'));
});
localServer = application.listen(START_PORT, () => {
resolve();
});
});
}
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
4、打包文件过大的问题;
"files": [
"!out/**/*","!dist/**/*"
],
这个是重点,一定要排除一些不必要的文件
5、桌面图标不更新的问题;
打开开始菜单,找到 开始[系统菜单] → 磁盘清理 → C 盘 → 勾选「缩略图」→ 确定。即可将图标缓存文件顺利删除。