三、Electron + Webpack + Vue 搭建开发环境及打包安装 ---- 打包electron应用

目录

  1. Webpack + Vue 搭建开发环境及打包安装 ------- 打包渲染进程
  2. Electron + Webpack  搭建开发环境及打包安装 ------- 打包主进程
  3. Electron + Webpack + Vue 搭建开发环境及打包安装 ---- 打包electron应用

三、打包Election App 应用

  在之前的节中已经写了渲染进程的打包,以及主线程的简单打包构建,那么这节就把之前两节的内容进行组合在一起。

1. 搭建项目

   首先在项目目录文件下运行 npm init -y 初始化项目生成package.json 文件

目录结构说明:

| - electron-vue

  | - app       打包构建目录

  | - builder      打包配置文件夹

    | - build.js    

    | - dev.js

    | - webpack.main.js

    | - webpack.render.js

  | - config    配置文件夹

    | - index.js

  | - pack    打包生成 exe 文件目录

  | - src      项目资源目录

    | - main    主线程文件

      | - createWindow

      | - main.js  主线程入口文件

    | - renderer  渲染线程文件

      | - assets

      | - components

      | - App.vue

      | - index.html

      | - index.js  渲染线程入口文件

    | - static     静态文件夹

  | - package.json

 

2. 编写webpack配置文件

  这里对于配置文件将不会再做过多说明,大多数配置已经在之前的几节中早有说明

  /builder/webpack.render.js   添加一下代码 (基本上都是复制第一节中的代码)

  1 /*
  2  * @Author: your name
  3  * @Date: 2020-12-19 20:11:31
  4  * @LastEditTime: 2020-12-19 23:05:45
  5  * @LastEditors: Please set LastEditors
  6  * @Description: In User Settings Edit
  7  * @FilePath: \electron-vue\builder\webpack.render.js
  8  */
  9 
 10 const path = require('path');
 11 const HtmlWebpackPlugin = require('html-webpack-plugin');
 12 const VueLoaderPlugin = require('vue-loader/lib/plugin');
 13 const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 14 const isDevMode = process.env.NODE_ENV === 'development';
 15 const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
 16 const CopyPlugin = require("copy-webpack-plugin");
 17 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 18 const webpack = require('webpack');
 19 
 20 module.exports = {
 21     // 配置打包模式为开发模式
 22     mode: process.env.NODE_ENV,
 23     // 打包入口文件
 24     entry: {
 25         app: path.join(__dirname, '../src/renderer/index.js')
 26     },
 27     // 打包出口文件
 28     output: {
 29         // 输出目录
 30         path: path.join(__dirname, '../app/'),
 31         // 公共路径前缀
 32         publicPath: isDevMode ? '/' : '',
 33         // 输出文件名
 34         filename: 'js/[name].[contenthash].js',
 35         // 配置按需加载文件
 36         chunkFilename: 'js/[name].bundle.js'
 37     },
 38     module: {
 39         rules: [{    // 添加解析 .vue文件loader
 40             test: /\.vue$/,
 41             loader: 'vue-loader'
 42         }, {        // 添加解析 .css文件loader
 43             test: /\.css(\?.*)?$/,
 44             use: [    // loader 顺序不能乱
 45                 'vue-style-loader',
 46                 'style-loader',
 47                 'css-loader'
 48             ]
 49         }, { // 配置sass语法支持,并且使用的是缩进格式
 50             test: /\.s[ac]ss$/,
 51             use: [
 52                 ...(
 53                     isDevMode
 54                     ? ['vue-style-loader', 'style-loader']
 55                     : [MiniCssExtractPlugin.loader]
 56                 ),
 57                 'css-loader',
 58                 {
 59                     loader: 'sass-loader',
 60                     options: {
 61                         sassOptions: {
 62                             indentedSyntax: true // 如需使用花括号嵌套模式则设置为false
 63                         }
 64                     }
 65                 }
 66             ]
 67         }, { // 配置Babel将ES6+ 转换为ES5
 68             test: /\.js(\?.*)?$/,
 69             exclude: file => ( // 排除node_modules文件夹
 70                 /node_modules/.test(file) &&
 71                 !/\.vue\.js/.test(file)
 72             ),
 73             use: {
 74                 loader: 'babel-loader',
 75                 options: {
 76                     presets: ['@babel/preset-env'],
 77                     plugins: ['@babel/plugin-transform-runtime']
 78                 }
 79             }
 80         }, { // 配置图片文件加载
 81             test: /\.(png|jpe?g|gif|tif?f|bmp|webp|svg)(\?.*)?$/,
 82             use: {
 83                 loader: 'url-loader',
 84                 options: {
 85                     limit: 10000,
 86                     esModule: false
 87                 }
 88             }
 89         }, { // 配置字体文件加载
 90             test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
 91             use: {
 92                 loader: 'file-loader',
 93                 options: {
 94                     esModule: false,
 95                     limit: 10000
 96                 }
 97             }
 98         }, { // 处理node文件
 99             test: /\.node$/,
100             loader: 'node-loader'
101         }]
102     },    // 配置 source-map 文件源码映射
103     // devtool: isDevMode ? 'cheap-eval-source-map': 'source-map',
104     node: {        // 添加node 变量
105         __dirname: isDevMode,
106         __filename: isDevMode
107     },
108     resolve: {
109         // 引入文件时可以省略文件后缀名
110         extensions:['.js','.json','.vue'],
111         // 常用路径别名
112         alias: {
113             '@': path.join(__dirname, '../src/')
114         }
115     },
116     plugins: [
117         // 配置HTML页面模板
118         new HtmlWebpackPlugin({
119             // 使用模板的路径
120             template: path.join(__dirname, '../src/renderer/index.html'),
121             // 输出后的文件路径
122             filename: './index.html',
123             // 对文件添加hash值, 防止文件缓存
124             hash: true
125         }),
126         new VueLoaderPlugin(),        // vue-loader 加载插件
127         new CleanWebpackPlugin({ // 清除所有文件,main.js文件除外 因为主线程热加载必须要存在main.js文件如果不存在将会报错,所以需要排除
128             cleanOnceBeforeBuildPatterns: ['**/*', '!main.js*']
129         }),
130         // new BundleAnalyzerPlugin({ analyzerPort: 8888 }), // chunks 分析插件 详细配置参考地址: https://github.com/webpack-contrib/webpack-bundle-analyzer
131         new webpack.optimize.SplitChunksPlugin({        // 详细配置参考地址: https://www.webpackjs.com/plugins/split-chunks-plugin/
132             cacheGroups: {
133                 default: {
134                     minChunks: 2,
135                     priority: -20,
136                     reuseExistingChunk: true
137                 },
138                 // 打包重复出现的代码
139                 vendor: {
140                     name: 'vendor',
141                     chunks: 'initial',
142                     minChunks: 2,
143                     maxInitialRequests: 5,
144                     minSize: 0
145                 },
146                 // 打包第三方类库
147                 commons: {
148                     name: 'commons',
149                     chunks: 'initial',
150                     minChunks: Infinity
151                 }
152             }
153         }),
154         new MiniCssExtractPlugin({    // css打包成css文件插件 详细配置参考地址:https://github.com/webpack-contrib/mini-css-extract-plugin
155             filename: 'css/[name].css',
156             chunkFilename: 'css/[id].css',
157         }),
158         new CopyPlugin({ // 复制静态文件   详细配置参考地址:https://github.com/webpack-contrib/copy-webpack-plugin
159             patterns: [{
160                 // 复制项目中所用到的公告文件
161                 from: path.join(__dirname, '../src/static'),
162                 to: path.join(__dirname, '../app/static')
163             }]
164         }),
165     ],
166     target: 'electron-renderer'
167 }

  /builder/webapck.main.js  添加以下代码(基本都是复制第二节中的代码)

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:11:41
 4  * @LastEditTime: 2020-12-19 22:02:42
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\builder\webpack.man.js
 8  */
 9 
