使用electron开发桌面级小程序自动部署系统

支持部署小程序开发者工具的坑,接下来我将此次开发过程的思考和问题进行总结,从多个角度来介绍本项目。

J.A.R.V.I.S是做什么的?

它是一个安装在Mac或Windows上的app程序,可以随时从Git上拉取最新代码选取分支和tag并自动打包构建不同环境上传至小程序后台的发布系统。

为什么叫J.A.R.V.I.S?

老贾是唐尼的智能管家,项目启动的时候正值复联四热映,主要是为了纪念一下唐尼吧,在星期五和Jarvis两个名字中犹豫了好久,最后还是觉得Jarvis比较酷一点,嗯,就是这么随意。

设计思路

工作原理

electron本质上就是一个将web打包成桌面应用的 Node. js 的变体,在开启app的同时就会启动一个node服务,通过node可以实现很多前端无法实现的事情,一个发布系统整个流程都是千篇一律的,无非就是拉代码、拉分支、切分支、构建开发包、上传后台。其中拉代码、切分支、构建这种平时在命令行内进行的操作,可以将它交给nodeJs提供的child-process衍生子进程的功能进行不同目录下的shell脚本执行,最关键的上传则需要通过node请求微信开发中工具提供的api为渲染层提供上传接口进行相应操作。最后将electron项目打包为app,分别装在开发者的电脑上就可以实现一个基础版的小程序上传系统。

工作流程

配置

第一次使用需要先进行基础配置,将本机用户名、项目地址、开发者昵称一并保存到本地Stroage,为后续操作提供基础信息。保存的同时将项目拉取到本地的Applications目录中并新建一个jarvis目录,此目录用来保存以后所有需要构建的小程序项目,此时jarvis目录作为一个黑盒子,所有的信息都是从git拉下来的最新提交,与本地项目的开发代码会形成隔离,你的本地任何代码改动操作都不会影响到盒子内项目的信息,除非你进行了commit。

打包构建

切换分支

配置完基础信息后调用gitlabApi拉取该项目的分支和tag信息,渲染到下拉列表选择切换本地分支,同时在面板展示分支的基础信息,项目名称、当前分支名称、提交时间、提交描述、提交成员、提交id......

项目编译

接下来需要填写本次上传的版本号和版本描述并选择打包环境,然后进行项目构建。这里选择环境选择的是需要打包项目的根目录中的构建命令,比如我的小程序项目使用gulp构建,gulpfile中定义了四种打包命令,那么在点击开始项目构建后,程序会自动切换到黑盒中的项目根目录下执行对应命令并打包为dist文件。

上传

打包完之后的文件通过微信官方提供的http调用接口,先获取到开发者工具在本地的端口号文件,通过调用upload的api拼接端口号、项目路径、描述、版本号进行上传。上传成功后在面板上展示上传信息和上传状态并且通过钉钉群同步推送上传消息,包含发布版本、描述、发布人,最后在微信公众平台选择设置体验版。到此,一个完整的编译打包上传流程全部完成。

谈谈基础架构

整体使用vue-electron框架,分为五个大模块

  • dist——src的输出目录
  • src--开发目录
  • static——静态资源文件目录
  • build——打包文件目录
  • .electron-vue——webpack配置目录

.electron-vue——webpack配置目录

此目录下保存着不同的webpack配置文件,使用vue-loader、babel-loader、url-loader、vue-html-loader、post-css等插件使项目成为支持解析.vue文件,可使用高级js语法的现代化工程,并且会将开发目录打包为标准的electron项目。

dist electron输出目录

通过webpack将项目打包为一个electron的标准项目,输出到dist目录下,package.json将会以此目录下的mian.js作为入口文件进行运行。

src——开发目录

src作为核心内容,包含三大部分main(electron主进程文件目录)、render(前端渲染层页面——vue+element)、service(后端提供服务接口——express)。

main作为一个桥梁的存在,链接着渲染层和服务端进程。其中service-main.js作为service中express的的启动文件导出,并在main/index.js中与electron同时启动,index.js为启动electron的核心文件,最后会被webpack编译输出到输出目录下——dist/electron/main.js

render负责前端页面的可视化渲染,使用vue+element可以快速的构建出一套现代化的界面,某些情况下也可能会与原生app进行通信,如去除默认边框、自定义快捷命令等,所以渲染层常用的一个方法就是ipcRenderer,通过ipcRenderer可以与electron进行通信调用electron提供的一些原生api。

示例(关闭、放大、缩小)

这是vue定义的点击事件,通过发送不同的参数与electron的mian进行交互。

main.js负责监听通信并执行动作

示例(解决打包后无法复制粘贴的问题)

service为分为rutes、views、app.js三部分,rutes负责整个前端页面提供调用接口,app.js负责服务的启动和接口路由的注册,view内使用pug模板承载一些异常状态的访问页面。

示例(实现分环境打包接口)

这里需要注意一下,这个接口的实现是非常灵活的,需要根据你当前项目的编译文件进行配置,比如我的项目开发时使用gulp打包编译环境到dist,其编译命令分别为:

  • gulp build:Dev(联调环境)
  • gulp build:Test(测试环境)
  • gulp build:Slave(预发布环境)
  • gulp build:Prod(线上环境)

那么同理,配置好dist输出文件目录,收到请求后执行事先实现好的shell命令即可完成打包这一步,如果你不太了解环境编译打包这块内容,可以参考我之前的一篇文章"《武装你的小程序——开发流程指南》";

代码实现

build 打包app目录 build是app打包完成后的输出目录,这个文件可以存放你的项目图标,打包的时候electron会默认在这个目录下找图标,如果找不到就会使用electron默认图标。

使用electron遇到的问题

  • 官方强烈推荐使用yarn安装依赖,淘宝镜像安装的依赖会在打包的时候导致超级多的未知bug!!!比如我一不小心使用了cnpm安装了elemnent-ui最后打包导致无法解析该模块,只能删除node-modules重新使用yarn安装。
  • error:Cannot assign to read only property 'exports' of object '#<Object>' 在express项目里使用了model.exports方式导出模块,但webpack 2中不允许混用import和module.exports 解决办法:

1.解决办法就是统一改成ES6的方式编写即可. import {a} from './a'; export default a;

2.引入插件transform-es2015-modules-commonjs yarn add babel-plugin-transform-es2015-modules-commonjs 然后在 babelrc中配置 { "plugins": ["transform-es2015-modules-commonjs"] } 即可解决

  • 如果在electron中使用了child_process去开启一个子进程执行shell的话,像是gulp,npm这种在开发环境可以正常执行,但打包app后node执行的环境变量就会被更改,导致执行失败,可以将process.env.PATH手动更改为process.env.PATH+=':/usr/local/bin'即可。
  • 打包的app图标不是自己配置的图标?

脚手架的pacage.json有三个字段

你可以在这里配置你的项目图标。

项目展望

当前项目已经可以在公司内部的生产环境中使用,但与内部项目耦合严重,不够灵活,同时还有一些未知的问题和不足,我会在后续慢慢完善和优化,待解耦完成代码足够健壮的情况下我会选择将项目代码开源出来,下面列出我后续将要实现的功能。

  1. 项目管理器功能,可配置多个不同项目分别进行打包上传。
  2. 高度自定义的配置信息:gitlab的token、钉钉机器人的token、不同项目的打包执行脚本、不同的环境配置。
  3. 支持自定义分支列表而不是一次全部拉取出来,这对一些拥有超多的分支大型项目来说是不灵活的。
  4. 除了接口的shell脚本执行结果外打包后的验证功能,可以通过读取部分差异化文件进行比对打包结果。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券