【架构】vue-cli集成electron

一、引言

在文章开始之前,需要先介绍一下webpack和electron;

Webpack:是一个用于现代 JavaScript 应用程序的静态模块打包工具。
Electron:Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。
当遇到需要将原本是 web 端的应用打包成桌面端的需求时,就可以采用 webpack+electron 的方式来开发桌面端,这种方式有以下四点好处:

  • 原项目改动小,由于 electron 自带 Chromium,所以原项目几乎可以无缝迁移到 electron。

  • 前端技术栈复用,electron 的渲染进程可以使用当下任何前端框架(如 vue、react)来构建应用的界面,同时 electron 集成了 node.js 原生能力,
    可以方便的操作本地文件系统、调用本地程序、创建系统托盘、打开文件对话框等等,不需要再去学习 c#、c++ 语言,对前端开发十分的友好。

  • 跨平台开发,一套代码可以打包多平台(windows、linux、macOS),这大大降低了开发和维护的成本,而且一套 HTML/CSS/JS 在多端上的表现也一致,
    不需要针对不同的平台做专门的兼容处理。

  • 易于打包和发布,electron-builder 可以打包生成 .exe(windows)、.dmg(macOS)、.AppImage(linux),方便在不同平台安装,通过
    electron-updater 可以在线升级。
    在这里插入图片描述

二、基本概念

  1. electron 的基本概念

Electron分为主进程、渲染进程。主进程的作用是启动应用、创建/销毁窗口、控制应用的生命周期、访问操作系统的API,管理全局数据、权限控制等;

渲染进程的作用是显示用户界面、处理用户交互,应用的功能基本都在渲染进程中实现。

主进程和渲染进程通过IPC(主进程中是ipcMain,渲染进程中是ipcRenderer),ipc的通信方式和事件总线十分类似:

主进程中接收消息:

// main.js
const { ipcMain, dialog } = require('electron');

ipcMain.on('open-file-dialog', (event, arg) => {
  console.log('收到消息:', arg);
  dialog.showOpenDialog({ /* ... */ });
});

渲染进程中发送消息:

// renderer.js
const { ipcRenderer } = require('electron');

ipcRenderer.send('open-file-dialog', 'some data');

主进程中发送消息:

// main.js
win.webContents.send('update-available', '新版本来了!');

渲染进程中接收消息:

// renderer.js
ipcRenderer.on('update-available', (event, msg) => {
  console.log('主进程通知:', msg);
});
  1. webpack 的基本概念

webpack 的内容庞大,这里就简述一下 webpack 中入口(entry)、输出(output)、插件(plugin)、模式(mode)的概念。

  • 入口起点指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图的开始。进入入口起点后,webpack 会 找出有哪些模块和库是入口起点(直接和间接)
    依赖的。
  • 输出属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放
    置在 ./dist 文件夹中。
  • 插件用于执行打包优化,资源管理,注入环境变量等。
  • 通过选择 development, production 或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。

三、项目集成与目录结构

  1. 通过 npm 安装 electronelectron-buildervue-cli-plugin-electron-builder到开发依赖下,自动更新需要安装
    electron-updater
  2. 建议在项目根目录下或src文件夹下新建 electron 文件夹,将 electron 相关的脚本都放到此文件夹下
    my-app/
    ├── dist/                # 渲染进程构建输出目录
    ├── dist_electron/       # 桌面端构建输出目录
    ├── src/
    │   ├── electron/        # Electron 相关代码
    │   └── ...
    ├── vue.config.js        # vue-cli 配置文件
    ├── electron-builder.yml # electron-builder 打包配置文件
    ├── package.json
    └── ...
    

四、运行与打包

  1. 修改package.json:
    {
      "scripts": {
         "electron:serve": "vue-cli-service electron:serve",
         "electron:build": "vue-cli-service electron:build",
      }
    }
    
  2. 在 electron 主进程脚本中加载相应的渲染进程的开发地址:
    // src/electron/index.js
    mainWindow.loadURL('http://localhost:3000');
    // 或者使用 webpack 的开发服务器地址变量
    // mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    
  3. 执行 npm run electron:serve
  4. package.json 中添加打包配置:
    {
      "build": {
        "appId": "com.example.electronapp",
        "productName": "MyElectronApp",
        "directories": {
          "output": "release"
        },
        "files": [
          “./dist_electron/bundled”
        ],
        "mac": {
          "target": "dmg"
        },
        "win": {
          "target": "nsis"
        },
        "linux": {
          "target": "AppImage"
        }
      }
    }
    
  5. 修改vue.config.js
    pluginOptions: {
      electronBuilder: {
        preload: 'src/electron/preload.js',       # 向渲染进程提供 node.js API
        customFileProtocol: './',                 # 自定义文件的根目录
        mainProcessFile: 'src/electrin/index.js', # 主进程的入口
        nodeIntegration: true,
      },
    },
    
  6. 执行npm run electron:build,打包完成之后你将在文件夹中看到对应平台的安装包。