10 const path = require('path');
11 const webpack = require('webpack');
12 const { dependencies } = require('../package.json');
13 const ElectronDevWebpackPlugin = require('electron-dev-webpack-plugin');
14 
15 module.exports = {
16     // 配置开发模式
17     mode: process.env.NODE_ENV,
18     entry: {
19         // 配置入口文件
20         main: path.join(__dirname, '../src/main/main.js')
21     },
22     // 配置出口文件
23     output: {
24         path: path.join(__dirname, '../app/'),
25         libraryTarget: 'commonjs2',
26         filename: '[name].js'
27     },
28     // 监听文件改变
29     watch: true,
30     optimization: {
31         minimize: true,
32     },
33     module: {
34         rules: [{
35             test: /\.js$/,
36             loader: 'babel-loader',
37             exclude: /node_modules/
38         }, {
39             test: /\.node$/,
40             loader: 'node-loader'
41         }]
42     },
43     externals: [
44         ...Object.keys(dependencies || {})
45     ],
46     node: {
47         __dirname: true,
48         __filename: true
49     },
50     plugins: [
51         new webpack.DefinePlugin({}),
52         new ElectronDevWebpackPlugin()
53     ],
54     target: 'electron-main'
55 }

  /builder/dev.js    添加以下代码

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:10:54
 4  * @LastEditTime: 2020-12-19 23:10:27
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\builder\dev.js
 8  */
 9 
