跳到主要内容

Taro v3.6 Reach 正式发布

· 阅读需 24 分钟
Flame
大喵
robin
SHUAI XUE
zhiqingchen
JJ
TJ

两个月前,我们发布了 Taro v3.6 的 canary 版本,在技术委员会和社区范围内提供跨端路由库、跨框架组件等主要能力和重要修复的测试,并发起社区投票正式确定了当前版本的代号 —— Reach。

taro-3.6.jpg

日前 Taro v3.6 正式版本已经发布,下文将围绕 3.6 版本内的跨端、平台能力支持等多个方面展开,快速了解在 v3.6 中各个重要特性。

一、跨端能力支持

支持各类跨端能力,抹平多端研发之间的体验差异,是 Taro 一直以来尝试去实现的,基于 Taro 3 适配多端前端 UI 框架的逻辑,通过在小程序端模拟实现框架所需的 BOM / DOM API 就能达成对于各类跨端能力的适配。

1. 支持路由库

在 Web BOM 中,History & Location 对象是重要组成部分,它们是实现前端路由的关键。Taro 为支持前端路由库的使用,在运行时中引入了 histroy location 对象的实现,同时尽可能与 Web 端规范对齐。通过在 window 对象上访问到 historylocation 对象,并支持监听 hashchangepopstate 事件,为跨端使用路由库提供基础。

// 统称: 页面路由状态
window.history
window.location

// 支持监听事件
window.addEventListener('hashchange', () => {})
window.addEventListener('popstate', () => {})

小程序天然支持多页面(pages 数组配置),因此 Taro 并非以整个应用为一个路由系统,而是顺应小程序规范以页面维度进行路由管理。每当切换页面时,会将当前页面的页面路由状态缓存。跳转至新页面后会重新创建页面路由状态,并挂载在 window 对象上。当返回上一级页面时,会将上一级页面的页面路由状态重新挂载到 window 对象中。

至此,可以在小程序中使用成熟的前端路由库了,包括 react-routervue-router。在路由库中,诸如 <Link> 组件内部会动态生成 <a> 标签,因此需要引入 @tarojs/plugin-html 插件以支持在 Taro 中使用 html 标签开发组件。

{
"plugins": ["@tarojs/plugin-html"]
}

在 Taro 编译过程中,当 DOM 序列化数据的 nn 字段为 HTML 标签时,标签会映射为对应的小程序组件名称。由于无法提前预知动态标签,因此需要应用显式告知可能会使用到的动态标签。例如在应用中塞入一个无样式的标签名即可:

<View>
<a></a>
</View>

更多细节可以查看 官方文档,也可以查看官方提供的 DEMO 获知更多用法。

2. 支持网络请求库

与适配各路由库类似,通过对运行时补充就能支持绝大多数的网络请求库,所有请求库在底层都是通过使用 XMLHttpRequestFetch 提供能力支持的,而请求库大多都兼容 XMLHttpRequest 对象,也即是在提供 XMLHttpRequest 对象实现的基础上,就能支持绝大多数的第三方库。

支持这些成熟的网络请求库(例如 axios 等)就能为开发者在跨端研发场景下,提供更好的研发体验。通过引入 @tarojs/plugin-http 插件,为小程序环境提供网络请求库所需的运行时环境支持。

{
"plugins": ["@tarojs/plugin-http"]
}

注意:当前 @tarojs/runtime 在小程序环境中缺少BlobFormDataFile对象,这在网络请求库的文件上传特性中是必须的,故暂不支持。

在支持网络请求库的同时,考虑到部分用户,特别是 web 转小程序的项目中依赖 cookie 实现鉴权,@tarojs/plugin-http 插件模拟实现了 document.cookie api 以及通过 http 响应头 Set-Cookie 来设置客户端 cookie 值 ,行为和 web 中保持一致。 此功能默认设置为关闭,需要的可通过 enableCookie 配置开启。

