三、Electron + Webpack + Vue 搭建开发环境及打包安装 ---- 打包electron应用
目录
- Webpack + Vue 搭建开发环境及打包安装 ------- 打包渲染进程
- Electron + Webpack 搭建开发环境及打包安装 ------- 打包主进程
- 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. 下载项目所需依赖包
- chalk
- html-webpack-plugin
- webpack
- webpack-cli
- webpack-dev-server
- vue-loader
- css-loader
- vue
- style-loader
- vue-style-loader
- vue-template-compiler
- webpack-bundle-analyzer
- copy-webpack-plugin
- mini-css-extract-plugin
- sass-loader
- babel-loader
- @babel/preset-env
- @babel/plugin-transform-runtime
- @babel/core
- url-loader
- file-loader
- node-loader
- node-sass
- core-js
- electron-dev-webpack-plugin
- electron
4. 在项目的文件夹打开命令行窗口 运行npm run dev
如果没有什么报错的话将会弹出一个新的electron App的窗口,有可能会报错就是缺少安装的模块,到此就完成了开发环境的配置
5. 构建生产环境
/builder/build.js 添加以下代码
- 设置 app 一些选项
- 打包渲染进程
- 压缩渲染进程
- 打包主进程
- 打包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的单页面。
有不足或不对的地方欢迎指正