10 process.env.NODE_ENV = 'development';
11 const webpack = require('webpack');
12 const WebpackDevServer = require('webpack-dev-server');
13 const webpackRenderConfig = require('./webpack.render.js');
14 const webpackMainConfig = require('./webpack.main.js');
15 const chalk = require('chalk');
16 
17 
18 // 构建开发环境
19 function devRender(){
20     return new Promise((resolve, reject) => {
21         const compiler = webpack(webpackRenderConfig);
22         new WebpackDevServer(compiler, {
23             contentBase: webpackRenderConfig.output.path,
24             publicPath: webpackRenderConfig.output.publicPath,
25             compress: true,        // 开发服务器启用gzip压缩
26             progress: true,        // 控制台显示打包进度
27             hot: true,            // 热加载
28         }).listen(8083, 'localhost', err => {
29             if(err) reject(err);
30             console.log(chalk.blue('\n Listening at http://localhost:8083 \n'));
31             resolve('渲染进程打包完毕');
32         })
33     });
34 }
35 
36 
37 function devMain(){
38     return new Promise((resolve, reject) => {
39          // 运行 webpack打包
40         webpack(webpackMainConfig, err => {
41             if(err){
42                 reject('打包主进程遇到Error!');
43             } else {
44                 resolve("打包主进程成功");
45             }
46         })
47     });
48 }
49 
50 Promise.all([devMain(), devRender()]).then(res => {
51     console.log('\n'+ res.join(' ') + '\n');
52 }).catch(err => {
53     console.log(err);
54 });

  /src/main/main.js   添加一下代码

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:11:58
 4  * @LastEditTime: 2020-12-19 22:00:18
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\src\main\index.js
 8  */
 9 
10 const electron = require('electron');
11 const { createMianWin } = require('./createWindow');
12 
13 class App {
14     constructor({app, BrowserWindow}){
15         this.BrowserWindow = BrowserWindow;
16         this.app = app;
17         this.win = null;
18         this.eventHandle(app);
19     }
20     createWindow(){
21         this.win = createMianWin();
22         this.win.loadURL('http://localhost:8083/');
23         // 等待渲染进程页面加载完毕再显示窗口
24         this.win.once('ready-to-show', () => this.win.show())
25     }
26     eventHandle(app){
27         app.on('closed', () => this.closed());
28         app.on('ready', () => this.ready());
29         app.on('window-all-closed', () => this.windowAllClosed());
30         app.on('activate', () => this.activate());
31     }
32     activate(){
33         if(!this.win) this.createWindow();
34     }
35     windowAllClosed(){
36         if(process.platform !== 'darwin') this.app.quit();
37     }
38     ready(){
39         this.createWindow();             // 创建主窗口
40     }
41     closed(){
42         this.win = null;
43     }
44 }
45 
46 let app = new App(electron);

  /src/main/createWindow/index.js    添加以下代码

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:16:07
 4  * @LastEditTime: 2020-12-19 23:07:39
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\src\main\createWindow\index.js
 8  */
 9 