参数名类型默认值说明
enableCookieBooleanfalse支持 document.cookie 、 通过后端返回 Set-Cookie 响应头来设置 cookie
disabledFormDataBooleantrue是否禁用 FormData 全局对象
disabledBlobBooleantrue是否禁用 Blob 全局对象

在 @tarojs/plugin-http 插件中,以 axios 作为基准库完成测试,如果在使用其他请求库时遇到适配问题,可在社区或通过 issues 反馈相关信息。

二、平台能力支持

拓展更多端平台,适配支持各端能力与特性,是跨端解决方案不断发展的重要组成部分之一。

1. 支持鸿蒙端平台插件

在 Taro 与 OpenHarmony 建立官方合作关系,并受邀成立 CrossPlatformUI Sig(跨平台前端框架兴趣小组)后,让 Taro 支持支配鸿蒙就一直在议程上,鸿蒙的方舟开发框架提供类 Web 范式编程,支持使用 JS 开发 UI 层,其语法与小程序相接近,可以沿用 Taro 现有的架构适配鸿蒙。

taro-harmony

持续关注 Taro 的开发者可能还记得,在 v3.5-canary 版本时,我们曾推出支持 Taro 应用适配到鸿蒙平台的插件,但最终没有合入 v3.5 版本主干并顺势推出该能力。

@tarojs/plugin-platform-harmony 端平台插件经过一段时间的打磨,相关能力与特性也在社区推进下持续优化,框架编译的项目在鸿蒙开发板上得到进一步验证,同时在 Taro v3.5 新增的 @tarojs/webpack5-runner 编译内核也能够为鸿蒙项目编译提供支持,终于我们在 v3.6 中再次为社区开发者提供了适配鸿蒙的端平台插件。

// config/index.js

config = {
// 配置使用插件
plugins: ['@tarojs/plugin-platform-harmony'],
// harmony 相关配置
harmony: {
// 【必填】鸿蒙应用的绝对路径
projectPath: path.resolve(process.cwd(), '../MyApplication'),
// 【可选】HAP 的名称,默认为 'entry'
hapName: 'entry',
// 【可选】JS FA 的名称,默认为 'default'
jsFAName: 'default'
}
}

具体使用方法可查看官方文档,需要注意鸿蒙插件不在 Taro 项目内维护,所以并不会每次发布同版本号版本,直接使用 minor 与 Taro 版本号相同的版本即可。

特别感谢以下同学为鸿蒙适配作出的贡献:

@AdvancedCat@jiaozitang@huozhongyi123@troy-sxj@JSZabc@crazyonebyone@evernoteHW@soulhat@xueshuai@LuMeiling

2. React Native 能力

为了让整体开发体验跟 RN 更加一致,减少开发者的理解成本。我们对 @tarojs/rn-runner 的代码进行了重构。将 Taro RN 需要的所有编译逻辑,都封装到了 metro 配置中,与 RN 项目集成会更加灵活。

新版本在项目根目录下会创建入口文件 index.js 和配置文件 metro.config.js。如项目本身有这两个文件,则不会生成,需要参考模板进行添加或合并。另外 Taro RN 的相关配置,集中在 resolver 和 transformer 中,可根据相关源码自行覆盖调整。

React Native 0.70 版本已于 2022-9-5 正式发布,在 0.70 版本中 Hermes 已成为默认的 JS 引擎,

v3.6 版本将与 RN 默认配置保持一致,如不需要可自行关闭。Hermes 也带来了 RN 性能的较大提升,特别是启动场景,详细内容参考官方文章

Hermes

Taro 将与 RN 社区保持同步,将默认的 RN 版本设置为 0.70。相关依赖也已同步至最新版本,仍然可使用 yarn upgradePeerdeps 进行更新。@react-native-community/clipboard@react-native-community/cameraroll 已被弃用,旧版本升级后需要删除。

