开发时间:2025/08/26

开发作者:zhaozzz

开发内容:Vue.js + Electron 前端项目开发打包成exe可执行文件


博客日记:大家好久不见,时隔一年,我又来了。本文将详细介绍如何从零开始,使用Electron将Vue.js项目打包成Windows可执行文件(.exe)。记录一下。欢迎大家来交流讨论

 一、技术栈介绍

- Vue.js 2.6.11: 前端框架

- Electron 28.0.0: 桌面应用框架

- Element UI 2.15.14: UI组件库

- ECharts 5.4.0: 图表库

二、创建Vue.js项目

 步骤1:创建项目

在桌面随便创建一个文件夹,然后VScode直接打开该文件夹,创建新的 Vue 项目

vue create my-vue-project

 步骤2:安装依赖

# 安装项目依赖

npm install

# 安装Electron相关依赖

npm install electron electron-builder concurrently wait-on --save-dev

步骤3: 配置Electron

步骤1:创建Electron主进程文件

在项目根目录创建 `electron-main.js` 文件:

const { app, BrowserWindow, Menu } = require('electron');
const path = require('path');
const isDev = process.env.NODE_ENV === 'development';
 
let mainWindow;
 
function createWindow() {
    // 创建浏览器窗口
    mainWindow = new BrowserWindow({
        width: 1200,
        height: 800,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
            enableRemoteModule: true,
            webSecurity: false
        },
        icon: path.join(__dirname, 'public', 'favicon.ico'),
        show: false,
        titleBarStyle: 'default'
    });
 
    // 加载应用程序
    if (isDev) {
        // 开发环境下加载localhost
        mainWindow.loadURL('http://localhost:8080');
        // 打开开发者工具
        mainWindow.webContents.openDevTools();
    } else {
        // 生产环境下加载本地文件
        let indexPath;
        
        // 尝试多个可能的路径
        const possiblePaths = [
            path.join(__dirname, 'dist', 'index.html'),
            path.join(__dirname, 'index.html'),
            path.join(process.resourcesPath, 'app', 'index.html')
        ];
        
        for (const filePath of possiblePaths) {
            try {
                const fs = require('fs');
                if (fs.existsSync(filePath)) {
                    indexPath = filePath;
                    console.log('找到index.html文件:', indexPath);
                    break;
                }
            } catch (error) {
                console.log('检查路径失败:', filePath, error.message);
            }
        }
        
        if (!indexPath) {
            console.error('无法找到index.html文件,尝试的路径:', possiblePaths);
            mainWindow.loadURL('data:text/html,<h1>应用加载失败</h1><p>无法找到index.html文件</p>');
            return;
        }
        
        console.log('尝试加载文件:', indexPath);
        mainWindow.loadFile(indexPath);
    }
 
    // 窗口准备好后显示
    mainWindow.once('ready-to-show', () => {
        mainWindow.show();
        console.log('Electron窗口已准备好并显示');
    });
 
    // 页面加载完成事件
    mainWindow.webContents.once('did-finish-load', () => {
        console.log('页面加载完成');
    });
 
    // 监听页面加载失败
    mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
        console.error('页面加载失败:', errorCode, errorDescription);
    });
 
    // 当窗口关闭时
    mainWindow.on('closed', () => {
        mainWindow = null;
    });
 
    // 设置菜单
    const template = [
        {
            label: '文件',
            submenu: [
                {
                    label: '退出',
                    accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
                    click: () => {
                        app.quit();
                    }
                }
            ]
        },
        {
            label: '视图',
            submenu: [
                {
                    label: '重新加载',
                    accelerator: 'Ctrl+R',
                    click: () => {
                        mainWindow.webContents.reload();
                    }
                },
                {
                    label: '强制重新加载',
                    accelerator: 'Ctrl+Shift+R',
                    click: () => {
                        mainWindow.webContents.reloadIgnoringCache();
                    }
                },
                {
                    label: '开发者工具',
                    accelerator: 'F12',
                    click: () => {
                        mainWindow.webContents.toggleDevTools();
                    }
                }
            ]
        }
    ];
 
    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
}
 
// 应用程序准备完成后创建窗口
app.whenReady().then(createWindow);
 
// 当所有窗口关闭时退出应用程序
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});
 
app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});
 
// 阻止新窗口创建
app.on('web-contents-created', (event, contents) => {
    contents.on('new-window', (event, navigationUrl) => {
        event.preventDefault();
        require('electron').shell.openExternal(navigationUrl);
    });
});

步骤2:配置package.json

修改 `package.json` 文件,添加Electron相关配置:

