首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >领导:我们需要把系统打包成一个客户端,你看好做吗?我:整!

领导:我们需要把系统打包成一个客户端,你看好做吗?我:整!

作者头像
爱学英语的程序媛
发布于 2026-09-15 11:40:07
发布于 2026-09-15 11:40:07
1610
举报

哈喽大家好,我是小李。

就在昨天下午,领导突然走过来跟我说,我们的项目需要打包成客户端,这样用户下载之后就可以直接使用了!你研究一下怎么实现,然后明天跟我确认一下方案。

我思考了一下,说:好的(md), 我研究一下。

之前我们一直做的都是 web 端的应用或者是本地的小程序,虽然我也开发过一些移动端的应用,例如 android, harmony 等等,但是我还是第一次听说过还能把 web 端的应用打成桌面的安装包,然后让用户下载之后使用。

在这里说一下我们项目的背景:一个基于 Vite + React + Ant Design + Redux Persist + HashRouter 的前端单体控制台应用,以业务域目录组织页面,以聊天编排和任务联动为核心,兼具常规后台管理能力和事件驱动式智能体交互能力。

后端模块核心部分使用的 python + fastAPI + mysql + redis, 并且引入了openclaw 的架构设计模式。

说到 openclaw,不知道到今天为止迭代了多少个版本了,但是它的核心其实就是帮助用户干活,而干活的时候需要的这些数据是存储在用户的电脑上的,所以就需要让它去访问这些文件,而 web  端的应用是没有办法访问的,所以我们就需要桌面端的版本,来为它提供更丰富的能力。

接到这个需求,我先是去网上调研了一下,打包的工具有哪几种?读了很多的帖子和文章,也问了AI, 总结下来,用的比较多的主要有两种:

一种是通过 Electron 来打包,另一种是 通过 MixOne 来构建。

前者是目前市场上最主流、生态最完善的选择,比较适合我们这种已经有一定复杂度的业务项目。它的核心思想是:用 Electron 创建一个“壳”,把你现有的 Web 应用装进去。你现有的 React 路由、状态管理、Ant Design 组件几乎可以原封不动地复用。

而后者它的生态就没有 Electron 这么丰富了,它是最近几年才兴起的一个脚手架工具,它的核心优势是“去 IPC 化”。在标准 Electron 开发中,我们需要手动编写很多进程间通信的代码;而 MixOne 提供了语法糖,让你可以在前端组件中像调用普通函数一样直接调用系统 API(如文件对话框、本地数据库等),通过这种方式,我们能很显著地提升开发效率。

具体要怎么选择呢?

其实答案也显而易见,我们肯定是要用第一种方式。一方面,新的东西一般都不稳定;另一方面,因为我们的项目比较大,能求稳还是要求稳。

其实使用 Electron 的话,仍然有两种方式,一种是轻封装,另一种是深度集成。

前者是通过一个脚手架来直接打包,后者的话则需要引入更多的工具,例如进程通信等等,复杂度会明显上升,本文的话我们先以轻封装为例,深度集成的话后面有机会再来跟大家分享。

那废话不多说,我们直接开干。

官网的地址也给大家贴在下面,如果有必要的话大家可以去读一读。

https://www.electronjs.org/zh/docs/latest/

接下来,我们直接开干!

首先,需要安装一下依赖:

1、安装依赖

代码语言:javascript
复制
npm install electron electron-builder vite-plugin-electron -D

直接在终端中输入上述命令,执行就好。

安装成功之后,你会看到类似上面的输出。

注意,在安装之前需要确认一下node的版本。最好是22以上。否则后面可能会遇到兼容性的问题。

2、创建主进程文件

在src 同一级别的目录下新建文件夹 electron, 里面创建一个文件:main.js,这个就是 Electron 的主进程文件。

代码语言:javascript
复制
const { app, BrowserWindow } = require('electron');
const path = require('path');

const isDev = process.env.NODE_ENV === 'development';

function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      nodeIntegration: false,  // 保持关闭,因为你不需 Node.js 能力
      contextIsolation: true,
    },
    // 可选:隐藏菜单栏
    autoHideMenuBar: true,
  });

  // 关键:开发环境加载 Vite 开发服务器,生产环境加载打包后的文件
  if (isDev) {
    win.loadURL('http://localhost:5173'); // 你的 Vite 默认端口
    win.webContents.openDevTools(); // 开发时方便调试
  } else {
    win.loadFile(path.join(__dirname, '../dist/index.html'));
  }
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

3、配置vite.config.js文件

代码语言:javascript
复制
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import electron from 'vite-plugin-electron';

export default defineConfig({
  plugins: [
    react(),
    electron({
      entry: 'electron/main.js', // 指定主进程入口
    }),
  ],
  base: './', 
  server: {
    port: 5173,
  },
  build: {
    outDir: 'dist',
  },
});