五、常见问题

  1. 打包后提示找不到 background.js

    package.json 中添加 "main": "background.js"

  2. 打包后打开应用空白

    在生产和开发环境下,需要加载的资源地址不同,可对主进程脚本中做如下修改:

    // src/electron/index.js
    ...
    const isDevelopment = process.env.NODE_ENV === 'development'
    
    app.on("ready", () => {
      const mainApp = new BrowserWindow({
        ...
      })
      // 如果默认协议是 file,可将 app 改为 file
      mainApp.loadURL(isDevelopment ? process.env.WEBPACK_DEV_SERVER_URL : `app://./index.html`)
    })
    
  3. preload.js在生产和开发环境下地址不一样,导致无法注入preload.js

    打包后,由于资源统一在asar下,preload.js的路径会和开发环境下不同,可在主进程脚本中做如下修改:

    // src/electron/index.js
    ...
    const isDevelopment = process.env.NODE_ENV === 'development'
    
    app.on("ready", () => {
      const mainApp = new BrowserWindow({
        ...
        preload: isDevelopment 
          ? path.join(__dirname, '../src/electron/preload.js') 
          : path.join(app.getAppPath(), 'preload.js'),
      })
    })
    
  4. macOS上每次安装都有安全提示或直接提示文件损坏无法安装

    这是因为 macOS 的安全策略导致的。有两种解办法,一种是修改 macOS 的安全策略等级;另一种是打包 macOS 平台应用时,进行应用的公证。

    package.json 中添加配置:

    // package.json
    {
      "build": {
        ...
        "mac": {
          ...
          "hardenedRuntime": true,
          "entitlements": "build/entitlements.mac.plist",
          "entitlementsInherit": "build/entitlements.mac.plist"
        }
        "afterSign": "src/electron/notarize.js"
      }
    }
    

    在 build 文件夹下添加 entitlements.mac.plist 文件

    // build/entitlements.mac.plist
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>com.apple.security.cs.allow-jit</key>
        <true/>
        <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
        <true/>
        <key>com.apple.security.cs.allow-dyld-environment-variables</key>
        <key>com.apple.security.cs.disable-library-validation</key>
        <true/>
      </dict>
    </plist>
    

    执行 npm install -D @electron/notarize 安装公证依赖,在 src/electron/ 中新建 notarize.js,并到
    https://developer.apple.com/ 中申请开发者账号,创建与公证相关的证书等操作(可自行百度)。

    // src/electron/notarize.js
    const { notarize } = require('@electron/notarize')
    
    exports.default = async function notarizeMacos(context) {
      const { electronPlatformName, appOutDir } = context
      console.log('开始公证')
      if (electronPlatformName !== 'darwin') {
        console.log('非macos环境,停止公证')
        return
      }
    
      const appName = context.packager.appInfo.productFilename
    
      await notarize({
        appBundleId: # 应用 bundleId,
        appPath: `${appOutDir}/${appName}.app`,
        appleId: # 苹果账号,
        appleIdPassword: # 应用专属密码,
        teamId: # 团队id,
      })
    
      console.log('公证完成')
    }
    
  5. 打包后的 macOS 安装包,有的电脑可以安装,有的缺安装后无法打开

    这是由于苹果公司在使用自研 cpu 前一直使用的是英特尔的 cpu,这两种 cpu 的架构不同,一个是 arm64 一个是 x64;针对这个问题有两种解决方案,
    一种是打包时指定 cpu 的架构 npm run electron:build --mac --arm64npm run electron:build --mac --x64, 另一种是
    打双架构包,但是这会让应用体积变大,执行命令 npm run electron:build --mac --universal 或修改 package.json 中的打包配置:

    // package.json
    {
      "build": {
        ...
        "mac": {
          ...
          target: {
            target: "default",
            arch: ["universal"]
          }
        }
      }
    }
    

六、结语

vue-cli 已逐渐退出主流舞台,在当下的新项目中,我们更推荐使用现代构建工具如 Vite。配合社区成熟方案如 vite-electron,能够实现开箱即用的开发体验,无需手动配置繁琐的 Webpack、Babel 或热更新逻辑,极大提升了开发效率与项目可维护性。

不过,本文的主要背景是公司现有的老项目。在这种场景下,我们面临的首要任务是如何平滑地将既有的 Web 应用迁移为桌面端应用。综合评估了开发成本、学习曲线、技术栈一致性以及后续的可维护性,我们最终选择了使用 Electron 作为桌面端方案。

虽然 Electron 的应用体积相对较大,内存占用也较高,但它拥有成熟的生态、良好的文档支持,并且能够最大限度地复用前端项目已有的技术栈与代码结构。这对于一个追求稳定、可控、低风险迁移的项目来说,是一种非常稳妥而现实的技术选型。

希望本文能为你在类似的技术决策过程中提供一些参考,无论是面对旧项目的迁移,还是在探索前端能力在桌面平台的延展。理解技术选型背后的权衡,往往比选择某个具体工具本身更重要。

如果你在迁移过程中遇到具体的问题,欢迎留言或讨论,也欢迎你继续关注后续的进阶分享。

相关推荐

【功能】FizEIM 闪记-高效会议新体验

FizEIM 的语音会议功能凭借快速发起、全程记录、智能生成报告等强大优势,以及多端同步和安全可靠的特点,为企业打造了一个高效、便捷、智能的会议协作平台

zyy_333的博客 934

【转载】协作赋能-制造业生产流程重构

协作赋能制造业生产流程重构

zyy_333的博客 140

【功能】项目管理,提升整体运营效率

FizEIM飞智协作是一款专门为企业设计的工作管理工具,它整合了企业内部众多与项目相关的信息资源,涵盖项目的规划、执行、监控和收尾等各个阶段

zyy_333的博客 927

【功能】CRM核心痛点及FizEIM解决方案

CRM系统是飞智协作众多子系统中的一套专门用于客户的管理系统,与其他子系统相辅相成

zyy_333的博客 767

【设计】项目管理交互文档

本文分享了Fiz-EIM项目管理部分的交互设计规范。

zyy_333的博客 227

【功能】FizEIM 文档库助力高效协作,告别文件管理困境

FizEIM 文档库助力高效协作,告别文件管理困境

zyy_333的博客 878

【功能】从“听“到“懂“:多模态大模型如何重塑企业会议体验

本文将分享多模态大模型的技术原理,以及我们如何借助通义千问的Qwen2.5-Omni模型,为企业打造更智能、更高效的协作体验。

zyy_333的博客 1288

【部署】Fiz-EIM个人安装部署体验

给寻找高效协作工具的小伙伴们一些参考

zyy_333的博客 1055

【实践】基于LiveKit构建实时视频会议系统

本文主要介绍如何使用LiveKit来实现简单的音视频会议系统。

zyy_333的博客 2394

【架构】基于 WebSocket 的即时通讯系统设计与实现 —— 以 Fiz-EIM 平台为例

在数字化办公场景深度渗透的当下,即时通讯(IM)系统已成为企业协作架构的核心组件。WebSocket 协议作为 RFC 6455 定义的标准化实时通信方案,通过全双工通信通道与持久化 TCP 连接,构建了高效的实时数据交互架构。

zyy_333的博客 1298

【转载】AI赋能企业协作-从人工到AI的演进

(IM)平台已从简单的消息传递工具,逐步演变为支撑企业协作的核心基础设施。从早期基于人工的业务处理,到AI深度参与甚至主导协作流程,企业IM的进化历程不仅反映了技术发展的脉络,更揭示了未来组织协作的终极形态。本文将企业IM的演进划分为四个阶段,结合技术突破与行业实践,探讨每个阶段的核心特征与价值。在互联网普及初期,企业IM的核心功能是解决信息传递的效率问题。这一阶段的协作模式完全依赖。随着企业IT技术发展,

zyy_333的博客 98

【转载】AI赋能企业协作-FizEIM的功能探索

