草庐IT

Taro 小程序持续集成

杨成功 2023-03-28 原文

传统意义上的持续集成,是在 Web 端通过自动化的方式将项目打包并上传到服务器,这一过程需要 Git 参与。

持续集成的目的是为了免去手动打包、手动上传这一繁琐且容易出错的步骤,提高部署效率和部署的安全性。

而小程序部署方式与 Web 端不同,它不需要在本地打包,点击开发者工具中的上传按钮就会发布版本,版本可以在小程序管理后台看到。

当需要其他人测试时,将某个版本设置为体验版,然后分享体验版二维码即可。

为什么小程序也需要持续集成?

在实际开发中我们遇到了这样的问题:

每个前端人员上传后会产生一个新版本,不同的人上传后需要测试时,就要登录到管理后台切换体验版,在频繁测试场景下这个过程非常繁琐。

那么如何处理呢?解决方案就是将某个固定的版本号设置为体验版(如上图中的 v1.1.0),每个人都在这个版本号下上传,这样就不需要在后台切换版本了。

多人在一个版本号下上传,开发者工具办不到,此时需要集成 CI 的能力。

Taro 集成 CI

我司小程序是基于 Taro 开发的,Taro 提供了官方插件 @tarojs/plugin-mini-ci 来支持持续集成,使用也很方便。

我们以微信小程序为例,介绍接入持续集成的正确姿势。

注意:小程序持续集成至少需要 Taro v3.6.2 的版本,之前的版本会报错,请注意升级。

1、小程序后台生成上传密钥。

用代码的方式上传小程序,必然需要微信提供一个凭证,这个凭证就是上传密钥。在小程序后台找到【开发->开发管理->开发设置】,会看到“小程序代码上传”面板。点击“生成”按钮,根据步骤创建密钥并下载。

下载后将密钥命名为 private.key,然后将其保存在项目的 config 目录下。

2、安装插件并配置

在终端执行命令:

$ yarn add @tarojs/plugin-mini-ci -D
在配置文件 config/index.js 中引入插件并配置:

const ciPlugin = {
// 微信小程序
weapp: {
appid: 'xxxxx',
privateKeyPath: 'config/private.key',
},
// 版本号
version: '1.1.0',
// 版本发布描述
desc: 'CI自动发布',
}

const config = {
...
plugins: [
['@tarojs/plugin-mini-ci', ciPlugin]
],
}
配置中的 weapp 选项表示微信小程序配置,传入小程序的 appid,属性 privateKeyPath 表示下载后的上传密钥的路径(相对路径)。简单两步,配置就完成了。

3、添加上传命令

Taro 编译微信小程序时,通过命令 taro build --type weapp 来实现。如果要在编译之后自动上传代码,也就是触发我们上一步集成的 CI 插件,只需要添加一个 --upload 参数。

我们将编译并上传单独设置为一个命令,在 package.json 中设置如下:

{
"scripts": {
"upload": "taro build --type weapp --upload"
}
}
在终端执行 yarn run upload 命令,控制台开始执行打包,完成后会自动将代码上传并设置为体验版,同时在控制台中自动打印出体验版的二维码,如图:

现在我们直接截图分享二维码即可,再也不需要登录管理后台了。

@tarojs/plugin-mini-ci 原理解密

在 Taro 中使用该插件集成 CI 很简单,但如果你的小程序不是使用 Taro 开发,应该如何实现持续集成呢?下面我们解析下该插件的原理。

1、miniprogram-ci

小程序代码上传是微信支持的功能,微信团队发布了一个叫 miniprogram-ci 的 NPM 包,支持在 Node.js 中上传小程序代码。使用 @tarojs/plugin-mini-ci 插件时我们传入的配置,其实就是 miniprogram-ci 的配置。

在 Node.js 中,miniprogram-ci 的用法如下:

const ci = require('miniprogram-ci');
// ci项目实例
const project = new ci.Project({
appid: 'wxsomeappid',
type: 'miniProgram',
projectPath: 'the/project/path',
privateKeyPath: 'the/path/to/privatekey',
});
// 开始上传
const uploadResult = await ci.upload({
project,
version: '1.1.0',
desc: 'CI自动发布',
onProgressUpdate: console.log,
});
console.log(uploadResult);
上传代码之后,我们还需要将体验码生成并输出到控制台。

2、生成体验码

在小程序中扫描体验码,会打开当前小程序的体验版页面,其实这个页面是 H5 页面,地址如下:

https://open.weixin.qq.com/sns/getexpappinfo?appid=xxx#wechat-redirect
在链接中替换为自己的 appid,就可以将链接生成一个二维码输出到控制台,这里要借助另一个 NPM 包 ​​qrcode​​ 来实现。

首先安装 qrcode:

$ yarn add qrcode
然后编写一个将链接生成二维码,并输出到控制台的方法:

import * as QRCode from 'qrcode';
const printQrcode = async (url) => {
let terminalStr = await QRCode.toString(url, { type: 'terminal', small: true });
console.log(terminalStr);
};

// 生成二维码并输出到控制台
const url = 'https://open.weixin.qq.com/sns/getexpappinfo?appid=xxx#wechat-redirect';
printQrcode(url);
在代码上传完成后调用 printQrcode() 方法,即可打印出体验码。

总结

本篇介绍了如何在 Taro 中使用插件集成 CI,并解释了插件的原理帮助大家在非 Taro 环境下集成,整体实现并不困难。

但小程序有自己的场景,一般情况下 CI 只针对体验版。我们将上传代码封装为 upload 命令,你可以在本地执行,当然也可以在如 GitHub Action 的自动化流水线中执行。

有关Taro 小程序持续集成的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  3. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  4. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  5. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  6. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  7. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  8. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  9. ruby-on-rails - 我如何将 Hoptoad 与 DelayedJob 和 DaemonSpawn 集成? - 2

    我一直很高兴地使用DelayedJob习惯用法:foo.send_later(:bar)这会调用DelayedJob进程中对象foo的方法bar。我一直在使用DaemonSpawn在我的服务器上启动DelayedJob进程。但是...如果foo抛出异常,Hoptoad不会捕获它。这是任何这些包中的错误...还是我需要更改某些配置...或者我是否需要在DS或DJ中插入一些异常处理来调用Hoptoad通知程序?回应下面的第一条评论。classDelayedJobWorker 最佳答案 尝试monkeypatchingDelayed::W

  10. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

随机推荐