前言
手动公布小程序效率低还容易出错,本文就思考如何用Jenkins来公布taro小程序。
手动打包小程序的问题
- 频繁发版 + 发版流程琐碎 + 可能存在的多个小程序,效率低
- 打包时常常固定一个人或者一台机器打包上传,不灵便
- 手动打包可能选错接口环境,导致线上问题
Jenkins打包益处
- 固定代码分支以及环境,打包过程由jenkins承当。效率高,缩小环境谬误的危险
- 所有人都能够自在打包
以上需要,整顿成一个demo我的项目了,基于Taro 3.x
taro小程序打包示例地址
Jenkins如何公布小程序
微信小程序ci能力
开发者可不关上小程序开发者工具,独立应用 miniprogram-ci 进行小程序代码的上传、预览等操作
微信小程序ci官网文档
密钥及 IP 白名单配置
应用 miniprogram-ci 前应拜访"微信公众平台-开发-开发设置"后下载代码上传密钥,并配置 IP 白名单 开发者可抉择关上 IP 白名单,关上后只有白名单中的 IP 能力调用相干接口。
通过小程序管理员扫码,就能够取得上传密钥。IP白名单能够本人设置,限度指定IP地址操作。
我公司因为jenkins自身就做了内网拜访限度,这里就没有反复限度了。
密钥的寄存
个别下载的密钥,是放到我的项目根目录当中。思考到密钥寄存在我的项目中不太平安,就让运维在jenkins打包阶段,再注入到我的项目中。
应用Taro框架集成的ci公布
个别微信原生小程序间接应用miniprogram-ci的能力即可。因为我的项目应用了taro框架,这里就以taro插件来做为例子。taro兼容了各小程序平台ci(继续集成)的能力。
yarn add @tarojs/plugin-mini-ci -D
次要原理:通过小程序密钥进行身份鉴权。ci就具备上传或者预览小程序的权限
小程序继续集成 | Taro 文档
我的项目中进行ci配置
参数 | 类型 | 阐明 | |
---|---|---|---|
appid | string | 小程序我的项目的 appid | |
privateKeyPath | string | 私钥文件在我的项目中的相对路径,在获取我的项目属性和上传时用于鉴权应用 | |
robot | number | 指定应用哪一个 ci 机器人,可选值:1 ~ 30(选填, 3.6.0 版本开始反对) | |
desc | string | 形容 | |
version | string | 版本 |
下面都是自定义的,个别跟着具体打包脚本来自定义的。如果想要全局自定义version或者desc,能够在package.json下配置taroConfig参数
// package.json{ "taroConfig": { "version": "1.0.0" },}
上面是我的项目中配置ci的过程,通过CIPluginFn配置密钥以及具体的参数
// config/index.jsconst { robot = 1, desc } = argvconst CIPluginFn = { weapp: { appid: 'xxxx', privateKeyPath: 'private.xxxx.key', // 配置密钥的门路 robot, }, desc,}const config = { plugins: [['@tarojs/plugin-mini-ci', CIPluginFn]],}
自定义打包命令
这里自定义了test以及prod两个环境,test测试环境通过--env指定为development,prod默认为线上production
// package.json{ "scripts": { "build:weapp:test": "npm run build:weapp -- --env development", "build:weapp": "taro build --type weapp", "dev:weapp": "npm run build:weapp -- --watch", "release:weapp:test": "npm run build:weapp:test -- --upload --robot=1 --desc='test环境'", "release:weapp:prod": "npm run build:weapp -- --upload --robot=2 --desc='prod环境'" },}
jenkins配置
jenkins是自动化打包我的项目的工具。平时咱们须要应用微信开发工具,手动装置依赖,并执行打包、上传的动作。当初把这些动作配置到jenkins的流水线当中,以实现主动打包上传。
服务器配置jenkins教程能够自行查阅。
重点留神下java版本与jenkins的版本,版本不匹配会导致很多谬误。
新建工作
装置完Jenkins就能够创立一个工作,来正式打包我的项目了
抉择工作模版
jenkins工作配置:
- 拉取我的项目代码
- 确定我的项目分支
- 执行自定义的打包命令
配置好工作后,点击Build Now
进行打包
打包后果如下:
上图打包过程中生成的二维码无奈扫描,可扫的体验二维码寄存在dist文件夹下的upload.png。
后续可本人优化,把生成的二维码发送到钉钉等。
小程序后盾上传后果
下面就实现了就enkins配置的流程,但还有如下几个问题须要解决。
- [ ] 1. API环境变量如何配置
- [ ] 2. 测试环境反对环境的切换。不便测试人员在测试接口或者线上接口切换
- [ ] 3. 体验码确定。毕竟同时只能存在一个体验码
1. 环境变量配置以及打包命令配置
环境变量env配置
taro默认的打包命令是build:weapp,其对应的NODE_ENV为prodcution。而咱们想要jenkins打包时也能呈现test环境或者其余环境的变量,能够在script脚本中通过--env来指定环境
在tao-cli源码中提供了env的注入形式
能够看出次要注入了env变量,process.env.NODE_ENV就将会采纳。
另外也能够了解咱们退出了—watch后,其会将process.env.NODE_ENV置为development的过程。
// taro-cli/src/cli.tsif (command) { .... // 设置环境变量 process.env.NODE_ENV ||= args.env if (process.env.NODE_ENV === 'undefined' && (command === 'build' || command === 'inspect')) { process.env.NODE_ENV = (args.watch ? 'development' : 'production') } ...}
我的项目中指定--env变量,比方指定了--env为development
"build:weapp:test": "npm run build:weapp -- --env development"
在config目录中,process.env.NODE_ENV的值就是咱们指定的--env值。依据process.env.NODE_ENV就能够制订不同的脚本了,比方默认的dev,prod,当然这里也能够减少为pre等脚本。
// config/dev.jsmodule.exports = { env: { NODE_ENV: '"development"', },}//config/prod.jsmodule.exports = { env: { NODE_ENV: '"production"', },}//config/index.jsmodule.exports = function (merge) { if (process.env.NODE_ENV === 'development') { return merge({}, config, require('./dev')) } return merge({}, config, require('./prod'))}
API环境变量确定
下面咱们配置好了jenkins打包,上面就须要确定接口具体的环境变量了。因为小程序比拟非凡,还须要手动提审小程序,还可能有测试环境切换接口环境的需要,因此须要确定下环境变量的优先级。当然如果没有兜底或者切换的需要,间接在config/dev.js或者prod.js下的env中配置接口地址即可。
环境变量env的优先级
为了防止线上环境呈现测试接口,这里做了兜底的策略:只有是小程序release环境则肯定是线上代码。另外为了反对测试环境切换环境,须要在本地进行env缓存。最初就是webpack注入的环境变量了process.env.NODE_ENV。
环境变量的优先级:
- 保底环境: 小程序release环境或者jenkins-线上环境
- 缓存storage存在的变量env:目标是反对测试环境切换环境
- Webpack注入的process.env.NODE_ENV变量:次要由Jenkins决定
具体的实现
实现优先级
getCurrentEnv函数的次要作用就是依据优先级获取以后的env变量
// utils/env.tsimport Taro from '@tarojs/taro'/** 获取以后的环境变量 */export const getCurrentEnv = (env: string | undefined) => { // 本地缓存的env const cacheEnv = Taro.getStorageSync(STORAGE_ENV_KEY) // 小程序release环境或者线上打包地址,默认都是线上地址 if (isWeappRelease() || isProdEnv()) { return EEnvType.prod } // 存在缓存env,则采纳 if (cacheEnv && [EEnvType.dev, EEnvType.prod].includes(cacheEnv)) { return cacheEnv } // webpack注入的环境变量 return env}
依据确定的env来确定接口地址
通过getCurrentEnv获取了以后的环境变量env,就能拿到以后申请的域名地址API_CURRENT_HOST,此处间接将接口地址以枚举的模式列出来了。
// configs/env.tsimport { getCurrentEnv, EEnvType } from '~/utils/env'/** api域名:理论应用替换成本人我的项目对应的域名 */export const API_HOST = { [EEnvType.dev]: 'test', [EEnvType.prod]: 'prod',}/** 以后的环境变量 */export const currentEnv = getCurrentEnv(process.env.NODE_ENV)/** API 以后申请域名 */export const API_CURRENT_HOST = API_HOST[currentEnv]
测试环境反对环境切换
切换环境组件EnvPopup
通过抉择控件切换环境变量,因为咱们的接口API_CURRENT_HOST是在编译阶段就确定了,这里在storage中切换env值并不会让接口变更,思考到切换只是测试低频的需要,因此就简略解决为手动重启小程序的形式。
当然如果不想要这样做,能够将申请域名存到内存当中,比方小程序全局变量Taro.getApp()中,以实现在运行时切换的需要。
export const EnvPopup: React.FC<{}> = () => { const [visible, setVisible] = useState(false) const listData = [ [ { value: EEnvType.dev, text: '开发环境' }, { value: EEnvType.prod, text: '正式环境' }, ], ] const confirmPicker = (values: (string | number)[]) => { Taro.setStorageSync(STORAGE_ENV_KEY, values[0]) Taro.showToast({ title: '请点击右上角三个点,抉择从新进入小程序后失效', icon: 'none', }) } return ( <> <View className={styles.btn} onClick={() => { setVisible(true) }} > 切 </View> </> )}
小程序体验码
小程序体验码是单例的,同一时间只会存在一个实例。也就是他人将体验码切走,扫旧的二维码也是指向最新的版本。
因为咱们外部约定了test环境为ci机器人1,prod线上环境为ci机器人2。为了固定体验码,提供了以下倡议
体验码切换约定
- 体验码:平时稳固在ci机器人1
- 提审:以机器人2提审,但体验码不变
- 线上测试回归:
- 单需要时,间接切到线上体验码:体验码能够先切到ci机器人2,之后切回机器人1
测试须要同时测试不同环境,能够思考提供开发版:
能够提供本地开发版,本地先执行npm run build:weapp
打包线上包,而后小程序工具预览。因为预览码只有25分钟的有效期,能够给测试人员加开发者权限,在小程序:小程序助手 下能查看到了提交的开发版,这个是没有时效的。这一步能够本人在scripts中退出
"build:weapp:preview": "taro build --type weapp --preview"
总结
以上就是jenkins打包taro小程序的过程了,具体过程能够查看demo,有任何问题欢送留言