注意:升级后将不再支持 iOS 12,详细内容请参考 discussions。同时 Taro Playground 作为 RN 端的调试工具及跨端 Demo 同步更新至 v3.6。

3. Web 端能力

通过在社区中收集的相关问题反馈,Taro Web 各类特性也一直在不断推进,让开发者在多端研发的体验能够尽可能达成一致。面对各类自定义 Web 端能力的需求,虽然有很多方案可以提供组件、API 等能力的补充,但类似小程序端平台插件这样的能力在 Web 端中并没有得到支持。

在 3.6 版本中,我们将 Web 端各类定制化的能力从 runner 中转移到 @tarojs/plugin-platform-h5 插件中提供,譬如通过配置 useHtmlComponents 模式替换使用的组件库;注册 Web Components 组件库,配置各前端 UI 框架组件适配器;移除不必要的 API 等等特性。

class H5 extends TaroPlatformWeb {
// ...
}

export default (ctx) => {
ctx.registerPlatform({
name: 'h5',
useConfigName: 'h5',
async fn({ config }) {
const program = new H5(ctx, config)
await program.start()
},
})
}

和小程序端一样,借助于插件或 TaroPlatformWeb 基类,开发者可以很容易横向或纵向拓展 Web 端的各项能力,详情可参考文档

Web 端也一直在补充各类开发者常用的组件与 API 抹平与小程序端的差异。在 v3.6 版本中新增生命周期、WXML 相关的 API 支持若干,例如:createIntersectionObservercreateMediaQueryObserver 等,同时新增 movable-areamovable-view 等组件支持。

在社区开发者交流时,我们也发现了部分研发场景下需要监听各 API、组件不支持事件,相比于支持 canIUse 方法在跨端转换场景中能够更有效定位问题,所以通过支持 __taroNotSupport 事件满足相关需求,可以参考以下示例使用。

interface IOption {
name: string // 不支持的组件或 API 名称
type: 'method' | 'component' // 'method': API; 'component': 组件
category: 'permanently' | 'temporarily' | 'weixin_corp' // 'weixin_corp': 仅在微信公众号 JS-SDK 环境下支持
args?: any[] // API 传入参数
instance?: unknown // 组件实例
}
Taro.eventCenter.on('__taroNotSupport', (option: IOption) => {
console.warn('调用不支持的 API 或组件', option)
})

三、跨框架组件库

借助于 stencil,Taro 3 得以通过 Web Components 实现一套跨框架组件库,通过适配器将 Taro 的组件库提供给各个前端 UI 框架使用,开发者也可以基于这些封装上层组件,提供更多有趣的能力。

1. Web 端适配器

出于降低开发者维护门槛,与 stencil 组件库打包流程更好兼容等多方面考虑,在 3.6 版本中我们在升级 stencil 依赖版本的同时,通过官方提供的  ds-output-target 工具替换了原有的自定义适配器。

该版本适配器更好的抹平各个框架组件使用差异,补齐过往版本迭代过程中部分特性兼容性的缺失问题,为开发者提供更好的体验。在 3.6 中依旧保留过往版本各框架适配器,可以参考以下示例通过配置别名替换组件库适配器(不建议使用,后续不会维护旧版适配器,可能无法得到新的组件或特性支持)。

// config/index.js

const config = {
h5: {
webpackChain(chain) {
chain.resolve.alias.set(
// 当前版本适配层地址 @tarojs/components/dist/[framework]
'@tarojs/components/dist/react',
// 旧版本适配层地址 @tarojs/components/dist/[framework]/component-lib
'@tarojs/components/dist/react/component-lib'
)
},
},
}

2. 虚拟列表

作为从 Taro 3 开始支持的上层组件,虚拟列表应当是很多开发者都熟悉的特性,在过往版本中也有过数次升级,支持包括 unlimitedSize、relative 定位模式等特性,在 v3.6 版本中我们再次对虚拟列表做出了调整,将其从 @tarojs/components 包中抽离到 @tarojs/components-advanced 中维护(4.x 版本之前开发者依旧可以通过 @tarojs/components/virtual-list 引用虚拟列表组件),也欢迎大家一同参与上层组件库的维护与共建,沉淀更多跨端可用的能力。

