H5
本篇将介绍 H5 开发的相关内容,包括兼容性、注意事项等。
兼容性
ES5
默认配置下,@babel/preset-env
的 target
配置为:
targets = {
ios: '9',
android: '5',
}
如果需要兼容更低版本的系统,请修改在项目根目录的 babel.config.js
中修改 babel-preset-taro
的配置。文档
babel-loader
为了提升编译速度,Taro 给 babel-loader
设置了 exclude
属性。对于 node_modules
里(除了命名含有 taro
)的依赖,都不经过 babel 编译。babel-loader
配置请看 Github。
因此需要注意以下问题:
@tarojs/components
默认不经 Babel 编译,但3.2.10
之前没有编译出 ES5 包,请更新到3.2.10
及以上版本。- 默认不编译
node_modules
里的依赖,如有兼容性需求,请手动使用 WebpackChain 修改babel-loader
的exclude
属性。
Android 4.4
兼容安卓 4.4 请确认完成了以下操作:
- Taro 使用
v3.2.15+
版本。 - 使用兼容性组件库(暂时只支持 React)。
- 合理配置
babel-preset-taro
,安装corejs3
。 - 如还是遇到
Promise undefined
的问题,可在index.html
中手动引入一个 Promise 的 polyfill。
组件库
Input 组件不受控制
在 React 框架中使用 Input 组件时,如果传入 Input 组件值并未更新,开发者对输入值的约束会失效。这是由于虽然用户输入触发了相关事件,但由于开发者约束值导致组件 props 并未实际触发组件更新导致,此时需要手动刷新组件内容。
React 兼容性组件库
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, // 如果使用时遇到问题,可尝试将 devServer 配置项中的 hot 设置为 false
},
],
],
}
dataset
Taro-H5 在 3.3.1+ 版本才支持 data-*
设置参数到节点上,如需使用请升级到对应版本。
IE 浏览器兼容
在 Taro H5 中,我们使用了 IntersectionObserver 来实现了 Image
组件和 createIntersectionObserver
方法,考虑到该对象在各端特别是移动端适配度已经很高我们在 v3.6.23 版本开始考量移除了它的 polyfill 依赖,如若项目有 IE11 及以下浏览器需求可以通过以下配置启用该兼容模式。
// config/prod.js
module.exports = {
env: {
NODE_ENV: '"production"',
SUPPORT_TARO_POLYFILL: '"enabled"', // 3.+ 默认值为 enabled; 4.+ 默认值为 disabled
},
// ...
}
值 | 说明 |
---|---|
enabled | 启用全部 Polyfill |
Object | Object Scope Polyfill |
Object.assign | Object.assign Polyfill |
Object.defineProperty | Object.defineProperty Polyfill |
IntersectionObserver | IntersectionObserver Polyfill |
disabled | 禁用全部 Polyfill |
钉钉内核浏览器兼容
钉钉内核的浏览器部分特性和其他浏览器有所不同,需要专门适配(譬如标题不能切换等等)。由于需要引入 dingtalk-jsapi
将导致包体变大,故而默认关闭,如果需要可通过如下配置启用适配模块。
// config/prod.js
module.exports = {
env: {
NODE_ENV: '"production"',
SUPPORT_DINGTALK_NAVIGATE: '"enabled"', // 默认值为 disabled
},
// ...
}
路由
路由模式
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
时,会出现以下报错:
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,
},
],
],
}
服务端渲染(SSR)
社区 @SyMind 大佬提供了编译 NextJS 应用的插件 tarojs-plugin-platform-nextjs,用于支持 Web 端支持 SSR 能力,可以根据项目需要自行选择。
事件
__taroNotSupport
版本 3.5.6 开始支持该事件
Web 版本中调用不支持的组件或 API 时会触发该事件,可供开发者作统一配置处理。
interface IEventResult {
// 组件或 API 名称
name: string
// 类型
type: 'component' | 'method'
// 状态分类
category: 'temporarily' | 'weixin_corp' | 'permanently'
// 组件实例
instance?
// API 调用参数
args?: unknown?[]
}
组件编译模式
与小程序和 RN 一样,H5 也可以将编译为原生组件
使用方法
1. 配置组件路径
修改 app.config.js
,增加 components
配置,指向组件入口文件的路径:
export default {
// ...
components: ['pages/index/index', 'components/picker/index'],
}
2. 开始编译
使用 taro build native-components
命令,配合参数 type
,即可编译出对应平台的自定义组件。
taro build native-components --type h5 [--watch]
尺寸转换
组件编译模式同样支持与 Taro 一致的尺寸转换,需要注意的是虽然 css 样式完成了转化,但是部分在代码中的单位转换需要依赖 pxTransform
完成。
- Taro.pxTransform(10)
+ Taro.pxTransform.bind(this)(10)
组件模式下,Taro 将尺寸配置关联到组件实例上,在调用相关代码时需要关联相关配置,这一点与正常模式相区别。