1. 前言

大家好,我是若川。持续组织了近一年的源码共读活动,感兴趣的可以 加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含包含jQueryunderscorelodashvuexsentryaxiosreduxkoavue-devtoolsvuex4koa-composevue 3.2 发布vue-thiscreate-vue玩具vite等20余篇源码文章。历史面试系列。另外:目前建有江西|湖南|湖北籍前端群,可加我微信进群。

2. 前情回顾

本文提到的工具已开源,可以直接克隆拿去用,也可以自行修改使用,https://github.com/lxchuan12/mp-cli.git,求个star^_^[1]

估计有很多开发小程序的同学,还在使用微信开发者工具上传小程序。如果你是,那么这篇文章非常适合你。如果不是,同样也很适合你。

早在 2021年08月,我写过一篇文章 Vue 3.2 发布了,那尤雨溪是怎么发布 Vue.js 的?

Vue 2.7 如何发布跟Vue 3.2这篇文章类似,所以就不赘述了。

vuejs发布的文件很多代码我们可以直接复制粘贴修改,优化我们自己发布的流程。比如写小程序,相对可能发布频繁,完全可以使用这套代码,配合miniprogram-ci[2],再加上一些自定义,加以优化。

于是今天我们来开发这样的脚手架工具。

看完本文,你将学到:

1. 如何利用 release-it 提升版本号,自动打 tag,生成 changelog 等
2. npm init 原理
3. 如何写一个脚手架工具- 如何解析 Nodejs 命令行参数 minimist- 如何选择单选、多选 enquirer(prompt, MultiSelect)- 等等

先看看最终开发的效果。

支持的功能

支持的功能

显示帮助信息

显示帮助信息

上传效果

上传效果

3. 关于为啥要开发这样的工具

关于小程序 ci 上传,再分享两篇文章。

基于 CI 实现微信小程序的持续构建[3]

小打卡小程序自动化构建及发布的工程化实践[4] 虽然文章里不是最新的 miniprogram-ci,但这篇场景写得比较全面。

接着,我们先来看看 miniprogram-ci 官方文档。

4. miniprogram-ci 官方文档

miniprogram-ci 文档[5]

4.1 上传

const ci = require('miniprogram-ci')
;(async () => {const project = new ci.Project({appid: 'wxsomeappid',type: 'miniProgram',projectPath: 'the/project/path',privateKeyPath: 'the/path/to/privatekey',ignores: ['node_modules/**/*'],})const uploadResult = await ci.upload({project,version: '1.1.1',desc: 'hello',setting: {es6: true,},onProgressUpdate: console.log,})console.log(uploadResult)
})()

4.2 预览