本系列文章AI赋能企业协作与第一个系列IM工具对比中反复比较了国内外、商业、开源的IM工具以及IM工具的AI支持,在之前的中,由于信息偏差,Workplus(BeeWorks)已不再开源,这里向各位读者致歉,后面的文章将尽力避免类似情况。

zyy_333的博客 101

【转载】AI赋能企业协作-国内外协作平台的AI对比

功能成熟度高,生态集成性强(钉钉与阿里云、飞书与字节系应用无缝对接)。安全体系完善。适合标准化需求明确的中大型企业。

zyy_333的博客 299

【转载】AI赋能企业协作-企业协作中的AI

例如,某家大型零售企业通过引入AI客服助手,将客户满意度提升了15%,同时减少了30%的人力成本。例如,通过分析团队沟通数据,智能助手可以提供协作效率报告,并给出改进建议。例如,在客服场景中,智能助手可以快速响应客户的咨询,减少人工客服的工作量。同时,AI的引入,为团队协作带来了革命性的变化。AI可以分析项目需求,根据人员占用率或能力匹配,将任务分配给最合适的成员,确保任务与能力匹配,从而提高任务完成效率。跨部门协作:在跨部门协作中,智能助手可以自动生成会议纪要、提取关键任务,并提供个性化的日程安排建议。

zyy_333的博客 230

【转载】IM工具对比-从工具到场景(下)

从企业规模到行业分类,下面列举了几个场景,如果诸位看官恰好在某个场景中看到了自己的工作状态,希望它能带给你一点启发。

zyy_333的博客 103

【转载】IM工具对比-从工具到场景(上)

前面4篇文章展示了部分的调研工作,接下来,又有了新的问题,开源IM工具虽然免费,但真的能满足企业级协作的需求吗?对于这个问题的思考,一方面是企业实际应用的场景,一方面是工具的目标场景。两者的匹配度越高越能证明这个工具正是适合你的工具。那么我的客户实际遇到了哪些场景,是否具有行业普遍性,在这些场景内,前面调研的工具又是否能够高度契合呢,下面我们来看一下(本篇从企业规模进行分类,从上文对比的5个产品中选择workplus、野火IM、Fiz-EIM三项简单分析,三款产品的功能介绍均来自各自官网)

zyy_333的博客 149

【转载】IM工具对比-从协作平台再到开源项目

由于协作平台的开发、部署、集成工作均需要专业技术团队进行支撑,具有一定的门槛,因此目前在gitee、开源中国等社区,优秀、成熟的协作平台项目数量不多。私有化部署:适合中大型企业或对数据安全要求高的行业,数据完全由企业掌控,但部署和维护成本较高。自动化与集成:支持与第三方工具(如ERP、CRM、OA等)集成,支持自动化工作流。混合部署:结合云端和私有化部署的优势,适合需要灵活性和安全性的企业。性价比:综合考虑功能、性能、安全性和成本,选择最适合企业的方案。

zyy_333的博客 282

【转载】IM工具对比-从IM到企业协作平台

通过与多个客户的沟通,不管是银行、制造业、政府部门,IM需求的背后实际是更希望得到一个高效易用、安全可控的协作平台。消息流转功能可以将业务系统中的任务、审批、通知等自动转化为IM消息,确保信息及时传递。例如,销售数据异常时,自动通知销售经理;接上篇,带着对于IM的重新思考,本人再次进行了学习和调研:对于这个领域的调研和了解越多就发现不了解的越多。自动化处理重复性任务,如自动回复常见问题、自动生成会议纪要、自动分配任务等,释放员工精力。,支持多人实时编辑、版本管理、在线评论等功能,适合依赖文档协作的企业。

zyy_333的博客 175

【转载】IM工具对比

接上篇--通过对于IM工具的简单调研,认识到不同类型的IM工具的使用场景存在着些许差距,因此也各有各的生存空间。本人也将工作以来接触的客户按照需求类型进行了如下分类,浅谈一下开源工具在其中的价值,并将开源工具进行对比。也为后续工作梳理一下思路。

zyy_333的博客 207
上一篇: 【功能】CRM核心痛点及FizEIM解决方案
下一篇: 【功能】项目管理,提升整体运营效率
Fiz-EIM官方
Fiz-EIM官方 大数智能 大数智能
博客等级 码龄2年 58粉丝 · 10原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值