Skip to content
索引

electron打包vue

环境要求

需要版本号大于14.0.0的较新的node版本,需要安装vue脚手架命令

bash
npm install -g @vue/cli
npm install -g @vue/cli

添加打包工具

bash
vue add electron-builder
vue add electron-builder

配置electron镜像地址

因为有些下载的文件访问的是国外地址,不配置镜像地址无法成功下载

bash
npm config set registry http://registry.npm.taobao.org/
npm config set electron_mirror="https://npm.taobao.org/mirrors/electron/"
npm config set electron_builder_binaries_mirror="http://npm.taobao.org/mirrors/electron-builder-binaries/"
npm config set registry http://registry.npm.taobao.org/
npm config set electron_mirror="https://npm.taobao.org/mirrors/electron/"
npm config set electron_builder_binaries_mirror="http://npm.taobao.org/mirrors/electron-builder-binaries/"

最好去C:\Users\Administrator默认路径下查看.npmrc文件中是否配置成功

如果有proxy=null,https-proxy=null等配置,要删除

关闭杀毒软件

进行打包

bash
npm run electron:build // 打包命令
npm run electron:build // 打包命令

可能出现下载错误,需要手动下载nsis

nsis/nsis版本名/文件

手动下载放在路径中

C:\Users\Administrator\AppData\Local\electron-builder\Cache\winCodeSign
C:\Users\Administrator\AppData\Local\electron-builder\Cache\winCodeSign

打包后在dist_builder中生成了exe文件,点击安装即可

electron-builder打包后跨域访问失效问题的解决

  1. 修改ajax请求地址如axios的请求地址为完整url地址

  2. electron主启动类(如background.js文件)中关闭web权限检查

    js
    async function createWindow() {
      const win = new BrowserWindow({
        ...
        webPreferences: {
          ...
          //关闭web权限检查,允许跨域
          webSecurity: false
        }
      })
      //打包后开启控制台
      //win.webContents.openDevTools();
      ... 
    }
    
    async function createWindow() {
      const win = new BrowserWindow({
        ...
        webPreferences: {
          ...
          //关闭web权限检查,允许跨域
          webSecurity: false
        }
      })
      //打包后开启控制台
      //win.webContents.openDevTools();
      ... 
    }
    

如遇exe报毒

360开放平台提交

https://open.soft.360.cn/report.php

electron图标

需要256*256,格式为ico,注意,不能采用直接修改后缀名的方式,需要使用专门的网站转换

json
module.exports = {
  pluginOptions: {
    electronBuilder: {
      builderOptions: {
        win: {
          icon: 'src/assets/logo.ico'
        }
      }
    }
  }
}
module.exports = {
  pluginOptions: {
    electronBuilder: {
      builderOptions: {
        win: {
          icon: 'src/assets/logo.ico'
        }
      }
    }
  }
}

nsis

json
   nsis: {
           // 是否一键安装
          "oneClick": false,
          "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
          "allowToChangeInstallationDirectory": true, // 允许修改安装目录
          "installerIcon": "src/assets/logo.ico", // 安装图标
          "uninstallerIcon": "src/assets/logo.ico", // 卸载图标
          "installerHeaderIcon": "src/assets/logo.ico", // 安装时头部图标
          "createDesktopShortcut": true, // 创建桌面图标
          "createStartMenuShortcut": true, // 创建开始菜单图标
          "shortcutName": "variable-generation" // 图标名称
        }
      }
   nsis: {
           // 是否一键安装
          "oneClick": false,
          "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
          "allowToChangeInstallationDirectory": true, // 允许修改安装目录
          "installerIcon": "src/assets/logo.ico", // 安装图标
          "uninstallerIcon": "src/assets/logo.ico", // 卸载图标
          "installerHeaderIcon": "src/assets/logo.ico", // 安装时头部图标
          "createDesktopShortcut": true, // 创建桌面图标
          "createStartMenuShortcut": true, // 创建开始菜单图标
          "shortcutName": "variable-generation" // 图标名称
        }
      }
typescript
"use strict"

import { app, BrowserWindow, Menu, protocol, dialog } from "electron"
import installExtension, { VUEJS3_DEVTOOLS } from "electron-devtools-installer"
import { createProtocol } from "vue-cli-plugin-electron-builder/lib"
const isDevelopment = process.env.NODE_ENV !== "production"

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: "app", privileges: { secure: true, standard: true } }])