10 const { BrowserWindow } = require('electron');
11 
12 module.exports = {
13     createMianWin(options = {}){
14         options = Object.assign({
15             width: 1200,    // 窗口宽度
16             height: 800,    // 窗口高度
17             // autoHideMenuBar:true,
18             backgroundColor: '#fff',    // 窗口背景颜色
19             show: false,                // 创建窗口后不显示窗口
20             hasShadow: false,
21             webPreferences:{
22                 nodeIntegration: true, // 在渲染进程引入node模块
23             }
24         }, options);
25         return new BrowserWindow(options);
26     }
27 }

  /src/renderer/index.js    添加以下代码

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:12:07
 4  * @LastEditTime: 2020-12-19 21:07:58
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\src\renderer\index.js
 8  */
 9 
10 import Vue from 'vue';
11 import App from './App';
12 
13 const app = new Vue({
14     render: h => h(App)
15 }).$mount("#app");

  /src/renderer/index.html   添加以下代码

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>Document</title>
 7     <link rel="stylesheet" href="./static/css/base.css">
 8 </head>
 9 <body>
10     <div id="app"></div>
11 </body>
12 </html>

  /src/renderer/App.vue  添加以下代码

 1 <!--
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:13:48
 4  * @LastEditTime: 2020-12-19 23:22:44
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\src\renderer\App.vue
 8 -->
 9 <template>
10 <div> 
11     <h1>{{txt}}</h1>
12 </div>
13 </template>
14 
15 <script>
16 export default {
17     data(){
18         return {
19             txt: 'hello electron 11.1'
20         }
21     }
22 }
23 </script>
24 
25 <style lang="sass" scoped>
26 h1
27     color: red
28 </style>

  /src/static/css/base.css  添加以下代码

1 html, body {
2     margin: 0;
3     padding: 0;
4 }

  /package.json  添加以下代码

  将main 选项修改成   "main": "./app/main.js" 

  添加新的npm指令   "dev": "node ./builder/dev.js" 

3. 下载项目所需依赖包

  1. chalk
  2. html-webpack-plugin
  3. webpack
  4. webpack-cli
  5. webpack-dev-server
  6. vue-loader
  7. css-loader
  8. vue
  9. style-loader
  10. vue-style-loader
  11. vue-template-compiler
  12. webpack-bundle-analyzer
  13. copy-webpack-plugin
  14. mini-css-extract-plugin
  15. sass-loader
  16. babel-loader
  17. @babel/preset-env
  18. @babel/plugin-transform-runtime
  19. @babel/core
  20. url-loader
  21. file-loader
  22. node-loader
  23. node-sass
  24. core-js
  25. electron-dev-webpack-plugin
  26. electron

4. 在项目的文件夹打开命令行窗口 运行npm run dev 

