三、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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM