Skip to main content
Version: 3.x

H5

本篇将介绍 H5 开发的相关内容,包括兼容性、注意事项等。

兼容性

ES5

默认配置下,@babel/preset-envtarget 配置为:

targets = {
ios: '9',
android: '5'
}

如果需要兼容更低版本的系统,请修改在项目根目录的 babel.config.js 中修改 babel-preset-taro 的配置。(babel-preset-taro 暴露的参数暂时没有文档,详细配置请参考 源码,欢迎贡献文档~)

babel-loader

为了提升编译速度,Taro 给 babel-loader 设置了 external 属性。对于 node_modules 里(除了命名含有 taro)的依赖,都不经过 babel 编译。babel-loader 配置请看 Github

因此需要注意以下问题:

  • @tarojs/components 默认不经 Babel 编译,但 3.2.10 之前没有编译出 ES5 包,请更新到 3.2.10 及以上版本。
  • 默认不编译 node_modules 里的依赖,如有兼容性需求,请手动使用 WebpackChain 修改 babel-loaderexternal 属性。

Android 4.4

兼容安卓 4.4 请确认完成了以下操作:

  • Taro 使用 v3.2.15+ 版本。
  • 使用兼容性组件库(暂时只支持 React)。
  • 合理配置 babel-preset-taro,安装 corejs3
  • 如还是遇到 Promise undefined 的问题,可在 index.html 中手动引入一个 Promise 的 polyfill。

React 兼容性组件库

note

Taro 3.2.4 开始支持

Taro3 的 H5 端组件库基于 Web Components,使用了 Stencil 框架进行开发。

Stencil 兼容性情况

但移动端对 Web Components 的支持还有一些问题,主要问题如下:

  • 安卓 4.4 白屏
  • 多行文字截断失效
  • 部分安卓机(OPPO、VIVO 居多),样式 visibility 切换失败导致页面白屏

因此,对兼容性要求强烈对开发者,可以使用 React 兼容性组件库代替默认的 Web Components 组件库。它完全基于 React 开发,兼容性良好,但是目前只适配了若干常用的组件,开发者请谨慎选择使用

使用方法

  1. 安装兼容性组件库
$ yarn add @tarojs/components-react
  1. 设置编译配置 h5.useHtmlComponents
config/index.js
module.exports = {
h5: {
useHtmlComponents: true
}
}
  1. 启动编译
$ taro build --type h5 --watch

贡献流程

由于人力问题,Taro 团队的迭代重心仍在 Web Components 组件库上。也欢迎各位开发者为 React 兼容性组件库添砖加瓦,具体工作是把以 Stencil 语法开发的组件改为 React 语法(Stencil 支持 JSX,因此改造工作量不大)。具体开发流程请看:@tarojs/component-react

lazy-load

Taro-H5 打包时会将页面和组件拆分成独立的文件按需加载,但这么做会导致没有用到的页面和组件依旧会被打包,有一些场景(比如 PWA 等需要严格限制包体大小时)会因此受到一些困扰。

所以我们通过 babel 插件提供了移除懒加载的方法:

babel.config.js
module.exports = {
presets: [
['taro', {
framework: 'react',
hot: false,
'dynamic-import-node': true
}]
]
}

dataset

Taro-H5 在 3.3.1+ 版本才支持 data-* 设置参数到节点上,如需使用请升级到对应版本。

路由

路由模式

H5 支持使用 hash 路由模式和浏览器 history 路由模式,默认使用 hash 模式。可以修改 h5.router.mode 进行配置。

路由基准路径 basename

H5 支持设置路由 basename,可以修改 h5.router.basename 进行配置。

自定义路由

H5 支持设置自定义的路由影射规则,可以修改 h5.router.customRoutes 进行配置。

路由守卫

Taro H5 的路由实现基于 history 库,因此支持使用 history 库提供的一系列能力,路由守卫就是其中之一。

当用户返回上一页时,我们可以借助 historyBlocking Transitions 能力监听返回事件,根据一些判断逻辑(例如弹窗挽留用户)决定是否执行路由返回操作。

history 文档上的例子(例子中的 window.confirm 可以替换为自定义弹窗)
import { history } from '@tarojs/router'

function Index () {
useEffect(() => {
// Block navigation and register a callback that
// fires when a navigation attempt is blocked.
let unblock = history.block(tx => {
// Navigation was blocked! Let's show a confirmation dialog
// so the user can decide if they actually want to navigate
// away and discard changes they've made in the current page.
let url = tx.location.pathname
if (window.confirm(`Are you sure you want to go to ${url}?`)) {
// Unblock the navigation.
unblock()

// Retry the transition.
tx.retry()
}
})
return () => unblock()
}, [])

return <View />
}

React

使用 React 开发 H5 时需要注意的一些问题。

fast refresh

React 在 H5 Dev 编译模式时默认开启了 fast refresh 功能。

但是当使用了自定义环境变量时会出现以下报错:

或配置了 Webpack devServer 关闭热更新:hot: false 时,会出现以下报错:

danger

Uncaught ReferenceError: $RefreshSig$ is not defined

这都是因为在 dev 环境,Taro 默认做了两件事情:

  • 使用 fast-refresh 的 Babel plugin
  • 把 Webpack 配置的 devServer.hot 设置为 true,会加入 fast refresh 的 loader。

而且 fast refresh 的 Babel plugin 和 loader 必须同时启用或关闭。

因此当出现上述报错时,或不希望开启 fast refresh 时,可以通过同时配置 Babel 和 Webpack 进行关闭:

config/index.js
const config = {
// ...
h5: {
devServer: {
hot: false
}
}
}
babel.config.js
module.exports = {
presets: [
['taro', {
framework: 'react',
hot: false
}]
]
}