实验室项目打包工程落在我肩上啦!!第一次接触electron,心里十分没底,好在最后勇敢牛牛不怕困难,多次看electron官方文档和pkg文档,也是跌跌撞撞完成任务了。
项目介绍
项目前端使用了electron,将umi嵌入进去开发。项目后端使用node来实现的。因为要求实时性非常高,所以通信协议采用的websocket。本次是将一个前后端分离项目,打包成一个完整的桌面应用程序
pkg将node后端打包成可执行exe文件
配置说明
"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
pkg package.json
electron-builder构建
这里搭配了umi的构建,所以篇幅有点长,请耐心看完。首先还是介绍配置环境我已经将不需要的脚本 命令和其他配置文件删除。这是package.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行
"exe": "npm run build:renderer && npm run build-main-prod && electron-builder --win",
看似一个脚本语句,实则执行了三条,分别是npm run build:renderer
、npm run build-main-prod
、electron-builder --win
而前面两条分别对应package.json 中的第34、32行,在解释这两条语句之前,先给大伙看看目录结构
可以看到renderer里面的内容实际上是umi里面的东西,接下来解释这三条命令
渲染进程的构建 npm run build:renderer
这条语句实则执行
"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
这条语句实则执行
"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
,以下是其配置
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
,下面讲解一下
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
,下面讲解一下
'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
其中主要配置build
的files
里面就是需要electron 打包的东西,最主要的还是dist
目录因为我们将eletron-main
和electorn-renderer
打包之后是放到dist
里面的
注意: electron打包会遇到缺包问题,自己去github解决吧,毕竟当时我也遇到缺包.
将node后端和electron结合,形成完整的桌面应用程序
在前面我们提到了pkg将node程序打包成可执行exe文件,那么我们只需要将打包后的exe放入前端文件里面,在electron的main进程启动的时候开启一个子进程将exe文件启动起来即可,我这里用的node的child_process模块,在electron窗口建立起来的时候启动我们的node后端,这个node后端要放到static
文件里面,这样才能打包进去
总结
第一次了解electron并对其打包成一个完整的应用程序,其中electron的配置,还有umi的配置揉到一起,刚开始脑壳都是大的。好在又活了一天。
原文链接:https://juejin.cn/post/7346530887473577993 作者:李先生930