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

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)- 等等

先看看最终开发的效果。

支持的功能

33cb0bcf404bc50467af8c935ef4eebb.png
支持的功能

显示帮助信息

98cf3742259e942dfe11c77d2bc1f6ce.png
显示帮助信息

上传效果

257cc3602a8022f425d3496ca182d023.png
上传效果

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

524ffb3a29aa2645d5f5a2f303c51bed.gif

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

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

e40f79827e85d319b3d00457281dfa1e.jpeg

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

今日话题

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超级玛丽马里奥版下载_将超级马里奥赋予生命

超级玛丽马里奥版下载Have you ever seen a zoetrope? If today’s sophisticated computer animation is the latest evolution of the form, then the remarkable zoetrope is a crucial ancestor; the transitional form between the drawing and the animation.等皆你见过…

如何在繁重的工作中持续成长?

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外…

熊kong作品资源链接_Kong雀技术:向世界展示您的设计作品

熊kong作品资源链接The door opened and I entered the bedroom of an apartment I was looking to rent. No furniture or items inside, it was almost empty except for a frame in the wall. It was a photo of a peacock. As I stared at it, I could not shake one clear…

漫谈前端工程化基建和架构设计 | 留言送书

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。本文留言抽奖送书&#xff0c;具体规则看文末。透过工程基建&#xff0c;架构有迹可循。前…

设计模式 日志系统设计_模式:我们设计系统的故事

设计模式 日志系统设计Design Patterns are some of the most over-used concepts in design today. And we all know what happens when you have some ideas all over the place. We start repeating them like parrots and applying them to everything, therefore distorti…

前端好还是后端好,看看7年前端和后端怎么说

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外…

提升UI技能的5个步骤

element ui 步骤重点 (Top highlight)What to do when you know how to use the software and know the basics of designing interfaces? There are a few simple things that you can do to take your skills to the next level, and you don’t need to invest in expensiv…

空降进阿里的 P10 都是什么人

周末见了几个朋友&#xff0c;吃饭时聊到他们前老板郭东白&#xff08;阿白&#xff09;&#xff0c;对了&#xff0c;我朋友在速卖通&#xff0c;他说阿白是 14 年来的阿里&#xff0c;直接就空降进了他们部门&#xff0c;当上首席架构师&#xff0c;后来又升到了 CTO&#xf…

linux下练习 c++ 关联式容器multimap特性

/* multimap特性 key可以重复 不支持下标访问 */ #include<iostream> #include<string> #include "print.h" #include<map> using namespace std; typedef pair<int,string> pairmp; typedef multimap<string,double> MS;int main() …

一致性设计,而不是一致性

一致性设计重点 (Top highlight)If we ask any design system advocate what are the main reasons to build and maintain a design system, chances are ‘Consistency’ will come up as first or second in their list, together with the ‘A single source of truth’ po…

如何在 React 应用中使用 Hooks、Redux 等管理状态

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 点此扫码加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系…

长语音识别体验_如何为语音体验写作

长语音识别体验重点 (Top highlight)“Voice User Interface (VUI) Designer” is an increasingly prominent job title in the tech world. A VUI designer typically writes the conversation and designs the flow between a VUI — an invisible interface that communica…

分析了1011个程序员的裁员情况后得出的启示

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 点此扫码加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系…

定义设计系统

System is “the whole creation, the universe,” from Late Latin systema “an arrangement, system,” from Greek systema “organized whole, a whole compounded of parts”.系统是晚期拉丁语系统的“整体创造物&#xff0c;宇宙”&#xff0c;是希腊语系统的“一种安排…

2w行代码、200个实战项目,助你修炼5大编程基本功。【送书《设计模式之美》】...

大家好&#xff0c;我是若川。之前送了很多书&#xff0c;现在又和异步图书合作再次争取了几本书&#xff0c;具体送书规则看文末。所谓练武不练功&#xff0c;到老一场空&#xff0c;以技术为驱动的程序员同样如此。面向对象编程范式、设计原则、代码规范、重构技巧和设计模式…

C++第10周项目2扩展之2参考——迭代求和

课程首页地址&#xff1a;http://blog.csdn.net/sxhelijian/article/details/7910565【项目2扩展之2&#xff08;选做&#xff09;】计算下面的式子&#xff0c;不能使用求幂函数pow()式一&#xff1a;#include <iostream> using namespace std; int main( ) { int i,m1;…

swift自行车品牌介绍_品牌101:简介

swift自行车品牌介绍Sometimes when I’m around designer friends and there’s a lull in the conversation one of us will blurt out, “What is branding, anyway?” Then we shrug our shoulders and chuckle, knowing that the answer is far too complex to sum up in…

flutter 透明度动画_Flutter中的动画填充+不透明度动画✨

flutter 透明度动画Flutter SDK provides us with many widgets which help us in animating elements on screen easily by implicitly managing the animations i.e. we need not worry about creating and managing intances of AnimationController during the lifecycle o…

阿里 P10 是怎样的存在?

谈起中国顶尖的程序员&#xff0c;很多人首先会想到之前的雷军、张小龙&#xff0c;还有现在的多隆、行癫、道哥等人&#xff0c;但今天我想聊一聊的这位大神&#xff0c;他的技术成就也同样令人瞩目。19 年获得国家技术发明二等奖、20 年获得国家计算机协会颁发的“ CCF 杰出工…

vba交付图表设计_您是在为交付目的而“设计”吗?

vba交付图表设计重点 (Top highlight)It’s a regular Monday morning. All the design team is organizing the tasks for the ongoing week and reviewing requirements and deadlines for the various projects at the studio or company you work at. Suddenly, among the …