https://img20.360buyimg.com/ling/jfs/t1/125645/6/13305/50138/5f6aaaa4E2f20eba7/d70a2d2da2d68de1.jpg

在新版本中,虚拟列表支持在选择 preact、vue3 框架构建的项目中使用,同时在使用各个前端 UI 框架的项目中都支持使用选择 absolute********relative ********不同定位方式,unlimitedSize 模式与传入 itemSize 函数等特性也得到支持。

以 Vue 为例,我们需要在入口文件声明使用:

// app.js 入口文件
import Vue from 'vue'
import registerVirtualList from '@tarojs/components-advanced/dist/components/virtual-list'
// Note: 使用以下路径导出插件可以在 vue 中获得更好的类型支持
// import registerVirtualList from '@tarojs/components-advanced/dist/components/virtual-list/vue'

Vue.use(registerVirtualList)

一个最简单的长列表组件会像这样,virtual-list  的 5 个属性都是必填项:

<! –– row.vue 单项组件 ––>
<template>
<view :id="id" :class="index % 2 ? 'ListItemOdd' : 'ListItemEven'"> Row {{ index }} : {{ data[index] }} </view>
</template>

<script>
export default {
props: ['id', 'index', 'data'],
}
</script>

<! –– page.vue 页面组件 ––>
<template>
<virtual-list
wclass="List"
:height="500"
:item-data="list"
:item-count="list.length"
:item-size="100"
:item="Row"
width="100%"
>
<! –– Vue 中支持列表首尾使用的插槽,对应 React 中的 renderTop、renderBottom 参数 ––>
<template v-slot:top>
<view>top</view>
</template>
<template v-slot:bottom>
<view>bottom</view>
</template>
</virtual-list>
</template>

<script>
import { markRaw } from 'vue'
import Row from './row.vue'

function buildData(offset = 0) {
return Array(100)
.fill(0)
.map((_, i) => i + offset)
}

export default {
data() {
return {
Row: markRaw(Row),
list: buildData(0),
}
},
}
</script>

需要注意的是,为抹平多框架参数差异便于维护,旧版本中部分命名会统一修改,比如在 React 版本中通过 children 传入的子节点组件改为 item;Vue 中的 wclass、wstyle 这类写法也不再支持。

在新版本中,根据需求和研发场景合理设置 itemSizeoverscanCountplaceholderCount 等参数优化长列表,可以获得比旧版本更加顺滑的体验,更多详情可以参考官方文档

四、研发生态

1. 小程序持续集成 CI

去年 Taro 提供小程序持续集成插件 @tarojs/plugin-mini-ci ,帮助开发者提供更好的研发体验,经过一年的项目沉淀和反馈,在本次版本重构了去年的所有代码,并提供了更优秀体验和灵活的配置。

  • 本次新增特性支持独立的 openpreviewupload 命令,操作自定义目录适用于将 taro 作为项目一部分(混合开发)的开发场景;
  • 同步更新各个小程序端的 CI API 变更(阿里系、抖音小程序变化最大)
  • 新增钉钉小程序 CI 集成;
  • 新增京东小程序 CI 集成;
  • 统一所有平台 CI 构建后的输出数据,并将数据传递给新增的onPreviewCompleteonUploadComplete两个钩子用户可以编写新的插件,基于这个钩子实现 飞书、钉钉 的 CI 推送功能等等。

以下为当前各平台支持的功能情况表:

平台/功能自动打开 IDE输出预览二维码输出体验二维码
weapp
qywx
alipay
dd
swan
jd

ps: 该插件在 taro3.6.0 版本以下亦可支持单独使用,插件版本号无需保持与其他包同步。