如果没有什么报错的话将会弹出一个新的electron App的窗口,有可能会报错就是缺少安装的模块,到此就完成了开发环境的配置

 5. 构建生产环境

  /builder/build.js   添加以下代码

  1. 设置 app 一些选项
  2. 打包渲染进程
  3. 压缩渲染进程
  4. 打包主进程
  5. 打包App
  1 /*
  2  * @Author: your name
  3  * @Date: 2020-12-19 20:11:04
  4  * @LastEditTime: 2020-12-20 11:58:58
  5  * @LastEditors: Please set LastEditors
  6  * @Description: In User Settings Edit
  7  * @FilePath: \electron-vue\builder\build.js
  8  */
  9 
 10 process.env.NODE_ENV = 'production';
 11 const chalk = require('chalk');
 12 const del = require('del');
 13 const webpack = require('webpack');
 14 const path = require('path');
 15 const fs = require('fs');
 16 const { spawn } = require('child_process');
 17 const renderConfig = require("./webpack.render.js");
 18 const mainRenderConfig = require('./webpack.main.js');
 19 const electronBuilder = require('electron-builder');
 20 const packageJson = require('../package.json');
 21 const archiver = require('archiver');
 22 
 23 const build = {
 24     setup: {},
 25     run(){
 26         del(['./app/*', './pack/*']);
 27         // 初始化版本信息
 28         this.initSetup();
 29         this.writeVersionConfig();
 30         this.buildApp();
 31     },
 32     initSetup(){
 33         const setup = require('../config/index.js');
 34         const runTimeObj = {
 35             dev: '开发版',
 36             test: '测试版',
 37             release: '正式版'
 38         }
 39         setup.versionName = runTimeObj.release;
 40         setup.publishTime = new Date().toLocaleString();
 41         Object.keys(runTimeObj).forEach(key => {
 42             if(process.argv.indexOf(key) > 1){
 43                 setup.versionType = key;
 44                 setup.versionName = runTimeObj[key];
 45             }
 46         });
 47         this.runTime(setup.versionType);
 48         this.setup = setup;
 49     },
 50     runTime(val){
 51         console.log(
 52             chalk.black.bgYellow('当前环境为:')
 53             + chalk.yellow.bgRed.bold(val)
 54         );
 55     },
 56     writeVersionConfig(){
 57         fs.writeFileSync(path.join(__dirname, '../config/index.js'), `module.exports = ${JSON.stringify(this.setup, null, 4)}`);
 58         packageJson.version = this.setup.version.slice(0,3).join('.');
 59         fs.writeFileSync(path.join(__dirname, '../package.json'), JSON.stringify(packageJson,null,4));
 60     },
 61     // 创建文件夹,如果文件夹已存在则什么都不做
 62     async createFolder(outpath){
 63         return new Promise(resolve => {
 64             fs.exists(outpath, exists => {
 65                 if(!exists) fs.mkdirSync(outpath);
 66                 resolve(1);
 67             });
 68         })
 69     },  // 打包App
 70     buildApp(){
 71         this.viewBuilder().then(async () => {
 72             let outpath = path.join(__dirname, '../pack/');
 73             // 创建一个pack目录
 74             await this.createFolder(outpath);
 75             let zipPath = renderConfig.output.path;
 76             let fileName = this.setup.versionType+ '-' + this.setup.version.join('.');
 77             let filePath = path.join(zipPath, `../pack/${fileName}.zip`);
 78             this.compress(zipPath, filePath, 7, (type, msg)=>{
 79                 if(type === 'error'){
 80                     return Promise.reject('压缩文件出错:'+ msg);
 81                 } else {
 82                     this.packMain();
 83                     console.log(`压缩包大小为:${(msg/1024/1024).toFixed(2)}MB`);
 84                 }
 85             });
 86         }).catch(err=>{
 87             console.log(err);
 88             process.exit(1);
 89         })
 90     }, 
 91     packMain(){
 92         this.mainBuild().then(()=>{
 93             electronBuilder.build().then(() => {
 94                 this.openExplorer();
 95             }).catch(error => {
 96                 console.log(error);
 97             })
 98         }).catch(err=>{
 99             console.log(err);
100             process.exit(2);
101         })
102     },  // 压缩打包文件
103     compress(filePath, zipPath, level = 9, callback){
104         const outpath = fs.createWriteStream(zipPath);
105         const archive = archiver('zip', {
106             zlib: { level }
107         });
108         archive.pipe(outpath);
109         archive.directory(filePath, false);
110         archive.on('error', err => {
111             if(callback) callback('error', err);
112         });
113         outpath.on('close', ()=>{
114             let size = archive.pointer();
115             if(callback) callback('success', size);
116         });
117         archive.finalize();
118     },
119     // 打开文件管理器
120     openExplorer() {
121         const dirPath = path.join(__dirname, '../pack/');
122         if (process.platform === 'darwin') {
123             spawn('open', [dirPath]);
124         } else if (process.platform === 'win32') {
125             spawn('explorer', [dirPath]);
126         } else if (process.platform === 'linux') {
127             spawn('nautilus', [dirPath]);
128         }
129     },  // 打包渲染进程
130     viewBuilder(){
131         return new Promise((resolve, reject) => {
132             const renderCompiler = webpack(renderConfig);
133             renderCompiler.run(err => {
134                 if(err){
135                     reject(chalk.red("打包渲染进程:" + err));
136                 } else {
137                     console.log('打包渲染进程完毕!');
138                     resolve();
139                 }
140             })
141         })
142     },  // 打包主进程
143     mainBuild(){
144         return new Promise((resolve, reject)=>{
145             const mainRenderCompiler = webpack(mainRenderConfig);
146             mainRenderCompiler.run(err => {
147                 if(err){
148                     reject(chalk.red('打包主进程出错' + err));
149                 } else {
150                     console.log('打包主进程完毕!');
151                     resolve();
152                 }
153             })
154         })
155     }
156 }
157 
158 build.run();

  /builder/webpack.mian.js  修改以下代码

 1 /*
 2  * @Author: your name
 3  * @Date: 2020-12-19 20:11:41
 4  * @LastEditTime: 2020-12-20 12:47:43
 5  * @LastEditors: Please set LastEditors
 6  * @Description: In User Settings Edit
 7  * @FilePath: \electron-vue\builder\webpack.man.js
 8  */
 9 
