electron-builder打包exe的问题记录

1,115 阅读2分钟
环境: 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.tspublicPath: './'

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 盘 → 勾选「缩略图」→ 确定。即可将图标缓存文件顺利删除。