导航:

(一)Electron跑起来
(二)从零搭建Vue全家桶+webpack项目框架
(三)Electron+Vue+Webpack,联合调试整个项目
(四)Electron配置润色
(五)预加载及自动更新
(六)构建、发布整个项目(包括client和web)

摘要:整个项目就剩最后一哆嗦了,但仅仅是当作demo模版来说,实际项目的话,还有很多需要细化的地方。项目完整代码:https://github.com/luohao8023/electron-vue-template,随博客更新。

一、打包客户端

首先是要改一下build.js,把上篇文章没做的事儿给做了。

上篇文章已经构建出了可执行文件目录app,这次我们要做的就是使用electron-builder把app目录打包为安装包。

在之前的基础上引入electron-builder,然后对app目录进行打包:

const builder = require('electron-builder');

// 在所有的打包逻辑执行完成之后,确认已经正确生成了app目录
builder.build().then(() => {
del(['./pack/*.yaml', './pack/*.blockmap']);
// 为了方便,打包完成之后我们打开文件管理器
openFileManager();
}); function openFileManager() {
// 打开文件管理器
let dirPath = path.join(__dirname, '..', 'pack');
if (process.platform === 'darwin') {
spawn('open', [dirPath]);
} else if (process.platform === 'win32') {
spawn('explorer', [dirPath]);
} else if (process.platform === 'linux') {
spawn('nautilus', [dirPath]);
}
}

然后自信满满的开始打包。。。。

报错了,说是什么描述缺失,icon没有设置啥的,就是打包的时候没有配置呗,去看下package.json文件,果然是少了build字段,package.json文件中的build字段就是有关打包的配置,一些必要的配置项还是要填的。

在package.json中增加build字段:

"build": {
"asar": true,
"productName": "Electron+vue+webpack模板",
"appId": "com.electron.template",
"copyright": "Copyright © template",
"directories": {
"output": "pack"
},
"files": [
"app/**"
],
"mac": {
"identity": "com.electron.templat",
"target": [
"dmg"
],
"artifactName": "${productName}.${ext}",
"icon": "main/favicon/favicon.icns"
},
"dmg": {
"title": "${productName}",
"artifactName": "${productName}.${ext}",
"icon": "main/favicon/favicon.icns"
},
"win": {
"legalTrademarks": "Copyright © template",
"publisherName": "electron",
"requestedExecutionLevel": "highestAvailable",
"target": [
{
"target": "nsis",
"arch": [
"ia32"
]
}
],
"artifactName": "${productName}.${ext}",
"icon": "main/favicon/favicon.ico"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"perMachine": true,
"allowElevation": true,
"artifactName": "${productName}-安装包-V${version}.${ext}",
"runAfterFinish": true,
"shortcutName": "Electron+vue+webpack-template"
}
},

现在我们来挨个解读一下各个配置项都是什么意思,当然还有很多其他配置,这里不再额外介绍了。

asar:是否打包为asar文件,设置为true的话,相当于给你的代码加密了一下,直接就是个.asar的文件,具体内容需要解密了之后才能看到;设置为false的话,不对你的代码进行加密处理,也就是用户安装你的程序之后,找到安装目录,就能直接看到源码,目录结构跟你开发的时候是一样的,不太安全,建议设置为true;

productName:你的应用名称,比如会显示在安装程序的标题处,以及安装完成后的应用程序目录里;
appId:你程序的唯一id,比如绑定到某第三方平台或应用市场,一般会需要这个,我是没有,随便填的;
copyright:按照网站的copyright来理解就好啦,如果你的程序不需要发不到各大市场的话,这个内容可以忽略;
directories:它下面还有其他属性,这里我们只填了ouptut选项,就是打包输出目录,我们这里填了pack文件夹;
files:需要打包哪些内容,就是你的源代码,我们这里填的"app/*",就是app目录下的所有内容;
 
上面都是一些基础的内容,下面介绍一下针对不同平台的配置:
mac:
identity:这个我不是特别清楚,看名字应该是表明开发者或者软件身份的东西;
target:你要打包成什么格式的安装包,这里填的是dmg,可以填多个;
artifactName:生成的可执行文件的名称;
icon:应用图标,显示在桌面快捷方式或者系统托盘;
针对dmg的单独配置这里就不说了,因为mac选项的target属性可以多填,我们填了dmg,就对dmg做了单独的配置,也可以忽略;
win:
legalTrademarks:合法商标。。。。。。
publisherName:发行商类似的意思;
requestedExecutionLevel:应用程序需要的权限,我们这里填的是highestAvailable,就是当前用户允许的最高权限,你如果是管理员用户在使用,那就是管理员权限,如果是普通用户在使用那就是普通管理员权限。设置为最高权限可以解决一些问题,比如对c盘的一些文件进行操作等。但是请注意一点,如果你的程序是以管理员身份运行的,但是你又想实现从桌面往应用程序中拖动文件的功能,这是不行的,因为文件管理器的权限是低于管理员的,windows上无法从低权限处往高权限处拖动文件,这点还是要注意一下;
target:目标平台,我们选32位,并且使用nsis打包;
artifactName:可执行文件名称;
icon:应用图标;
nsis:
因为electron-builder是基于nsis打包的(有兴趣的可以了解一下nsis),所以这里提供了一些基础配置:
oneClick:不是点击一次,也不是单例什么的,这里是一键安装的意思,设置为true的话,只要双击打开安装包,程序会自动安装并运行;建议设置为false,让用户点击下一步、下一步来安装;
allowToChangeInstallationDirectory:是否允许修改安装目录,默认为false;
perMachine:每台机器是否只允许安装一个程序,如果已安装,再次安装的时候,会要求用户先删除之前的程序;
allowElevation:允许请求提升(权限),如果设置为false,用户必须重启程序才能安装提升了权限的安装程序;
artifactName:安装包名称;
runAfterFinish:安装完成是否运行程序;
shortcutName:快捷方式名称
这是模版里用到的所有属性,解释的也不一定对。当然还有很多其他的配置项,感兴趣的可以搜一下了解了解,说不定某个小小的配置就能解决你一个大问题呢。
 
好了,说了这么多,现在接着运行打包命令吧,看看啥情况:
(node:96470) UnhandledPromiseRejectionWarning: Error: Application entry file "index.js" in the "/Volumes/SHARE/projects/github/electron-vue-template/pack/mac/Electron+vue+webpack模板.app/Contents/Resources/app.asar" does not exist. Seems like a wrong configuration.

还是有错啊,说的很详细,说是程序入口文件index.js不存在,我们看一下:

  "name": "electron-vue-template",
"version": "1.0.0",
"description": "electron-vue-template",
"main": "index.js",
"scripts": {
"dev": "node ./builder/dev.js",
"build": "node ./builder/build.js"
},

main字段就是程序入口,我们写的是index.js,看下代码目录,我们的主进程入口是main.js,那就改一下吧,把index.js改为main.js,接着运行打包命令:

还是出错呦,入口文件找不到,这个问题还真想来好大一会儿,感觉没有错啊,名称也修改来,就是main.js啊,又瞅了眼代码目录才恍然大悟,这不阴沟里翻船嘛,通常情况下main.js是在工程根目录的,但是我们规划完工程目录之后,把main.js给打包到app目录下了,所以入口字段应该填"app/main.js",接着运行打包命令,这次终于成功了,看下pack文件夹中生成的文件:

第一个dmg文件就是mac的安装包,第二个yml文件记录了程序的一些基本信息,mac文件夹下是一个免安装的可执行程序,最后一个就是我们压缩出来的小版本,windows下跟这个目录不一样。

先不着急安装,打开mac文件夹下的可执行程序,可以直接打开我们的程序,打开之后懵了,一片空白啊,啥东西也没有,赶紧找找原因。

打开app目录发现,没有生成update.html,经排查发现,上次提交的代码有个地方写错了,拼错了个单词:

Promise.all([buildPreload(), buildRender()]).then(resolve => {
resolve.forEach(log => {
console.log('打包输出===>', log);
});
const outpath = path.join(__dirname, '../pack/');
try {
fs.mkdirSync(outpath);
} catch(e) {
console.log('已创建pack文件夹', e);
}
console.log('打包渲染进程完毕!压缩小版本!');
const zipPath = renderConfig.output.path;
const fileName = setup.versionType + '-' + setup.version.join('.');
const filePath = path.join(zipPath, `../pack/${fileName}.zip`);
compress(zipPath, filePath, 7 , (type,msg) => {
if (type === 'error'){
Promise.reject('压缩文件时出错:' + msg);
} else {
console.log(`压缩包大小为:${(msg / 1024 / 1024).toFixed(2)}MB`);
}
});
Promise.all([buildMain(), buildUpdate()]).then(resplve => {
resolve.forEach(log => {
console.log('打包输出===>', log)
});
builder.build().then(() => {
del(['./pack/*.yaml', './pack/*.blockmap']);
openFileManager();
});
}).catch(err => {
console.error('打包【main】-【update】错误输出===>', err);
process.exit(2);
});
}).catch(err => {
console.error('打包【preload】-【render】出错,输出===>', err);
process.exit(1);
});

看一下,第二个Promise.all.then中,参数写成了resplve,而在打印log的时候用的是resolve,偏偏上面有resovle,所以也没报错,但是第二次promise的log就全被吃了,赶紧改回来,再跑一下,果然有个错误:

打包输出===> ModuleNotFoundError: Module not found: Error: Can't resolve 'css-loader' in '/Volumes/SHARE/projects/github/electron-vue-template':undefined

没有css-loader,那就装一个:

打包输出===> ModuleNotFoundError: Module not found: Error: Can't resolve 'less-loader' in '/Volumes/SHARE/projects/github/electron-vue-template':undefined

又说没有less-loader,再装一个,运行命令,看到app目录下生成了update.html,这下应该没问题了吧。

打开mac文件夹下的免安装文件,程序启动后跟我们本地调试的效果是一样的,再使用安装包安装一下,安装完成打开后也是正常的。

好啦,打包客户端就说到这儿了,下面说一下怎么使用同一套代码打包web端。

二、打包web端

这里建议把打包web端的逻辑单独拆出来,网站代码是同一套,但是打包逻辑是两套

dev的逻辑就是起个devServer返回html文件就行了,不再多说。

而打包的话是针对单页面的,只会生成一个html文件,如果相针对每个路由都生成一个html文件,这里提供下思路:

引入路由文件,遍历路由,拿到路径,针对每个路径,实例化一个HtmlWebpackPlugin,即可生成一个html文件:

webpackDevConfig.plugins.push(new HtmlWebpackPlugin({
template: './src/index.ejs',
filename: `.${routerPah}`,
title: "加载中...",
inject: false,
hash: true,
minify: false,
cache: false
}))

在package.js中增加启动命令:

  "scripts": {
"dev": "node ./buildClient/dev.js",
"devweb": "node ./buildWeb/dev.js",
"build": "node ./buildClient/build.js",
"buildweb": "node ./buildWeb/build.js"
}

分别调试和打包客户端、web端。

这篇文章端内容就到这里了,具体的逻辑还是要去看代码的。针对这套逻辑我们其实有已经上线了的产品的,很多细化的东西也有,但是不便拿出来说,也不好做成demo。模板中可能会有些冗余代码,就是之前的逻辑没有删除干净,自行优化就好了。

有什么问题欢迎留言讨论。项目完整代码:https://github.com/luohao8023/electron-vue-template