{
  "name": "my-vue-app",
  "version": "1.0.0",
  "private": true,
  "main": "main.js",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "electron": "electron .",
    "electron-dev": "concurrently \"npm run serve\" \"wait-on http://localhost:8080 && electron .\"",
    "build-electron": "npm run build && electron-builder",
    "dist": "npm run build && electron-builder --publish=never"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^2.6.14"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "buffer": "^6.0.3",
    "concurrently": "^7.6.0",
    "crypto-browserify": "^3.12.1",
    "electron": "^28.3.3",
    "electron-builder": "^24.13.3",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "path-browserify": "^1.0.1",
    "process": "^0.11.10",
    "stream-browserify": "^3.0.0",
    "vue-template-compiler": "^2.6.14",
    "wait-on": "^7.2.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ],
  "build": {
    "appId": "com.example.my-vue-app",
    "productName": "My Vue App",
    "directories": {
      "output": "dist_electron"
    },
    "files": [
      "dist/**/*",
      "main.js",
      "electron-main.js",
      "package.json"
    ],
    "extraFiles": [
      {
        "from": "dist",
        "to": "app"
      }
    ],
    "win": {
      "target": "nsis",
      "icon": "public/favicon.ico"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    }
  }
}

 步骤3:配置Vue CLI

创建或修改 `vue.config.js` 文件:

const { defineConfig } = require('@vue/cli-service')
const webpack = require('webpack')  // ✅ 添加这一行

module.exports = defineConfig({
  transpileDependencies: true,

  configureWebpack: {
    resolve: {
      fallback: {
        "path": require.resolve("path-browserify"),
        "stream": require.resolve("stream-browserify"),
        "buffer": require.resolve("buffer"),
        "crypto": require.resolve("crypto-browserify")
      }
    },
    plugins: [
      new webpack.ProvidePlugin({  // ✅ 正确使用 webpack.ProvidePlugin
        process: 'process/browser',
      })
    ]
  }
})

三、开发应用

步骤1:创建Vue组件

在 `src/views/` 目录下创建你的Vue组件。例如,创建一个简单的应用:

<template>

  <div class="home">

    <div class="container">

      <h1>Vue.js + Electron 桌面应用</h1>

      <p>这是一个从零开始创建的桌面应用</p>

      <el-button type="primary" @click="showMessage">点击我</el-button>

    </div>

  </div>

</template>



<script>

export default {

  name: 'Home',

  methods: {

    showMessage() {

      this.$message.success('Hello from Electron!');

    }

  }

}

</script>



<style scoped>

.home {

  padding: 20px;

  text-align: center;

}



.container {

  max-width: 800px;

  margin: 0 auto;

}



h1 {

  color: #409EFF;

  margin-bottom: 20px;

}

</style>

步骤2:配置路由

在 `src/router/index.js` 中配置路由:

import Vue from 'vue'

import VueRouter from 'vue-router'

import Home from '../views/Home.vue'



Vue.use(VueRouter)



const routes = [

  {

    path: '/',

    name: 'Home',

    component: Home

  }

]



const router = new VueRouter({

  mode: 'history',

  base: process.env.BASE_URL,

  routes

})



export default router

步骤3:测试开发环境(★★★★★)

启动开发服务器和Electron

npm run electron-dev

一键打包脚本创建 `build-standalone.bat` 文件

@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion

echo ========================================
echo    Vue.js应用一键打包成exe(优化版)
echo ========================================
echo.

:: 检查并构建Vue应用
echo 步骤1: 构建Vue.js应用...
if not exist "dist\index.html" (
    echo 正在构建Vue应用...
    call npm run build
    if errorlevel 1 (
        echo 错误: Vue应用构建失败!
        pause
        exit /b 1
    )
) else (
    echo ✓ Vue.js应用已构建完成
)
echo.

:: 准备应用文件
echo 步骤2: 准备应用文件...
if exist "executable" (
    echo 删除旧的executable目录...
    rmdir /s /q "executable"
)
mkdir "executable" >nul
echo 复制构建文件到executable目录...
xcopy "dist\*" "executable\" /e /y /q >nul
if errorlevel 1 (
    echo 错误: 文件复制失败!
    pause
    exit /b 1
)
echo ✓ 应用文件准备完成
echo.

:: 创建输出目录
echo 步骤3: 创建输出目录...
if exist "MyVueApp" (
    echo 警告: MyVueApp目录已存在,将被删除
    rmdir /s /q "MyVueApp"
)
mkdir "MyVueApp"
echo ✓ 创建输出目录: MyVueApp
echo.

:: 下载 Electron(使用国内镜像)
echo 步骤4: 下载Electron运行时...
set ELECTRON_VERSION=v28.0.0
set ARCH=win32-x64
set ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
set DOWNLOAD_URL=%ELECTRON_MIRROR%%ELECTRON_VERSION%/electron-%ELECTRON_VERSION%-%ARCH%.zip

