SoFunction
Updated on 2025-04-05

Vue+Electron Packaged Desktop Application (Super Detailed Complete Tutorial)

1. Use vite+vue3+js method

Remember, the entire project's json file cannot have comments, and it is not possible to report errors in time, otherwise there will still be problems when running the command.

1. Build desktop applications

Refer to this video

1- 1. Create a project

 npm create vite@latest
 or
 npm init vite@latest
 // choosevue3+jsorvue3+ts

1- 2. Installation depends on running the project

// Enter the project installation dependencynpm install
// Run the projectnpm run dev

1- 3. Configure Electron

npm install electron  //It is recommended to use mirrors here,Otherwise it will be too slow

1- 4. Modify the configuration file

1)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// /config/
export default defineConfig({
  base: './',	// Added the path to introduce resource css/js to the packaged dist file. Use relative paths here to prevent problems that cannot be found  plugins: [vue()]
})

2) (Newly added to the project root directory)

This is the entry file for electron running

// 
// Modules that control application life cycle and create native browser windowsconst { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
  // Create a browser window  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: (__dirname, '')
    }
  })
  // load  ('dist/') // This is different from the electronic official website path, so you need to pay attention to it  // Open the development tool  // ()
}
// This program will be initialized at Electron// Called when creating a browser window// Some APIs can only be used after the ready event is triggered.().then(() => {
  createWindow()
  ('activate', function () {
    // Usually on macOS, when clicking the application icon in dock, if nothing else    // Open a window, then the program will recreate a window.    if (().length === 0) createWindow()
  })
})
// Exit the program when all windows are closed except macOS.  Therefore, usually the procedures and they are// For the icon on the taskbar, it should be kept active until the user exits using Cmd + Q.('window-all-closed', function () {
  if ( !== 'darwin') ()
})
// In this file, you can include the code for all the remaining parts of the application.// It can also be split into several files,Then use require Import。

3) (Added in the project root directory)

// 
// All APIs can be used during preloading.// It has the same sandbox as Chrome extensions.('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = (selector)
    if (element)  = text
  }
  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, [dependency])
  }
})

4)

{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "",  // Added  //"type": "module", the one that comes with the project needs to be deleted, otherwise there will be problems  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron:serve": "electron ."  //Added electron run command  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "vite": "^4.4.5"
  }
}

1- 5. Packaging vue projects

npm run build

1- 6. Run electron

yarn electron:serve
or
npm run electron:serve

This step is basically completed. Add a new hot update and packaging configuration later. You can continue to read it

2. Hot update development environment

2-1. Edit

Update ('dist/') to ("http://localhost:5173"), and the updated file looks like this:

// 
// Modules that control application life cycle and create native browser windowsconst { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
  // Create a browser window  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: (__dirname, '')
    }
  })
  // load  // ('dist/') Change the line to the following line and load the url  ("http://localhost:5173") //Change it to your own project startup port here  // Open the development tool  // ()
}
// This program will be initialized at Electron// Called when creating a browser window// Some APIs can only be used after the ready event is triggered.().then(() => {
  createWindow()
  ('activate', function () {
    // Usually on macOS, when clicking the application icon in dock, if nothing else    // Open a window, then the program will recreate a window.    if (().length === 0) createWindow()
  })
})
// Exit the program when all windows are closed except macOS.  Therefore, usually the procedures and they are// For the icon on the taskbar, it should be kept active until the user exits using Cmd + Q.('window-all-closed', function () {
  if ( !== 'darwin') ()
})
// In this file, you can include the code for all the remaining parts of the application.// It can also be split into several files,Then use require Import。

2-2. Turn on vite and electron services at the same time

In order to make vite and electron run normally, you need to run vite first so that the url of its development server can be accessed normally, and then enable electron to load the url.

Two libraries need to be installed here:

  • concurrently: blocks running multiple commands, and the -k parameter is used to clear other processes that already exist or have been hung up.
  • wait-on: Wait for resources, used here to wait for the URL to be accessed

The installation command is

yarn add -D concurrently wait-on
or
npm install -D concurrently wait-on