const ci = require('miniprogram-ci')
;(async () => {const project = new ci.Project({appid: 'wxsomeappid',type: 'miniProgram',projectPath: 'the/project/path',privateKeyPath: 'the/path/to/privatekey',ignores: ['node_modules/**/*'],})const previewResult = await ci.preview({project,desc: 'hello', // 此备注将显示在“小程序助手”开发版列表中setting: {es6: true,},qrcodeFormat: 'image',qrcodeOutputDest: '/path/to/qrcode/file/destination.jpg',onProgressUpdate: console.log,// pagePath: 'pages/index/index', // 预览页面// searchQuery: 'a=1&b=2',  // 预览参数 [注意!]这里的`&`字符在命令行中应写成转义字符`\&`})console.log(previewResult)
})()

5. Taro 小程序插件 @tarojs/plugin-mini-ci

如果使用 Taro 开发的小程序,可以直接使用。

具体如何使用参考文档,我在本文中就不赘述了。

小程序持续集成 @tarojs/plugin-mini-ci[6]

我组织的源码共读第30期[7]读的就是这个插件,非常值得学习。@tarojs/plugin-mini-ci 源码解读可以参考 @NewName 的源码文章

我体验下来的感觉有以下几点可以优化。

  • 不支持指定机器人

  • 不支持不打包时上传

  • 不支持官方提供的更多配置

  • 不支持选择多个小程序批量上传等等

如果有时间我可能给 TaroPR,当然不一定会被合并。

6. uni-app 好像没有提供类似的插件

uni-app 好像没有提供类似的插件。需要自己动手,丰衣足食。

7. release-it 自动提升版本、打 tag、生成 changelog 等

于是我们自己动手,丰衣足食,写一个工具解决上面提到的问题,支持 Taro 打包后的小程序和 uni-app 打包后的,还有原生小程序上传和预览

开发小工具之前,先介绍一些好用的工具。

据说很多小伙伴的项目,没有打 tag、没有版本的概念,没有生成 changelog,没有配置 eslintprettier,没有 commit 等规范。

这些其实不难,commit 规范一般简单做法是安装 npm i git-cz -D, 在package.json 中加入如下脚本。

{"scripts": {"commit": "git-cz"}
}

git 提交时使用 npm run commit 即可,其他就不赘述了。

release-it,自动提升版本号,自动打 tag,生成 changelog

release-it 官网仓库[8]

npm init release-it
# 选择 .release-it.json 用下面的配置,复制粘贴到 .release-it.json 中。
# 再安装 changelog 插件
npm i @release-it/conventional-changelog -D
{"github": {"release": false},"git": {"commitMessage": "release: v${version}"},"npm": {"publish": false},"hooks": {"after:bump": "echo 更新版本成功"},"plugins": {"@release-it/conventional-changelog": {"preset": "angular","infile": "CHANGELOG.md"}}
}

这样配置后,可以 npm run release 执行 release-it 版本。还支持 hooks 钩子,比如提升版本号后"after:bump": "echo 更新版本成功",更多功能可以查看release-it 官网仓库[9]

7.1 npm init release-it 原理

为啥 npm init 也可以直接初始化一个项目,带着疑问,我们翻看 npm 文档。

`npm init`[10]

npm init 用法:

npm init [--force|-f|--yes|-y|--scope]
npm init <@scope> (same as `npx <@scope>/create`)
npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)

npm init <initializer> 时转换成 npx 命令:

npm init foo -> npx create-foo
npm init @usr/foo -> npx @usr/create-foo
npm init @usr -> npx @usr/create

看完文档,我们也就理解了:

运行 npm init release-it => 相当于 npx create-release-it

create-release-it[11]

npm init release-it 原理其实就是 npx create-release-it选择一些配置,生成 .release-it.json 或者 package.jsonrelease-it 配置。

再写入命令release 配置到 package.json

{"scripts": {"release": "release-it"}
}

最后执行 npm install release-it --save-dev也就是源码里的 await execa('npm', ['install', 'release-it', '--save-dev'], { stdio: 'inherit' });

这行源码位置[12]

8. 小程序上传工具实现主流程

需要支持多选,那肯定得遍历数组。

// 代码只是关键代码,完整的可以查看 https://github.com/lxchuan12/mp-cli/blob/main/src/index.js
(async () => {for (const mpConfigItem of mpConfigList) {try {const res = await main({});}catch(err){console.log('执行失败', err);}}
})();

main 函数

const { green, bold } = require('kolorist');
const step = (msg) => console.log(bold(green(`[step] ${msg}`)));
async function main(options = {}) {const project = new ci.Project(lastProjectOptions);if (upload) {step('开始上传小程序...');const uploadResult = await ci.upload(lastUploadOptions);console.log('uploadResult', uploadResult);}if (preview) {step('开始生成预览二维码...');const previewResult = await ci.preview(lastPreviewOptions);console.log('previewResult', previewResult);}
}

8.1 添加功能支持指定参数

使用 minimist[13] 解析命令行参数。

const getParams = () => {const params = process.argv.slice(2);const paramsDefault = {default: {robot: 1,preview: false,upload: false,// 空跑,不执行dry: false,// 根据配置,单选还是多选来上传小程序useSelect: false,useMultiSelect: false,help: false,version: false,},alias: {u: 'upload',r: 'robot',v: 'version',d: 'dry',s: 'useSelect',m: 'useMultiSelect',p: 'preview',h: 'help',}};return require('minimist')(params, paramsDefault);
};module.exports = {getParams,
};

8.2 支持读取项目的 package.jsonversion,也支持读取自定义version

kolorist[14] 颜色输出。

const { red, bold } = require('kolorist');
const getVersion = () => {let version;try {version = require(`${packageJsonPath}/package.json`).version;} catch (e) {console.log(e);console.log(red(bold('未设置 version , 并且未设置 package.json 路径,无法读取 version',),),);}return version;
};module.exports = {getVersion,
};

8.3 版本描述 支持指定 git commit hash 和作者

git rev-parse --short HEAD 读取 git 仓库最近一次的 commit hash

parse-git-config 可以读取 .git/config 配置。

// const path = require('path');
const { execSync } = require('child_process');
const parseGitConfig = require('parse-git-config');
const getDesc = (projectPath, version) => {// 获取最新 git 记录 7位的 commit hashlet gitCommitHash = 'git commit hash 为空';try {gitCommitHash = execSync('git rev-parse --short HEAD', {cwd: projectPath,}).toString().trim();} catch (e) {console.warn('获取 git commit hash 失败');console.warn(e);}// 获取项目的git仓库的 user.namelet userName = '默认';try {const {user: { name = '默认' },} = parseGitConfig.sync({cwd: projectPath,path: '.git/config',});userName = name;} catch (e) {console.warn('获取 .git/config user.name 失败');console.warn(e);}const desc = `v${version} - ${gitCommitHash} - by@${userName}`;return desc;
};module.exports = getDesc;

8.4 读取配置 wx.config.js 配置(更推荐)

当前也支持读取 .env 配置。读取 .env 配置,可以采用 `dotenv`[15]。关于 dotenv的原理,可以看我之前写过的文章面试官:项目中常用的 .env 文件原理是什么?如何实现?

wx.config.js 可以配置更多东西而且更灵活。所以更推荐。

感兴趣的可以研究 vue-cli 是如何读取 vue.config.js 配置的。围绕工作相关的学习,往往收益更大。

// 读取 wx.config.js 配置
const loadWxconfig = (cwd) => {try {return require(path.join(cwd, 'wx.config.js'));} catch (e) {return {error: '未配置 wx.config.js 文件',};}
};const parseEnv = () => {const cwd = process.cwd();let parsed = {};let wxconfig = loadWxconfig(cwd);if (wxconfig.error) {let dotenvResult = require('dotenv').config({path: path.join(cwd, './.env'),});parsed = dotenvResult.parsed;if (dotenvResult.error) {throw error;}} else {parsed = wxconfig;}// 代码有省略
}

8.5 支持选择多个小程序

我们可以用 enquirer[16] 来实现单选或者多选的功能。以下只是关键代码。完整代码可以查看 mp-cli/src/utils/getConfig.js 文件[17]

// 只是关键代码
const { prompt, MultiSelect } = require('enquirer');
const configPathList = fs.readdirSync(configPath);
const configPathListJson = configPathList.map((el) => {return require(`${configPath}/${el}`);
});
const { name } = await prompt({type: 'select',name: 'name',message: '请选择一个小程序配置',choices: configPathListJson,
});
result = configPathListJson.filter((el) => el.name === name);
return result;

8.6 支持多个批量上传

// 只是关键代码
const { prompt, MultiSelect } = require('enquirer');
const configPathList = fs.readdirSync(configPath);
const configPathListJson = configPathList.map((el) => {return require(`${configPath}/${el}`);
});
const multiSelectPrompt = new MultiSelect({name: 'value',message: '可选择多个小程序配置',limit: 7,choices: configPathListJson,
});try {const answer = await multiSelectPrompt.run();console.log('Answer:', answer);result = configPathListJson.filter((el) =>answer.includes(el.name),);return result;
} catch (err) {console.log('您已经取消');console.log(err);process.exit(1);
}

后续可能接入 CI/CD、接入邮件提醒、接入钉钉、支持可视化操作等等

8.7 更多如何使用可以参考文档

# 克隆我写的 mp-cli 工具
git clone https://github.com/lxchuan12/mp-cli.git
# 克隆腾讯开源的电商小程序
git clone https://github.com/lxchuan12/tdesign-miniprogram-starter-retail.git
# 切到分支 feature/release-it
git checkout feature/release-it

可以克隆我的项目,到一个目录中,比如 projects 中。

再克隆我的另外一个小程序(腾讯开源的电商小程序),到同一个目录中。比如 projects 中。

按照微信小程序文档[18]配置小程序密钥等,这样就能上传和预览了。如果没有微信小程序,可以自行免费开通个人的微信小程序。

9. 总结

通过本文的学习,我们知道了以下知识。

1. 如何利用 release-it 提升版本号,自动打 tag,生成 changelog 等
2. npm init 原理
3. 如何写一个脚手架工具- 如何解析 Nodejs 命令行参数 minimist- 如何选择单选、多选 enquirer(prompt, MultiSelect)- 等等

我相信大家也能够自己动手实现公司类似要求的脚手架工具,减少发版时间,降本提效。

参考资料

[1]

本文提到的工具已开源,可以直接克隆拿去用,也可以自行修改使用,https://github.com/lxchuan12/mp-cli.git,求个star^_^: https://github.com/lxchuan12/mp-cli.git

[2]

miniprogram-ci: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html

[3]

基于 CI 实现微信小程序的持续构建: https://help.coding.net/docs/best-practices/ci/1minute/wechat-mini-program.html

[4]

小打卡小程序自动化构建及发布的工程化实践: https://www.yuque.com/jinxuanzheng/gvhmm5/uy4qu9#8yQ8M

[5]

miniprogram-ci 文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html

[6]

小程序持续集成 @tarojs/plugin-mini-ci: https://taro-docs.jd.com/taro/docs/plugin-mini-ci/

[7]

源码共读第30期: https://juejin.cn/post/7082662027143053342

[8]

release-it 官网仓库: https://github.com/release-it/release-it

[9]

release-it 官网仓库: https://github.com/release-it/release-it

[10]

npm init: https://docs.npmjs.com/cli/v6/commands/npm-init

[11]

create-release-it: https://github.com/release-it/create-release-it

[12]

这行源码位置: https://github.com/release-it/create-release-it/blob/master/index.js#L120

[13]

minimist: https://github.com/substack/minimist

[14]

kolorist: https://github.com/marvinhagemeister/kolorist

[15]

dotenv: https://github.com/motdotla/dotenv

[16]

enquirer: https://github.com/enquirer/enquirer

[17]

mp-cli/src/utils/getConfig.js 文件: https://github.com/lxchuan12/mp-cli/blob/main/src/utils/getConfig.js

[18]

微信小程序文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经坚持写了8年,点击查看年度总结。
同时,最近组织了源码共读活动,帮助4000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。

扫码加我微信 lxchuan12、拉你进源码共读

今日话题

目前建有江西|湖南|湖北 籍 前端群,想进群的可以加我微信 lxchuan12 进群。分享、收藏、点赞、在看我的文章就是对我最大的支持~

还在用开发者工具上传小程序? 快来试试 miniprogram-ci 提效摸鱼相关推荐

  1. 如何用微信web开发者工具测试调试并打包上传小程序

    厦门四六开科技给大家讲讲 如何用微信web开发者工具测试调试并打包上传小程序,其实还是很简单的,这个教程针对小白,大神请直接略过. 一.下载并安装软件(根据自己电脑实际情况选择版本安装) 如何用微信开 ...

  2. CLI 发行uni-app到微信小程序,如何不打开微信开发者工具去进行小程序发布?

    前言: 小程,赶紧把这个UI这里改一下,改完赶紧推个版本,等着测试:哎小程,这个需求客户需要这样改一下,你赶紧改一下推个版本客户等着看!!! 上面这段话相信做开发的同僚或多或少每天都在听,可是小程序的 ...

  3. 微信开发者工具开发微信小程序

    微信开发者工具开发微信小程序 1.下载工具 2.工具使用 3.增删改查 a:使用云开发数据库 以查询为例 b:调用本地springboot接口 以查询为例 1.下载工具 进入微信公众平台:微信公众平台 ...

  4. 安装微信开发者工具及创建小程序

    大纲:         一.官网:微信公众平台微信公众平台,给个人.企业和组织提供业务服务与用户管理能力的全新服务平台.https://mp.weixin.qq.com/ 开发者工具下载页面https ...

  5. 微信开发者工具上传时 包超出限制的问题

    记录一下微信开发者工具 包明明没有超过限制 但是上传的时候缺提示包超出了限制 但是看了一下本地代码大小并没有超出限制啊 我又把微信开发者工具关了 重新运行的时候才看到 原来运行模式下不压缩代码且含有s ...

  6. 微信官方开发者工具如何导入小程序源码demo

    本文原地址: http://www.php.cn/xiaochengxu-353507.html 最近有很多网友私信问我们网站上下载的那些小程序源码,怎么将它导入到 小程序开发者工具 中呢?因为问的人 ...

  7. 用微信开发者工具--打开微信小程序weui组件示例

    浏览器搜索 :https://github.com/Tencent/weui-wxss/ 1.下载为小程序设计的weui组件, 2.在开发者工具中打开dist目录,而不是整个目录, 在开发者工具中就可 ...

  8. 获取微信小程序码传递的参数 / 微信开发者工具模拟扫描小程序码调试

    本文主要介绍如何在微信开发者工具中,模拟微信扫描小程序码打开小程序的场景,进行调试. 二维码调试可以看这篇文章:微信开发者工具模拟扫描二维码调试 添加编译模式 添加一个咱们自定义的编译模式 输入模式名 ...

  9. mysql多图怎么同时上传,小程序如何同时上传多张图片?

    元素上bindtap方法:(选择图片) chooseImgHandler: function (e) { var that = this; that.count_img = count_img; // ...

最新文章

  1. 快速整理excel_3小时整理了33个excel动图技巧,能快速提高工作效率,收藏备用吧...
  2. SpringCloud-容错处理Hystrix熔断器
  3. 【追一科技校招】AI浪潮已来,你不可错过的澎湃风口!
  4. awk bc命令 linux_linux之awk命令(转载)
  5. eclipse ldt update resource
  6. phython在file同时写入两个_轻松支撑百万级数据点写入 京东智联云时序数据库HoraeDB架构解密...
  7. 武大94年暖男型博士入选华为“天才少年”计划,最高年薪201万
  8. python保存rtmp流_ffmpeg 推送、保存rtmp 流命令
  9. jquery-超好用的数据容器-data方法
  10. node文件服务器,nodejs一个简单的文件服务器的创建方法
  11. thinkphp5json对象转数组
  12. CF1299B Aerodynamic 题解
  13. 「公众号吸粉神级插件」实现网站下载文件需要公众号获取验证码
  14. 分别画出程序的软件流程图、NS图、PAD图; 程序
  15. 复旦961-软件工程笔记
  16. 如何下载安装VS2017下载 vs2017社区版
  17. 【Axure高保真原型】日期时间选择器
  18. Windows Server 2008 R2安装教程
  19. 【数据库】学生档案管理系统
  20. 转自一个CG大神的文章

热门文章

  1. 作为一个数学专业的学生,我是怎么看待编程的?
  2. 遇到问题--python-- pandas--常见问题积累
  3. JWT详细教程与使用
  4. 【操作系统】《计算机的心智:操作系统之哲学管理》读书笔记
  5. centos 日志文件
  6. ffmpeg ——下载与安装
  7. carla学习笔记(九)
  8. 工业数据治理:全解时序数据处理工具
  9. 计算机中的三类总线是什么,计算机中三总线是什么意思
  10. 服务器同步备份到本地文件,私有云服务器同步本地文件