echo 正在下载 Electron %ELECTRON_VERSION% (%ARCH%)...
echo 镜像地址: %ELECTRON_MIRROR%
echo 这可能需要几分钟时间,请耐心等待...
powershell -Command "Invoke-WebRequest -Uri '%DOWNLOAD_URL%' -OutFile 'electron.zip' -UseBasicParsing"
if errorlevel 1 (
    echo 错误: 下载失败!
    echo 请检查网络连接或手动从 %ELECTRON_MIRROR% 下载
    pause
    exit /b 1
)
echo ✓ Electron下载完成
echo.

:: 解压 Electron
echo 步骤5: 解压Electron...
powershell -Command "Expand-Archive -Path 'electron.zip' -DestinationPath 'MyVueApp' -Force"
if errorlevel 1 (
    echo 错误: 解压失败!
    pause
    exit /b 1
)
echo ✓ Electron解压完成
echo.

:: 创建 resources/app 目录
echo 步骤6: 创建resources/app目录...
if not exist "MyVueApp\resources\app" mkdir "MyVueApp\resources\app"
echo ✓ 创建resources/app目录
echo.

:: 复制应用文件
echo 步骤7: 复制应用文件...
xcopy "executable\*" "MyVueApp\resources\app\" /e /y /q >nul
if errorlevel 1 (
    echo 错误: 文件复制失败!
    pause
    exit /b 1
)
echo ✓ 应用文件复制完成
echo.

:: 创建 package.json
echo 步骤8: 创建package.json配置文件...
(
echo {
echo   "name": "MyVueApp",
echo   "version": "1.0.0",
echo   "description": "Vue.js桌面应用",
echo   "main": "main.js",
echo   "scripts": {
echo     "start": "electron ."
echo   },
echo   "author": "Your Name",
echo   "license": "MIT"
echo }
) > "MyVueApp\resources\app\package.json"
echo ✓ package.json配置文件创建完成
echo.

rem 创建 main.js 主进程文件
echo Step 8.1: Creating main.js...
(
echo const { app, BrowserWindow } = require('electron'^);
echo const path = require('path'^);
echo.
echo function createWindow^(^) {
echo   const mainWindow = new BrowserWindow^({
echo     width: 1200,
echo     height: 800,
echo     webPreferences: {
echo       nodeIntegration: true,
echo       contextIsolation: false
echo     },
echo     icon: path.join^(__dirname, 'favicon.ico'^)
echo   }^);
echo   mainWindow.loadFile^('index.html'^);
echo }
echo.
echo app.whenReady^(^).then^(createWindow^);
echo.
echo app.on^('window-all-closed', ^(^) =^> {
echo   if ^(process.platform !== 'darwin'^) {
echo     app.quit^(^);
echo   }
echo }^);
) > "MyVueApp\resources\app\main.js"
echo ✓ main.js主进程文件创建完成
echo.

:: 处理图标
echo 步骤8.2: 处理应用图标...
if exist "public\favicon.ico" (
    copy "public\favicon.ico" "MyVueApp\resources\app\favicon.ico" >nul
    echo ✓ 图标文件已复制
) else (
    echo 警告: 未找到 public\favicon.ico,使用默认图标
)
echo.

:: 清理临时文件
echo 步骤9: 清理临时文件...
del "electron.zip" >nul 2>nul
rmdir /s /q "executable" >nul 2>nul
echo ✓ 清理临时文件
echo.

:: 创建桌面快捷方式
echo 步骤10: 创建桌面快捷方式...
powershell -Command "$WshShell = New-Object -comObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut('$env:USERPROFILE\Desktop\MyVueApp.lnk'); $Shortcut.TargetPath = '$(cd)\MyVueApp\electron.exe'; $Shortcut.WorkingDirectory = '$(cd)\MyVueApp'; $Shortcut.Description = 'MyVueApp - Vue.js桌面应用'; $Shortcut.Save()"
echo ✓ 桌面快捷方式创建完成
echo.

:: 打包完成
echo ========================================
echo           一键打包完成!
echo ========================================
echo.
echo 应用位置: %cd%\MyVueApp
echo 主程序: MyVueApp\electron.exe
echo 桌面快捷方式: %USERPROFILE%\Desktop\MyVueApp.lnk
echo.
echo 使用说明:
echo 1. 双击桌面快捷方式启动应用
echo 2. 或直接运行 MyVueApp\electron.exe
echo 3. 整个 MyVueApp 文件夹可复制到其他电脑使用(需 Win7+)
echo.
echo 文件大小:
powershell -Command "$size = (Get-ChildItem -Path 'MyVueApp' -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB; Write-Host ('{0:F1} MB' -f $size)"
echo.
echo 按任意键退出...
pause >nul

🎯 使用方法(★★★★★)

1. 开发:修改 `src/` 目录中的Vue.js代码

2. 构建:运行 `npm run build` 生成 `dist/`

npm run build

3. 打包:运行 `.\build-standalone.bat` 生成exe

.\build-standalone.bat

4. 分发:将 `MyVueApp/` 文件夹压缩发送给用户

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