10 const path = require('path');
11 const webpack = require('webpack');
12 const { dependencies } = require('../package.json');
13 const ElectronDevWebpackPlugin = require('electron-dev-webpack-plugin');
14 const isDevMode = process.env.NODE_ENV === 'development';
15 let plugins = [new webpack.DefinePlugin({})]
16 if(process.env.NODE_ENV === 'development') plugins.push(new ElectronDevWebpackPlugin())
17 
18 module.exports = {
19     // 配置开发模式
20     mode: process.env.NODE_ENV,
21     entry: {
22         // 配置入口文件
23         main: path.join(__dirname, '../src/main/main.js')
24     },
25     // 配置出口文件
26     output: {
27         path: path.join(__dirname, '../app/'),
28         libraryTarget: 'commonjs2',
29         filename: '[name].js'
30     },
31     // 监听文件改变
32     watch: isDevMode,
33     optimization: {
34         minimize: true,
35     },
36     module: {
37         rules: [{
38             test: /\.js$/,
39             loader: 'babel-loader',
40             exclude: /node_modules/
41         }, {
42             test: /\.node$/,
43             loader: 'node-loader'
44         }]
45     },
46     externals: [
47         ...Object.keys(dependencies || {})
48     ],
49     node: {
50         __dirname: isDevMode,
51         __filename: isDevMode
52     },
53     plugins,
54     target: 'electron-main'
55 }

  /package.json    添加以下代码

 1 {
 2     "name": "electron-vue",
 3     "version": "1.0.1",
 4     "description": "",
 5     "main": "./app/main.js",
 6     "scripts": {
 7         "test": "echo \"Error: no test specified\" && exit 1",
 8         "dev": "node ./builder/dev.js",
 9         "build": "node ./builder/build.js"
10     },
11     "keywords": [],
12     "author": "",
13     "license": "ISC",
14     "dependencies": {
15         "vue": "^2.6.12"
16     },
17     "devDependencies": {
18         "@babel/core": "^7.12.10",
19         "@babel/plugin-transform-runtime": "^7.12.10",
20         "@babel/preset-env": "^7.12.11",
21         "archiver": "^5.1.0",
22         "babel-loader": "^8.2.2",
23         "chalk": "^4.1.0",
24         "clean-webpack-plugin": "^3.0.0",
25         "copy-webpack-plugin": "^7.0.0",
26         "core-js": "^3.8.1",
27         "css-loader": "^5.0.1",
28         "del": "^6.0.0",
29         "electron": "^11.1.0",
30         "electron-builder": "^22.9.1",
31         "electron-dev-webpack-plugin": "^1.0.5",
32         "file-loader": "^6.2.0",
33         "html-webpack-plugin": "^4.5.0",
34         "mini-css-extract-plugin": "^1.3.3",
35         "node-loader": "^1.0.2",
36         "node-sass": "^5.0.0",
37         "sass-loader": "^10.1.0",
38         "style-loader": "^2.0.0",
39         "url-loader": "^4.1.1",
40         "vue-loader": "^15.9.6",
41         "vue-style-loader": "^4.1.2",
42         "vue-template-compiler": "^2.6.12",
43         "webpack": "^5.11.0",
44         "webpack-bundle-analyzer": "^4.3.0",
45         "webpack-cli": "^4.2.0",
46         "webpack-dev-server": "^3.11.0"
47     },
48     "build": {    // build 配置的详细参考地址:https://www.electron.build/configuration/configuration#build
49         "asar": true,  // 是否打包为asar文件
50         "productName": "Electron+vue",  // 应用名称
51         "appId": "com.electron.template",
52         "copyright": "Copyright © year motou",
53         "directories": {
54             "output": "pack"    // 打包输出目录
55         },
56         "files": [
57             "app/**"        // 打包文件
58         ],
59         "mac": {
60             "identity": "com.electron.template",
61             "target": [
62                 "dmg"
63             ],
64             "artifactName": "${productName}.${ext}",
65             "icon": "./icon.jpg"
66         },
67         "dmg": {
68             "title": "${productName}",
69             "artifactName": "${productName}.${ext}",
70             "icon": "./icon.jpg"
71         },
72         "win": {
73             "legalTrademarks": "Copyright © year motou",
74             "publisherName": "electron",
75             "requestedExecutionLevel": "highestAvailable",
76             "target": [
77                 {
78                     "target": "nsis",
79                     "arch": [
80                         "x64"
81                     ]
82                 }
83             ],
84             "artifactName": "${productName}.${ext}",
85             "icon": "./icon.jpg"  // 应用的icon图标
86         },
87         "nsis": {    
88             "oneClick": false,    // 表示不是一键安装
89             "createDesktopShortcut": "always",  // 允许创建桌面快捷方式
90             "allowToChangeInstallationDirectory": true,  // 允许修改安装目录
91             "perMachine": true,    // 如果已安装,再次安装的时候,会要求用户先删除之前的程序
92             "allowElevation": true,  // 允许请求提升(权限)
93             "artifactName": "${productName}-V${version}.${ext}",  // 安装包名称
94             "runAfterFinish": true,    // 安装完成是否运行程序
95             "shortcutName": "electron+vue"  // 快捷方式名称
96         }
97     }
98 }

  /src/main/main.js  修改以下代码