【原创】从零开始搭建Electron+Vue+Webpack项目框架(六)Electron打包,同时构建客户端和web端的更多相关文章

  1. 【原创】从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(二)

    摘要:上篇文章说到了如何新建工程,并启动一个最简单的Electron应用.“跑起来”了Electron,那就接着把Vue“跑起来”吧.有一点需要说明的是,webpack是贯穿这个系列始终的,我也是本着 ...

  2. 【原创】从零开始搭建Electron+Vue+Webpack项目框架(五)预加载和Electron自动更新

    导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...

  3. 从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(一)

    摘要:随着前端技术的飞速发展,越来越多的技术领域开始被前端工程师踏足.从NodeJs问世至今,各种前端工具脚手架.服务端框架层出不穷,“全栈工程师”对于前端开发者来说,再也不只是说说而已.在NodeJ ...

  4. Vue+webpack项目的多环境打包配置

    背景:由于需要将应用部署到线上开发环境.线上测试环境.线上预发环境.线上生产环境,而每个环境的访问地址是不同的.如果每次更改请求地址未免有些繁琐,就考虑在本地进行一次性配置. 代码管理工具:git 代 ...

  5. vue-用Vue-cli从零开始搭建一个Vue项目

    Vue是近两年来比较火的一个前端框架(渐进式框架吧). Vue两大核心思想:组件化和数据驱动.组件化就是将一个整体合理拆分为一个一个小块(组件),组件可重复使用:数据驱动是前端的未来发展方向,释放了对 ...

  6. 搭建自己的Webpack项目

    五,搭建自己的Webpack项目  https://www.jianshu.com/p/42e11515c10f

  7. 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之四Nlog记录日志至数据库

    为什么要进行日志记录呢?为什么要存至数据库呢?只能说日志记录是每个系统都应当有的. 好的日志记录方式可以提供我们足够多定位问题的依据.查找系统或软件或项目的错误或异常记录.程序在运行时就像一个机器人, ...

  8. 从零开始:一个正式的vue+webpack项目的目录结构是怎么形成的

    如何从零开始一个vue+webpack前端工程工作流的搭建,首先我们先从项目的目录结构入手.一个持续可发展,不断加入新功能,方便后期维护的目录结构究竟是长什么样子的?接下来闰土大叔带你们一起手摸手学起 ...

  9. (转)windows环境vue+webpack项目搭建

    首先,vue.js是一种前端框架,一般利用vue创建项目是要搭配webpack项目构建工具的,而webpack在执行打包压缩的时候是依赖node.js的环境的,所以,要进行vue项目的开发,我们首先要 ...

随机推荐

  1. Python常见经典

    python中if __name__ == '__main__': 的解析 当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它 ...

  2. 搭建Docker私有仓库&用户密码认证&web可视化界面

    1.拉取镜像 docker pull hyper/docker-registry-web docker pull registry 2.安装 yum install docker-compose 3. ...

  3. CSS样式表---------第三章:样式属性

    三.样式属性 1.背景与前景 background-color:#90; ------------背景色,样式表优先级高. background-image:url(路径)-------------- ...

  4. 5-7 学生cpp成绩统计

    完成“学生cpp成绩计算”之后,修改Person和Student类,各自增加两个无参构造函数. 仍以Person类为基础,建立一个派生类Teacher,增加以下成员数据: int ID;//教师工号 ...

  5. LootCode-链表排序-Java

    链表排序 0.来源 来源:力扣(LeetCode) 题目链接:https://leetcode-cn.com/problems/sort-list 1.题目描述 在 O(n log n) 时间复杂度和 ...

  6. 88)PHP,PDOStatement对象

    PDOStatement类,称之为PDO语句对象,SQL执行完(处理完)产生的结果对象. fetchColumn(index=) 允许传递参数,表示获得第一条记录的第几个字段的值. 相当于 getOn ...

  7. Python--继承、封装、多态

    大概每个人在学生时代开始就使用Java了,我们一直在学习Java,但Java中总有一些概念含混不清,不论是对初级还是高级程序员都是如此.所以,这篇文章的目的就是弄清楚这些概念. 读完本文你会对这些概念 ...

  8. interrupt 停止线程

    该方法只是给线程设置了一个停止的标记 并不是真正的立即停止线程 interrupted() 测试当前线程是否已经中断 isInterrupted() 测试线程是否已经中断 停止线程的方法: .异常法 ...

  9. 深入JVM内核--常用JVM配置参数

    Trace跟踪参数 -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K ...

  10. [LC] 442. Find All Duplicates in an Array

    Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others ...