4、修改package.json

代码语言:javascript
复制
{
  "main": "electron/main.js",
  "scripts": {
    "dev": "vite",
    "electron:dev": "vite & electron .",
    "build": "vite build",
    "electron:build": "vite build && electron-builder"
  },
  "build": {
    "appId": "com.yourcompany.yourapp",
    "productName": "你的应用名称",
    "directories": {
      "output": "release"
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "win": {
      "target": "nsis",
      "icon": "public/icon.ico"
    },
    "mac": {
      "target": "dmg",
      "icon": "public/icon.icns"
    }
  }
}

5、调整路由

如果你的 React Router 当前使用 BrowserRouter,刷新打包后的客户端可能会白屏。有两种解决方案:

方案 1:改用 HashRouter

代码语言:javascript
复制
import { HashRouter } from 'react-router-dom';
// 其他代码不变
<HashRouter>
  <App />
</HashRouter>

方案 2:保持 BrowserRouter,在 Electron 主进程中配置 webPreferences 和路由重定向(稍复杂,不推荐)。

6、打包

直接在终端执行下面的代码。

代码语言:javascript
复制
npm run electron:build

如果不出意外的话,打包结束之后你能在项目中和src同一级别的目录下看到release文件夹下有几个文件:

这哥里面的 .exe 文件就是我们需要的。

但是,出意外了

这个错误是因为 Electron Builder 在尝试编译原生模块(@parcel/watcher)时,找不到 Windows 编译工具链(Visual Studio 或 Windows Build Tools)。

这里推荐两种解决方案:

第一种当然就是直接安装了。(先别急,往后看)

管理员模式打开powershell,执行下面的代码:

代码语言:javascript
复制
npm install --global windows-build-tools

或者你也可以使用下面这个

代码语言:javascript
复制
npm install --global --production windows-build-tools

但是后者会自动安装 Visual Studio Build Tools 和 Python 环境,以及其他的一些必要的依赖。

第二种方式更简单:前提是你的项目不需要 Electron 的原生模块支持,我们可以直接修改 build 配置。让它在打包的时候跳过原生模块的编译。

修改之后,我们再次打包。

你以为会很顺利吗?

答案是不会。

这个模块人家官方不支持了。早就废弃掉了,npm官方也说了。

这里我们直接跳过对原生模块的编译,走上面的方法二。

然后看着挺正常的,但是就刷个dy的时间就报错了。。。

这个问题也很好解决,是由于文件的权限问题导致的。

上一个打包的进程还在占用文件,我们又开始了下一次打包。因为我们的配置改了,直接结束进程就行,然后删除release文件夹下的所有内容。

再次执行打包命令。

完美!

完成打包后在 release 目录下找到 .exe 或 .dmg 安装包。

双击 .exe文件就可以安装了。

如果安装报错的话,最有可能出现问题的地方就是语法问题。

Electron 主进程文件使用了 ES Module 语法(import),但 Electron 默认使用 CommonJS(require)。

这里直接修改一下模块的导入方式就行。

改了之后再次打包,生成的文件应该就可以直接安装了。

打开之后也跟我们网页端的效果是一模一样的。

文章的最后,有两个问题一起来看看

1、安装之后并没有生成桌面快捷方式,每次运行都需要重新安装,怎么解决?

这里需要补充一下NSIS配置,安装后自动创建桌面快捷方式

2、登录模块,输入账号和密码,提示请检查网络连接(本地网络是正常的),为什么?

1)、先定位这个报错是从哪抛出来的

这里其实都不用考虑太多,你可以想一想,你打包之后的应用是不是装在D盘里(你电脑的本地文件中),而我们网络请求走的是服务器的域名,这在 Electron 渲染进程里很容易被当成跨域请求拦截掉, axios 就会落到你现在看到的“请检查网络连接”。

具体的解决方式就是在 electron\main.js 中添加这个配置,让打包后的本地页面可以正常访问远程登录接口。

还有一种方式就是把登录请求改成主进程代理或本地后端转发,说具体一点就是渲染进程不再直接 axios.post('https://agent.zzgo.com.cn/...'),而是调用 window.electronAPI.login(...),由 Electron 主进程去请求远程接口,主进程把结果再回给前端页面

这样做有很多优点:

1)、不再依赖 webSecurity: false

2)、不会被 file:// -> https:// 的跨域问题卡住

3)、后面不只是登录,所有的接口都可以走这套流程。

具体的运行效果这里就不给大家展示了,因为涉及到数据安全的问题,如果大家有更多想法,欢迎在评论区交流讨论。

好啦,本期文章就分享到这里,感谢大家的阅读,我们下期再见~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 6、打包
  • 直接在终端执行下面的代码。
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档