/*
 * @Author: your name
 * @Date: 2020-12-19 20:11:58
 * @LastEditTime: 2020-12-20 12:47:10
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \electron-vue\src\main\index.js
 */

const path = require('path');
const url = require('url');
const electron = require('electron');
const { createMianWin } = require('./createWindow');

class App {
    constructor({app, BrowserWindow}){
        this.mode = process.env.NODE_ENV;
        this.BrowserWindow = BrowserWindow;
        this.app = app;
        this.win = null;
        this.eventHandle(app);
    }
    createWindow(){
        this.win = createMianWin();  // 打包之后加载的文件为index.html 文件所以需要更换加载目录
        let filePath = this.mode === 'production'
            ? url.pathToFileURL(path.join(__dirname, 'index.html')).href
            : "http://localhost:8083/";
        this.win.loadURL(filePath);
        // 等待渲染进程页面加载完毕再显示窗口
        this.win.once('ready-to-show', () => this.win.show())
    }
    eventHandle(app){
        app.on('closed', () => this.closed());
        app.on('ready', () => this.ready());
        app.on('window-all-closed', () => this.windowAllClosed());
        app.on('activate', () => this.activate());
    }
    activate(){
        if(!this.win) this.createWindow();
    }
    windowAllClosed(){
        if(process.platform !== 'darwin') this.app.quit();
    }
    ready(){
        this.createWindow();             // 创建主窗口
    }
    closed(){
        this.win = null;
    }
}

let app = new App(electron);

6. 运行 npm run build 进行打包

  

   运行之后如果看到如下结果表示打包成功, 在该过程中需要下载一个包,第一次打包下载会非常慢,可能会导致下载失败或者是网络超时,多尝试几次,或者自己单独的去网上下载

  还有就是打包完成的时候可能会被360阻止认为是木马程序,一定要点允许或者是添加到信任。

  最后附上源码地址: https://github.com/Liting1/electron-vue

  还有一些关于webpack打包多页面的配置没有写,后面会加上 打包多页面也就是每一个窗口使用的是一个vue的单页面。

  有不足或不对的地方欢迎指正

 完整版最新地址: https://github.com/Liting1/electron-vue-template

posted @ 2020-12-20 13:25  木头人_a  阅读(1344)  评论(0编辑  收藏  举报