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

路由#

路由模式#

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 可以替换为自定义弹窗)
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
}]
]
}