async function createWindow() {
  // Create the browser window.
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webSecurity: false, // 关闭权限
      nodeIntegration: (((process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean) as unknown) as boolean,
      contextIsolation: !(process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean
    }
  })
  //设置菜单
  let headerMenu = Menu.buildFromTemplate([
    {
      label: "退出",
      click: () => {
        app.quit()
      }
    },
    {
      label: "卸载",
      click: () => {
        dialog.showOpenDialog({
          title: "请选择您喜欢的文件",
          buttonLabel: "走你"
        })
        console.log(1111)
        app.getAppPath()
        console.log(app.getAppPath())
        app.getName()
        console.log(app.getName())
        console.log(app.getPath("exe"))
        console.log(app.getPath("userData"))
      }
    },
    {
      label: "全屏",
      click: () => {
        win.maximize()
      }
    },
    {
      label: "开发者选项",
      submenu: [
        {
          label: "开发者工具",
          click: () => {
            win.webContents.openDevTools()
          }
        }
      ]
    }
  ])
  Menu.setApplicationMenu(headerMenu)
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol("app")
    // Load the index.html when not in development
    win.loadURL("app://./index.html")
  }
}
// Quit when all windows are closed.
app.on("window-all-closed", () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== "darwin") {
    app.quit()
  }
})

app.on("activate", () => {
  // 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()
})

// 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.on("ready", async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    try {
      await installExtension(VUEJS3_DEVTOOLS)
    } catch (e) {
      console.error("Vue Devtools failed to install:", e.toString())
    }
  }
  createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === "win32") {
    process.on("message", data => {
      if (data === "graceful-exit") {
        app.quit()
      }
    })
  } else {
    process.on("SIGTERM", () => {
      app.quit()
    })
  }
}
"use strict"

import { app, BrowserWindow, Menu, protocol, dialog } from "electron"
import installExtension, { VUEJS3_DEVTOOLS } from "electron-devtools-installer"
import { createProtocol } from "vue-cli-plugin-electron-builder/lib"
const isDevelopment = process.env.NODE_ENV !== "production"

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: "app", privileges: { secure: true, standard: true } }])

async function createWindow() {
  // Create the browser window.
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webSecurity: false, // 关闭权限
      nodeIntegration: (((process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean) as unknown) as boolean,
      contextIsolation: !(process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean
    }
  })
  //设置菜单
  let headerMenu = Menu.buildFromTemplate([
    {
      label: "退出",
      click: () => {
        app.quit()
      }
    },
    {
      label: "卸载",
      click: () => {
        dialog.showOpenDialog({
          title: "请选择您喜欢的文件",
          buttonLabel: "走你"
        })
        console.log(1111)
        app.getAppPath()
        console.log(app.getAppPath())
        app.getName()
        console.log(app.getName())
        console.log(app.getPath("exe"))
        console.log(app.getPath("userData"))
      }
    },
    {
      label: "全屏",
      click: () => {
        win.maximize()
      }
    },
    {
      label: "开发者选项",
      submenu: [
        {
          label: "开发者工具",
          click: () => {
            win.webContents.openDevTools()
          }
        }
      ]
    }
  ])
  Menu.setApplicationMenu(headerMenu)
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol("app")
    // Load the index.html when not in development
    win.loadURL("app://./index.html")
  }
}
// Quit when all windows are closed.
app.on("window-all-closed", () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== "darwin") {
    app.quit()
  }
})

app.on("activate", () => {
  // 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()
})

// 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.on("ready", async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    try {
      await installExtension(VUEJS3_DEVTOOLS)
    } catch (e) {
      console.error("Vue Devtools failed to install:", e.toString())
    }
  }
  createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === "win32") {
    process.on("message", data => {
      if (data === "graceful-exit") {
        app.quit()
      }
    })
  } else {
    process.on("SIGTERM", () => {
      app.quit()
    })
  }
}

electron-builder

社区开发的打包工具

https://github.com/electron-userland/electron-builder

electron-vite-boilerplate

https://github.com/electron-vite/electron-vite-boilerplate.git

先打包生成dist-electron文件夹下下electron文件和dist文件夹下html文件,使用electron-builder打包这两个问题为electron的主进程和渲染进程

Released under the MIT License.