Then update the file and add two new commands to scripts:

{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "",  
  //"type": "module", the one that comes with the project needs to be deleted, otherwise there will be problems  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",  //Add 1 new update (here it is changed to your own project startup port)    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"" //Add 2 new updates  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "vite": "^4.4.5"
  }
}

2-3. Run

Two commands have been added:

  • Yarn electron waits for port 5173 to be accessible, and then executes electron
  • yarn electron:serve executes the development server run and yarn electron commands for blocking

Run the project as long as you execute the commandyarn electron:serveornpm run electron:serveThat is, when the project file is modified, the desktop application will also be automatically updated.

So far, the hot update has been completed, and the last part is the packaging operation

3. Packaging operation

Let’s talk about the conclusion first, and the key point is ().
It is impossible to run after packaging or loading http://localhost:5173. Therefore, you need to use vite to package it first, and then use electron-builder to load the packaged files of vite for packaging.
In order for the code to load http://localhost:5173 at runtime according to different environments and load files during packaging, environment variables need to be used to switch production and development environments.

3-1. Implementation

3-1-1. Environment variables

Here, the environment variable NODE_ENV is used to switch the production and development environment. The production environment is NODE_ENV=production and the development environment is NODE_ENV=development. If there are other environments such as release, it can be expanded on this basis.

3-2. Create an electron folder

Create a folder electron in the project root directory and move it in with the files.

3-3. Edit electron/

This file mainly needs to switch the content loaded by electron based on environment variables, and the content is modified as follows:

// 
// Modules that control application life cycle and create native browser windowsconst { app, BrowserWindow } = require('electron')
const path = require('path')
const NODE_ENV = .NODE_ENV  //Add new// const NODE_ENV = 'development' // Judge the development or production mode (it is recommended to write this way, and you can use the development mode. When it is about to be packaged, then replace this variable with the packaging mode)function createWindow () {
  // Create a browser window  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: (__dirname, '')
    }
  })
  // load  // ('dist/') // This is different from the electronic official website path, so you need to pay attention to it  (
    NODE_ENV === 'development'
    ? 'http://localhost:5173'
    :`file://${(__dirname, '../dist/')}`
  ); // Added  // Open the development tool  if (NODE_ENV === "development") {
    ()
  } // Added}
// This program will be initialized at Electron// Called when creating a browser window// Some APIs can only be used after the ready event is triggered.().then(() => {
  createWindow()
  ('activate', function () {
    // Usually on macOS, when clicking the application icon in dock, if nothing else    // Open a window, then the program will recreate a window.    if (().length === 0) createWindow()
  })
})
// Exit the program when all windows are closed except macOS.  Therefore, usually the procedures and they are// For the icon on the taskbar, it should be kept active until the user exits using Cmd + Q.('window-all-closed', function () {
  if ( !== 'darwin') ()
})
// In this file, you can include the code for all the remaining parts of the application.// It can also be split into several files,Then use require Import。

3- 4. Edit

First, modify the main property and change main: to main: electron/.
Next, edit the build property:

{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/",  // Modify the entry file location  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\""
  },
  "build": {
    "appId": "",  //Package id.Project name    "productName": "ElectronApp", // Project name    "copyright": "Copyright © 2021 <your-name>", // Copyright information    "mac": {
      "category": ""
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", // Static file resource acquisition directory      "output": "dist_electron" // Package location will be newly created to the project root directory    }
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1"
  }
}

Then, update the scripts attribute.
Here you need to install two libraries first:

  • cross-env: This library allows developers to only focus on setting environment variables without worrying about platform settings
  • electron-builder: electron packaging library
cross-env: This library allows developers to only pay attention to the setting of environment variables,No need to worry about platform settings
electron-builder: electronPackaging library

The updated scripts are as follows:

{
  "dev": "vite",
  "build": "vite build",
  "serve": "vite preview",
  "electron": "wait-on tcp:5173 && cross-env NODE_ENV=development electron .", // We need to set environment variables here to ensure that the url is loaded during development  "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"",
  "electron:build": "vite build && electron-builder" // Added package command}

Finally, the updated complete content is as follows:

{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/",  // Modify the entry file location  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"",
    "electron:build": "vite build && electron-builder" // Added package command  },
  "build": {
    "appId": "",  //Package id.Project name    "productName": "ElectronApp", // Project name    "copyright": "Copyright © 2021 <your-name>", // Copyright information    "mac": {
      "category": ""
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", // Static file resource acquisition directory      "output": "dist_electron" // Package location will be newly created to the project root directory    }
  },
  "dependencies": {
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1"
  }
}

3-5. Packing

yarn electron:build
or
npm run electron:build

Error: Package "electron" is only allowed in "devDependencies". Please remove it from the "dependencies" section in your .
This paragraph means that electron does not allow development dependencies, and needs to be replaced into the operation dependencies. After modification, the following is as follows:

{
  "name": "sd",
  "private": true,
  "version": "0.0.0",
  "main": "electron/",  // Modify the entry file location  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "electron": "wait-on tcp:5173 && electron .",
    "electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"",
    "electron:build": "vite build && electron-builder" // Added package command  },
  "build": {
    "appId": "",  //Package id.Project name    "productName": "ElectronApp", // Project name    "copyright": "Copyright © 2021 <your-name>", // Copyright information    "mac": {
      "category": ""
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "directories": {
      "buildResources": "assets", // Static file resource acquisition directory      "output": "dist_electron" // Package location will be newly created to the project root directory    }
  },
  "dependencies": {
    // Switch development dependencies to operation dependencies  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "concurrently": "^8.2.1",
    "vite": "^4.4.5",
    "wait-on": "^7.0.1",
    "electron": "^27.0.0",
    "vue": "^3.3.4"
  }
}

After packaging, two additional folders will be addeddistanddist_electron

If the package fails or is stuck in a place, it is because the package will generate dependency packages, which are all downloaded from github, require vpn, or domestic mirroring can be solved. For specific use of Taobao mirroring method, you can read the end of this blog, and test it personally.

At this point, everything is basically over, the pile aboveAfter referring to this blogger's article, you can also read it

2. Use vite+vue3+Ts method (a big guy has already built it, only Ts)

Use the framework configured by a certain boss, only supports the ts version, and there are no options (vite+vue3+ts)
The method is very simple

Execute commands to create a project
npm create electron-vite
You will download the project dependency for the first time. You will ask whether to download it. Enter y.
Then enter the project name and press Enter to create the installation dependency
npm install runs the project
npm run dev
After executing the command, the packaged exe will be run in the electron window.
npm run dev
(The big guy has integrated hot deployment, and the code update window is also updated)

3. Use vue-cli scaffolding method (support vue2/3)

Version Requirements

I'm usingv16.20.2,
Originally, I used the 18 version to package the package. There was always a problem: Error: error: 0308010C:digital envelope routines::unsupported
Later, I checked a lot of information and found the reason: because the recently released OpenSSL3.0 in the V17 version, and OpenSSL3.0 has added strict restrictions on the allowable algorithm and key size.
Of course, there are also solutions for version 17 or above. The stupidest method I have used is to reduce the version tov16.20.2, You can read the following blog to try other solutions
Three solutions to quickly solve Error: error:0308010C:digital envelope routines::unsupported

2. Create a vue project through vue-cli (both 2/3 is OK)

Created with vue-cli scaffolding, this method does not support vite

vue create Project name

3. Add the electronic-builder that comes with vue

After the following command is executed, the vue scaffolding will be executed first and then the electron will be run.

vue add electron-builder

4. Packaging the exe program

npm run electron:build

Note that the packaging process will download various things. The poor network is easy to fail to download. I recommend a useful method to everyone.
Create a .npmrc file in the root directory of the project and put the following code. The source of download is to go to the Taobao image to download it, which is faster

ELECTRON_MIRROR=/mirrors/electron/
ELECTRON_BUILDER_BINARIES_MIRROR=/mirrors/electron-builder-binaries/

The above solution to the network slow problem comes from this

This is the end of this article about Vue+Electron packaging desktop application (super detailed and complete tutorial). For more related content of Vue packaging desktop application, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!