写点什么

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

作者:若川
  • 2022 年 9 月 12 日
    浙江
  • 本文字数:6115 字

    阅读完需:约 20 分钟

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

1. 前言

大家好,我是若川为了能帮助到更多对源码感兴趣、想学会看源码、提升自己前端技术能力的同学。我倾力持续组织了一年每周大家一起学习200行左右的源码共读活动,感兴趣的可以点此了解。


想学源码,极力推荐关注我写的专栏(目前 3K+人关注)《学习源码整体架构系列》 包含jQueryunderscorelodashvuexsentryaxiosreduxkoavue-devtoolsvuex4koa-composevue 3.2 发布vue-thiscreate-vue玩具vite等 20 余篇源码文章。

2. 前情回顾

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


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


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


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


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


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


看完本文,你将学到:


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


先看看最终开发的效果。


支持的功能


支持的功能


显示帮助信息


功能展示


上传效果


上传效果

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

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


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


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


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

4. miniprogram-ci 官方文档

miniprogram-ci 文档

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


我组织的源码共读第30期读的就是这个插件,非常值得学习。@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 官网仓库


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 官网仓库

7.1 npm init release-it 原理

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


npm init


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-foonpm init @usr/foo -> npx @usr/create-foonpm init @usr -> npx @usr/create
复制代码


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


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


create-release-it


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' });


这行源码位置

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 解析命令行参数。


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 颜色输出。


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 hash    let 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.name let 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。关于 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 来实现单选或者多选的功能。以下只是关键代码。完整代码可以查看 mp-cli/src/utils/getConfig.js 文件


// 只是关键代码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-itgit checkout feature/release-it
复制代码


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


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


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

9. 总结

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


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


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




最后可以持续关注我 @若川。欢迎点此扫码与我交流,参加每周大家一起学习200行左右的源码共读活动,共同进步。


发布于: 刚刚阅读数: 4
用户头像

若川

关注

还未添加个人签名 2018.09.11 加入

https://lxchuan12.gitee.io

评论

发布
暂无评论
还在用开发者工具上传小程序? 快来试试 miniprogram-ci 提效摸鱼_JavaScript_若川_InfoQ写作社区