当前位置: 首页 > article >正文

创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程

环境: node v20.18.0 npm 11.1.0
用到的所有依赖:
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13",
    "vue-router": "^4.5.0"
  },
  "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",
    "cross-env": "^7.0.3",
    "dotenv-webpack": "^8.1.0",
    "electron": "^35.0.0",
    "electron-builder": "^25.1.8",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3"
  },

安装@vue/cli

// 已经安装可以忽略
npm install -g @vue/cli

创建一个新的 Vue 项目

vue create my-electron-vue-app
  • 进入项目目录
cd my-electron-vue-app
  • 修改vue.config.js
// 加上这个,build后,发布的页面不会出现白板
module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/'
};

添加Electron镜像地址

添加.npmrc文件,里面加上。不配置这个会有很多electron相关的文件下载不了。

electron_mirror=https://npmmirror.com/mirrors/electron/

安装 Electron

npm install electron --save-dev
  • 创建Electron入口文件main.js
mkdir electron
touch electron/main.js
// electron/main.js
// app 模块,它控制应用程序的事件生命周期。
// BrowserWindow 模块,它创建和管理应用程序 窗口。
const { app, BrowserWindow, ipcMain } = require('electron')
// 部引入 Node.js 中的 path 模块
const path = require('path')

const process = require('process')

// 添加一个createWindow()方法来将index.html加载进一个新的BrowserWindow实例
function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      //预加载
      // __dirname 字符串指向当前正在执行脚本的路径 (本项目,指向项目的根文件夹)。
      // path.join API 将多个路径段联结在一起,创建一个跨平台的组合路径字符串。
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // and load the index.html of the app.
  if (process.env.NODE_ENV === 'development') {
    mainWindow.loadURL('http://localhost:8080');
  // Open the DevTools.
  // mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
  }

}

// 在 Electron 中,只有在 app 模块的 ready 事件被激发后才能创建浏览器窗口。 
// 您可以通过使用 app.whenReady() API来监听此事件。 
// 在whenReady()成功后调用createWindow()。
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // 在macOS上,当单击dock图标并且没有其他窗口打开时,通常会在应用程序中重新创建一个窗口
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。
// 为了实现这一点,监听 app 模块的 'window-all-closed' 事件,
// 并在用户不是在 macOS (darwin) 上运行时调用 [app.quit()][app-quit]
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})
  • 创建Electron预加载文件preload.js
touch electron/preload.js
// electron/preload.js
/**
 * 预加载
 * 预加载脚本在渲染器进程加载之前加载,并有权访问两个 渲染器全局 (例如 window 和 document) 和 Node.js 环境(例如 process)
 */ 
window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }
  
  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, process.versions[dependency])
  }
})
  
  • 修改package.json
// package.json
{
  ...
  // 加入"main": "electron/main.js"
  "main": "electron/main.js",
  "scripts": {
    ...
    // 本地启动命令electron:serve
    "electron:serve": "set NODE_ENV=development&& electron ."
  },
  ...
}

安装Electron打包程序electron-builder

npm install electron-builder --save-dev
  • 修改package.json添加命令及build配置
// package.json
{
  ...
  "scripts": {
    ...
    "electron:build": "set NODE_ENV=production&& electron-builder"
  },
  // electron打包配置
  "build": {
    "appId": "com.example.yourapp",
    "productName": "YourApp",
    "directories": {
      "output": "dist_electron"
    },
    "files": [
      "dist/**/*",
      "electron/*"
    ],
    "win": {
      "target": "nsis",
      "icon": "build/icon.ico"
    },
    "mac": {
      "target": "dmg",
      "icon": "build/icon.icns"
    },
    "linux": {
      "target": "AppImage",
      "icon": "build/icon.png"
    }
  },
  ...
}
  • 也可以把electron打包配置到单独的electron-builder.yml文件。好处是可以注释。
appId: com.example.yourapp
productName: YourApp
copyright: Copyright © 2025 MyApp
directories:
  output: dist_electron
files:
  - "dist/**/*"
  - "electron/*"
asar: true
win:
  target: nsis
  icon: build/icon.ico
mac:
  target: dmg
  icon: build/icon.icns
linux:
  target: AppImage
  icon: build/icon.png
nsis:
  oneClick: false # 是否一键安装
  #allowElevation: true # 允许请求提升权限
  allowToChangeInstallationDirectory: true # 允许修改安装目录
  createDesktopShortcut: true # 创建桌面快捷方式
  createStartMenuShortcut: true # 创建开始菜单快捷方式

安装配置env环境变量

  • 安装 dotenv-webpack
npm install dotenv-webpack --save-dev
  • 修改vue.config.js
const Dotenv = require('dotenv-webpack');
module.exports = {
  configureWebpack: {
    plugins: [
      new Dotenv({
        path: `./.env.${process.env.NODE_ENV}`,
      })
    ]
  }
};
  • 安装cross-env
npm install cross-env --save-dev
  • 修改package.json 启动配置
{
  ...
  "scripts": {
    // "serve": "vue-cli-service serve",
    "serve": "cross-env NODE_ENV=development vue-cli-service serve",
    // "build": "vue-cli-service build",
    "build": "cross-env NODE_ENV=production vue-cli-service build",
    ...
  },
 }
  • 创建 .env 文件
touch .env.development
touch .env.production
// .env.development
API_URL=https://dev.api.example.com
// .env.production
API_URL=https://pro.api.example.com

安装vue-router配置

npm install vue-router
// src/router/index.js
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
import HelloWorld from '../components/HelloWorld.vue';

const routes = [
  { path: '/', component: HelloWorld }
];

const router = createRouter({
  // 打包用createWebHashHistory,如果用createWebHistory,页面会出现白板。
  history: process.env.NODE_ENV === 'production'
    ? createWebHashHistory(process.env.BASE_URL)
    : createWebHistory(process.env.BASE_URL),
  routes,
});

执行命令

  • electron本地启动
npm run electron:serve
  • electron打包
// 先执行vue的打包
npm run build
// 再执行electron的打包
npm run electron:build

http://www.kler.cn/a/579356.html

相关文章:

  • 大白话react第十八章React 与 WebGL 项目的高级拓展与优化
  • Java常见的并发设计模式
  • Elastic:AI 会开始取代网络安全工作吗?
  • 小程序事件系统 —— 33 事件传参 - data-*自定义数据
  • blender 坐标系 金属度
  • Linux 4.4 内核源码的目录结构及其主要内容的介绍
  • 使用python自动提取文本关键词
  • 【文献阅读】On-Device Language Models: A Comprehensive Review
  • LVGL开发说明
  • YOLOv10改进之MHAF(多分支辅助特征金字塔)
  • 【爬虫】开篇词
  • SSH/HTTP/HTTPS
  • Manus:革新未来的智能助手
  • 用R语言的XML库写一个采集图片的爬虫程序
  • 基于编译器特性浅析C++程序性能优化
  • 没有最好的,只有最合适的:重新认识测试工具的价值
  • 第十五届蓝桥杯----B组cpp----真题解析(小白版本)
  • PostgreSQL、SQL Server和MySQL数据库性能调优与故障排除技术
  • 用向量数据库建立本地知识库
  • Unity DOTS从入门到精通之 C# Job System