更多详情可以参考官方文档,同时要特别感谢 @bigMeow 为 CI 自动化脚本做出的贡献~

2. PostCSS 版本升级

在 Taro 项目持续迭代的过程中,部分依赖稳定没有实时跟进各个社区内的特性与优化,并升级相关依赖,PostCSS 就是其中之一。如果开发者想要通过新版本的特性来优化构建流程与最终产物,相对会很困难且可能会存在一定问题阻塞。

为此在 3.6 canary 通过梳理项目内相关插件与依赖,对 PostcCSS 版本进行梳理并升级,升级后版本为 v8.4.18。本次升级主要包含以下内容:

  1. 对 Taro 内部的 PostCSS 插件使用 PostCSS 8 版本 API 进行改写,降低代码量同时减少插件对 CSS 扫描次数进而提高构建速度;
  2. 使用 peerDependencies 管理 postCSS 依赖,降低用户的 node_modules 体积和复杂度;
  3. 对 Taro 全量模板的 PostCSS 版本同步进行更新,方便开发者对新特性的使用。

特别感谢 @xueshuai 为相关工作做出的贡献,希望开发者可以因此获得更好的研发体验。

3. 类型与文档自动同步

快速同步各平台支持的类型,一直以来都是十分头疼的问题之一,想要实时跟进各个平台以提升用户体验十分困难,更多时候我们都通过开发者提交的 PR 或 issue 对这些平台的类型更新维护。如果能够根据各个小程序平台官方提供的文档自动化生成类型,这对于框架维护和开发者来说会是一个很棒的体验。

CanIUse

通过在 Taro 社区中的积极探讨和论证,我们引入了自动同步各小程序平台组件类型的脚本机制,并通过与 GitHub CI 让机器人为 Taro 仓库提交类型更新 PR。组件类型的自动化同时让 Taro 的文档在类型更新时,同步这些平台组件的变更,为开发者提供更好的文档索引能力。同时我们也在文档提供了 canIUse 页面,供开发者快速检索组件、特性在各个平台支持的程度。

希望后续也能够通过和各平台合作的方式优化该能力,为开发者提供更好的体验。在这里特别感谢 @rebinv8 为组件类型自动化脚本做出的贡献~

4. Taro Playground 同步升级

作为 RN 端的调试工具及跨端 Demo,Taro Playground 同步更新 v3.6 更新。此次更新无法保证向下兼容,使用旧版本 Taro 的开发者,如需调试 Android,可在 releases 中下载旧包进行调试。在 App Store 中,我们只上架最新版本,需要旧版本的开发者请不要开启应用自动更新。如不慎升级,需自行打包编译,或联系我们加入测试组。

五、升级指南

1. 创建 v3.6 版本项目:

# 安装 v3.6.0 的 CLI 工具
npm i -g @tarojs/cli@latest
# 创建项目
taro init taro_project

# 也可以跳过安装 CLI 工具使用 npx 创建项目
npx @tarojs/cli@latest init taro_project

2. 已有项目升级到最新版本:

  1. 将 package.json 文件中 Taro 相关依赖修改为 3.6.0 版本;
  2. Taro v3.6 将 web 端插件化,需要新增依赖 @tarojs/plugin-platform-h5,同时 @tarojs/router@tarojs/taro-h5 不再需要额外声明依赖,可自行移除;
  3. 重新安装依赖,如果安装失败或打开项目失败,可以删除 node_modulesyarn.lockpackage-lock.json 后重新安装依赖重新尝试。

最后

自 Taro 引入技术委员会等机制后,与社区互动愈加频繁,Taro 也得益于诸多贡献者的帮助有能力去实现更多有意思的特性,给开发者带来更好的用户体验,这也是 Taro v3.6 在代号「Reach」中的期待。感谢各位参与到 Taro 开源生态共建的同学们,所有的努力都让 Taro 的生态更加美好,为建立更加完善、更加可持续的 Taro 开源生态,贡献力量!