H5
本篇将介绍 H5 开发的相关内容,包括兼容性、注意事项等。
兼容性
ES5
默认配置下,@babel/preset-env
的 target
配置为:
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-loader
的external
属性。
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 开发,兼容性良好,但是目前只适配了若干常用的组件,开发者请谨慎选择使用。
使用方法
- 安装兼容性组件库
$ yarn add @tarojs/components-react
- 设置编译配置
h5.useHtmlComponents
module.exports = {
h5: {
useHtmlComponents: true
}
}
- 启动编译
$ taro build --type h5 --watch
贡献流程
由于人力问题,Taro 团队的迭代重心仍在 Web Components
组件库上。也欢迎各位开发者为 React 兼容性组件库添砖加瓦,具体工作是把以 Stencil
语法开发的组件改为 React 语法(Stencil 支持 JSX,因此改造工作量不大)。具体开发流程请看:@tarojs/component-react
lazy-load
Taro-H5 打包时会将页面和组件拆分成独立的文件按需加载,但这么做会导致没有用到的页面和组件依旧会被打包,有一些场景(比如 PWA 等需要严格限制包体大小时)会因此受到一些困扰。
所以我们通过 babel 插件提供了移除懒加载的方法:
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 库提供的一系列能力,路由守卫就是其中之一。
当用户返回上一页时,我们可以借助 history
的 Blocking Transitions 能力监听返回事件,根据一些判断逻辑(例如弹窗挽留用户)决定是否执行路由返回操作。
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 进行关闭:
const config = {
// ...
h5: {
devServer: {
hot: false
}
}
}
module.exports = {
presets: [
['taro', {
framework: 'react',
hot: false
}]
]
}