微信小程序shell脚本自动构建

3,933 阅读6分钟

一、前言

近期接触到微信小程序的项目,发现整个开发流程是这样的:程序猿A完成功能一的开发,通过开发工具生成二维码发送给测试同事进行测试,程序猿B完 成功能二的开发,也通过开发工具生成二维码发送给测试同事进行测试,过一会测试找到猿A功能一咋没实现,猿A找到 猿B:“我代码呢”,“同步了呀”,“我刚刚又提交了”... 

因为生成二维码和上传代码的过程都是由开发来手动控制,整个流程就显得不太规范,容易出现代码未同步,环境变量未替换等问题,因此着手调研小程序的自动构建方式。


二、原理

通过微信开发工具提供的命令行工具,可完成登录、预览、上传、自动化测试等操作。命令行工具所在位置为:

macOS: <安装路径>/Contents/Resources/app.nw/bin/cli

Windows: <安装路径>/cli.bat

1. 命令行启动工具:

-o, --open [projectpath]: 打开工具,如果不带 projectpath,只是打开工具。如果带 project path,则打开路径中的项目,每次执行都会自动编译刷新,并且自动打开模拟器和调试器。projectpath 不能是相对路径。项目路径中必须含正确格式的 project.config.json 且其中有 appid 和 projectname 字段。

示例:

# 打开工具

cli -o

# 打开路径 /Users/username/demo 下的项目

cli -o /Users/username/demo

2. 命令行登录

命令行提供两种登录方式:一是将登录二维码转成 base64 给用户,让用户自己集成到自己系统中使用;二是将二维码打印在命令行中。

-l, --login: 启动登录逻辑。

--login-qr-output [format[@path]]: 指定二维码输出形式,format 可选值包括 terminal(命令行输出), base64, image。如果有填 path,表示结果输出到指定路径的文件中。如果没填 path,表示将结果输出到命令行。不使用此选项或使用了但没有填 format 的话则默认为命令行打印。

示例:

# 登录,在终端中打印登录二维码

cli -l

# 登录,在终端中打印登录 base64 形式的二维码

cli -l --login-qr-output base64

# 登录,二维码转成 base64 并存到文件 /Users/username/code.txt

cli -l --login-qr-output base64@/Users/username/code.txt

3. 命令行提交预览

预览时必须处于登录状态,如果没有登录,会提示需先登录。预览的二维码可命令行打印也可以转成 base64。ES6 等项目配置从 project.config.json 读取。

-p, --preview <project_root>: 预览代码,project_root 指定项目根路径。

--preview-qr-output [format[@path]]: 指定二维码输出形式,语义同登录用的选项 --login-qr-output。

--preview-info-ouput <path>: 指定后,会将本次预览的额外信息以 json 格式输出至指定路径,如代码包大小、分包大小信息。

示例:

# 预览,在终端中打印登录二维码

cli -p /Users/username/demo

# 预览,二维码转成 base64 并存到文件 /Users/username/code.txt

cli -p /Users/username/demo --preview-qr-output base64@/Users/username/code.txt

# 预览,并将预览代码包大小等信息存入 /Users/username/info.json

cli -p /Users/username/demo --preview-info-output /Users/username/info.json

4. 命令行上传代码

上传代码时必须处于登录状态,如果没有登录,会提示需先登录。上传代码需要的信息包括项目根目录、版本号、以及可选的版本备注。

-u, --upload <version@project_root>: 上传代码,version 指定版本号,project_root 指定项目根路径。

--upload-desc <desc>: 上传代码时的备注。

--upload-info-ouput <path>: 指定后,会将本次上传的额外信息以 json 格式输出至指定路径,如代码包大小、分包大小信息。

示例:

# 上传路径 /Users/username/demo 下的项目,指定版本号为 1.0.0,版本备注为 initial release

cli -u 1.0.0@/Users/username/demo --upload-desc 'initial release'

# 上传并将代码包大小等信息存入 /Users/username/info.json

cli -u 1.0.0@/Users/username/demo --upload-desc 'initial release' --preview-info-output /Users/username/info.json

5. 支持自动化测试

-t, --test <project_root>: 提交自动化测试,project_root 指定项目根路径。

示例:

# 提交测试路径 /Users/username/demo 下的项目

cli -t /Users/username/demo


三、Shell脚本

首先我们通过控制台验证一下上述小程序工具提供的命令行,以cli -o 打开工具为例:


进入开发工具的目录下,执行cli -o 即可打开工具。验证可行后,我们将此命令写入shell脚本中,通过执行脚本控制工具的开启,操作很简单,只需要在开发工具的目录下新建一个test.sh文件,加入如下一句代码即可:

./cli -o

然后执行sh test.sh,悲剧随即发生...


