使用electron-builder和pkg打造一款完整桌面应用软件

实验室项目打包工程落在我肩上啦!!第一次接触electron,心里十分没底,好在最后勇敢牛牛不怕困难,多次看electron官方文档和pkg文档,也是跌跌撞撞完成任务了。

项目介绍

项目前端使用了electron,将umi嵌入进去开发。项目后端使用node来实现的。因为要求实时性非常高,所以通信协议采用的websocket。本次是将一个前后端分离项目,打包成一个完整的桌面应用程序

pkg将node后端打包成可执行exe文件

配置说明
json 复制代码
"name": "unitback",//打包之后的名称
"main": "index.js",//入口文件
"bin": "main.js",//打包的入口文件
"pkg": {//pkg配置项
  "scripts": [ //包含了要打包到最终可执行文件中的JavaScript文件的路径
    "controller/*.js",
    "log4js/*.js",
    "database/*.js"
  ],
  "assets": [//额外文件或资源的路径
    "node_modules/sqlite3/lib/binding/napi-v6-win32-unknown-x64/node_sqlite3.node",
    "template"
  ],
  "targets": [//要构建的目标平台 这里设置的是node12环境,windowsOS
    "node12-windows"
  ],
  "outputPath": "dist"//输出路径的文件名
},

看到这里但是有点疑惑凭啥enum不写进去呀。后面了解了尽管 enum.js 没有在 pkg 的配置中指定,它可能在你的应用程序中被其他 JavaScript 文件引用,因此在构建时会被自动包含进去。

打包成exe
js 复制代码
pkg package.json

electron-builder构建

这里搭配了umi的构建,所以篇幅有点长,请耐心看完。首先还是介绍配置环境我已经将不需要的脚本 命令和其他配置文件删除。这是package.json文件。

json 复制代码
"build": {
  "productName": "CouplingSoftware",//打包之后的软件名称
  "files": [//打包需要包含的文件!!!!!!!!!
    "dist/",//webpack打包的输出
    "node_modules/",
    "package.json"
  ],
  "mac": {
    "category": "your.app.category.type"
  },
  "win": {
    "requestedExecutionLevel": "requireAdministrator",//管理员身份运行
    "target": [
      "nsis"//以nsis格式创建安装程序,NSIS 是一种流行的 Windows 安装程序制作工具,它允许开发人员创建自定义的 Windows 安装程序,用于将应用程序安装到用户的计算机上。
    ]
  },
  "nsis": {
    "oneClick": false,
    "perMachine": true,
    "allowToChangeInstallationDirectory": true
  },
  "directories": {
    "output": "release"
  },
  "appId": "com.cn.littlestrong.demo",
  "asar": false
},
"scripts": {
  "start": "npm run build-main-dev && run-electron ./dist/main/main.js",
  "start:main": "electron-webpack dev",
  "start:renderer": "cross-env APP_ROOT=src/renderer umi dev",
  "build-main-prod": "cross-env NODE_ENV=production webpack --config ./build/webpack.main.prod.config.js",
  "build-main-dev": "cross-env NODE_ENV=development webpack --config ./build/webpack.main.config.js",
  "build:renderer": "cross-env APP_ROOT=src/renderer umi build",
  "exe": "npm run build:renderer && npm run build-main-prod && electron-builder --win",
  "dist": "electron-builder",
},

这里打包执行npm run exe 实际执行以下脚本语句,也就是我上面package.json的第35行

js 复制代码
 "exe": "npm run build:renderer && npm run build-main-prod && electron-builder --win",

看似一个脚本语句,实则执行了三条,分别是npm run build:renderernpm run build-main-prodelectron-builder --win而前面两条分别对应package.json 中的第34、32行,在解释这两条语句之前,先给大伙看看目录结构

可以看到renderer里面的内容实际上是umi里面的东西,接下来解释这三条命令

渲染进程的构建 npm run build:renderer

这条语句实则执行

json 复制代码
"build:renderer": "cross-env APP_ROOT=src/renderer umi build",

解释一下:首先cross-env是设置环境变量的工具,用于跨平台开发。cross-env 设置环境变量 APP_ROOT 的值为 src/renderer,这意味着umi build过程中被构建的东西是src/renderer下面的内容。我说的迷糊的话,就想一想这句话:他凭啥知道构建umi的位置就是在src/renderer里面,而不是其他位置??

既然是编译umi,那离不开umi的webpack,接下来简单介绍项目中的umi的webpack配置 outputPath就不用说了吧,重点说一下chainWebpack,里面config.target('electron-renderer'); 这句话的意思是:webpack 将编译目标(target)设置为 electron-renderer,还有history更改为hash模式,这是因为默认路由模式"browser"会导致本地静态文件加载问题,publicPath:'./'这个也是静态文件加载问题

主进程的构建 npm run build-main-prod

这条语句实则执行

json 复制代码
"build-main-prod": "cross-env NODE_ENV=production webpack --config ./build/webpack.main.prod.config.js",

解释一下:NODE_ENV=production webpack --config ./build/webpack.main.prod.config.js 说明环境是 production 牢记一下这个,后面会讲到。依旧采用的webpack,配置文件是./build/webpack.main.prod.config.js,以下是其配置

js 复制代码
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// baseConfig已经配置了一些,这里引用即可
const baseConfig = require('./webpack.main.config');
module.exports = merge.smart(baseConfig, {
 //将模式改为生产环境
 mode: 'production',
});

既然上面引用了./webpack.main.config,下面讲解一下

js 复制代码
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
//这里又引入了配置
const baseConfig = require('./webpack.base.config');
module.exports = merge.smart(baseConfig, {
  //看见这个熟不熟熟悉?上面umi构建的target是electron-renderer
  target: 'electron-main',
  //构建的入口,出口呢???别着急,不是还引入了webpack.base.config里面的嘛
  entry: {
    main: './src/main/main.js',
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(
        process.env.NODE_ENV || 'development'
      ),
    }),
  ],
  //模式是开发模式,
  mode: 'development',
});

既然上面引用了./webpack.base.config,下面讲解一下

js 复制代码
'use strict';

const path = require('path');

module.exports = {
  //出口不就来了嘛
  output: {
     //这里构建到了dist/main文件里面的内容
    path: path.resolve(__dirname, '../dist/main'),
    filename: '[name].js',
  },
  node: {
    __dirname: false,
    __filename: false,
  },
  resolve: {
    extensions: ['.jsx', '.ts', '.js', '.json'],
  },
  devtool: 'source-map',
};
electron-builder构建完整应用

执行最后electron-builder --win 其中主要配置 buildfiles里面就是需要electron 打包的东西,最主要的还是dist目录因为我们将eletron-mainelectorn-renderer打包之后是放到dist里面的
注意: electron打包会遇到缺包问题,自己去github解决吧,毕竟当时我也遇到缺包.

将node后端和electron结合,形成完整的桌面应用程序

在前面我们提到了pkg将node程序打包成可执行exe文件,那么我们只需要将打包后的exe放入前端文件里面,在electron的main进程启动的时候开启一个子进程将exe文件启动起来即可,我这里用的node的child_process模块,在electron窗口建立起来的时候启动我们的node后端,这个node后端要放到static文件里面,这样才能打包进去

总结

第一次了解electron并对其打包成一个完整的应用程序,其中electron的配置,还有umi的配置揉到一起,刚开始脑壳都是大的。好在又活了一天。

相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰10 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪10 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy11 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom12 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试