什么鬼?!还能不能愉快地玩耍了[○・`Д´・ ○]

擦干眼泪,我们发现之所以控制台能执行命令,全是托开发工具的目录下的cli.bat文件的福,而我们shell脚本表示俺不知bat为何物...


好吧,既然cli.bat不能为我所用,那么我们就剖开它,看看它到底执行了啥操作:

@echo off

set CALLING_DIR=%CD%

cd /d %~dp0

.\node.exe .\cli.js %*

cd "%CALLING_DIR%"

以上就是cli.bat的代码,翻译成人话就是:先保存当前的路径,再打开开发工具目录路径,然后执行 .\node.exe .\cli.js + 命令 ,最后再恢复现场,打开之前保存的路径。功能不多,脾气挺大,我们将它翻译成shell脚本就是:

cd $1
./node.exe ./cli.js $2

输入的参数依次为:开发工具目录路径  执行的命令

忐忑地执行,然后愉快地发现成功了,啊哈哈哈哈,小样~



理论验证成功了,下面就开始华丽丽地写脚本了:

首先为方便调用,我们把刚刚验证的执行开发工具命令的代码包成一个方法,其中tool_path为开发工具的路径,输入的参数为命令符(如: -o):

#执行微信开发工具命令
cmd_tool()
{
   cd ${tool_path}
   ./node.exe ./cli.js $1
}


接下来我们来生成小程序调试二维码,很简单,只要调用 -p 命令即可,其中project_path为代码路径,生成的二维码图片会以base64的形式保存在代码路径下的develop_code.txt文件中,当然如果你想以日志的形式打印出二维码图像,直接执行 cmd_tool "-p ${project_path}" 即可:

#生成开发版二维码
develop_qr_code()
{
   echo "develop_qr_code"
   cmd_tool "-p ${project_path} --preview-qr-output base64@${project_path}/develop_code.txt"
}

(注:在线base64转图片 imgbase64.duoshitong.com ,转换前注意base64数据的前缀需为data:image/jpeg;base64,)


生成二维码前若开发工具未登录,则使用 -p 命令时会报错,此时我们需要先执行登录操作,生成登录二维码并扫描登录,与生成调试二维码相似,生成的登录二维码图片会以base64的形式保存在代码路径下的login_code.txt文件中:

#生成登录二维码
login_qr_code()
{
   echo "login_qr_code: Please scan login_qr_code"
   cmd_tool "-l --login-qr-output base64@${project_path}/login_code.txt" 
}


调试成功,我们可通过脚本将代码上传到微信小程序服务端,上传时需要的参数为版本号(version)和版本备注(version_desc),上传成功后即可在微信公众上获取小程序体验版二维码:

#上传代码
upload_code()
{
   echo "upload_code: version=${version}, version_desc=${version_desc}"
   if [ ! -n "${version}" ]; then
      echo "upload_code: Please input version"
   elif [ ! -n "${version_desc}" ];then
      echo "upload_code: Please input version desc"
   else
      cmd_tool "-u ${version}@${project_path} --upload-desc ${version_desc}"
      echo "upload_code: success"
   fi
}


至此,我们自动构建所需要的登录开发工具,生成调试二维码和上传代码的操作都一一实现了,将它们组合在一起就可以得到一个完整的构建脚本,脚本主要实现的功能时生成调试二维码和上传代码,并在需要登录的时候生成登录二维码,以下是完整的脚本代码:

#! /bin/sh
#小程序自动构建的Shell参数说明:编译类型 代码路径 开发工具路径 版本号(仅上传代码时需要) 版本备注(仅上传代码时需要)
#
# @author Zn
# @date 2018-9-11

build_type=$1
project_path=$2
tool_path=$3
version=$4
version_desc=$5

#异常退出
error_exit(){
  echo "error_exit: $1"
  exit 1
}

#执行微信开发工具命令
cmd_tool()
{
   cd ${tool_path}
   ./node.exe ./cli.js $1
}

#生成开发版二维码
develop_qr_code()
{
   echo "develop_qr_code"
   
   cmd_tool "-p ${project_path} --preview-qr-output base64@${project_path}/develop_code.txt"

   if [ ! -f "${project_path}/develop_code.txt" ]; then
      echo "develop_qr_code: error, need login"
      login_qr_code
      develop_qr_code
   else
      #添加二维码图片数据前缀
      sed -i "1i\data:image/jpeg;base64," ${project_path}/develop_code.txt
      echo "develop_qr_code: success"
   fi
}

#生成登录二维码
login_qr_code()
{
   echo "login_qr_code: Please scan login_qr_code"
   cmd_tool "-l --login-qr-output base64@${project_path}/login_code.txt" 
}

#上传代码
upload_code()
{
   echo "upload_code: version=${version}, version_desc=${version_desc}"
   if [ ! -n "${version}" ]; then
      echo "upload_code: Please input version"
   elif [ ! -n "${version_desc}" ];then
      echo "upload_code: Please input version desc"
   else
      login_qr_code
      cmd_tool "-u ${version}@${project_path} --upload-desc ${version_desc}"
      echo "upload_code: success"
   fi
}

#根据编译类型进行打包
echo "build_type = ${build_type}"
if [ "${build_type}" = "upload" ]; then
  upload_code
elif [ "${build_type}" = "debug" ]; then
  develop_qr_code
else
  error_exit "build type error: ${build_type}"
fi

#end


执行过程和结果:



        -----------------------------------  end  -----------------------------------


写在最后的彩蛋

最后讲一下在调试过程中遇到的一个问题:对于同一个小程序项目,开发工具会缓存项目的代码路径,若项目的代码路径发生变化,则在执行命令时会报错,无法生成二维码,要解决只能手动去清理开发工具的缓存。因此在同一台机器上,同一个小程序项目不能存在两份代码,这个在走集成构建的时候需要注意一下~


参考文档

developers.weixin.qq.com/miniprogram…

testerhome.com/topics/1491…