09 - 平台适配
多端编译差异
项目当前只编译 微信小程序(weapp) 和 H5 两个平台。代码中保留了支付宝(alipay)等平台的适配逻辑,但不在维护范围内。
Taro 运行环境
| 环境 | TARO_ENV | 构建产物 | 特有能力 |
|---|---|---|---|
| 微信小程序 | weapp | dist/weapp/ | 插件、分包、IntersectionObserver |
| H5 | h5 | dist/h5/ | DOM、浏览器 API、history |
构建配置差异
SCSS 分平台 mixin:
js
// config/index.js
sass: {
resource: process.env.TARO_ENV === 'weapp'
? ['src/style/imports.scss', 'src/style/weapp-mixins.scss']
: ['src/style/imports.scss', 'src/style/h5-mixins.scss']
}weapp-mixins.scss:aspect-ratio使用 padding-top 降级方案(微信不支持aspect-ratioCSS 属性)h5-mixins.scss:aspect-ratio优先使用原生 CSS,降级到 padding-top
H5 路由模式:
| 构建类型 | publicPath | router.mode |
|---|---|---|
| 非 App | / | browser |
| App 前端 | ./ | hash |
| App 服务端 | / | browser |
js
const IS_APP = BUILD_TARGET === 'app'
const IS_APP_SERVER = BUILD_APP_SERVER === 'server'
h5: {
publicPath: IS_APP ? (IS_APP_SERVER ? '/' : './') : '/',
router: {
mode: IS_APP ? (IS_APP_SERVER ? 'browser' : 'hash') : 'browser'
}
}Copy 模式差异:
| 平台 | 额外复制 |
|---|---|
| 所有 | src/assets → dist/<env>/assets |
| H5 | src/files → dist/h5/ |
| 微信 | i18n JSON → JS 转换复制(4个语言文件) |
平台检测工具
核心常量
src/utils/index.js 导出平台检测常量:
js
export const isWeixin = Taro.getEnv() == Taro.ENV_TYPE.WEAPP
export const isWeb = Taro.getEnv() == Taro.ENV_TYPE.WEB
// 微信 PC 客户端小程序
export const isPCMiniProgram = () => { /* Windows/Mac 客户端微信小程序 */ }
// 微信浏览器 H5
export const isWxWeb = isWeb && !!getBrowserEnv().weixin代码中保留了
isAlipay、isAPP等常量,但当前项目只编译 weapp 和 h5。
产品版本常量
js
export const VERSION_STANDARD = process.env.APP_PLATFORM == 'standard' // 云店(B2C)
export const VERSION_PLATFORM = process.env.APP_PLATFORM == 'platform' // ECShopX(BBC)项目当前产品版本限定为
standard和platform。
platforms.js 工具函数
src/utils/platforms.js 提供平台相关操作:
js
// 获取小程序 appid
export const getAppId = () => getExtConfigData().appid
// 平台模版名称
export const platformTemplateName = 'yykweishop'
// URL 转换:微信去除 /alipay 前缀(兼容遗留逻辑)
export const transformPlatformUrl = (url) => {
const weapp = Taro.getEnv() === Taro.ENV_TYPE.WEAPP
return weapp ? url.replace('/alipay', '') : url
}浏览器检测
js
export const browser = (() => {
if (!isWeb) return {}
// 检测: trident(IE)/presto(Opera)/webKit/gecko
// 移动端: mobile/ios/android/weixin/qq
// 返回: { trident, presto, webKit, gecko, mobile, ios, android, weixin, qq }
})()设备检测
js
// iPhone X 系列(刘海屏)
export const isIphoneX = () => {
const model = systemInfo.model
return model.search(/iPhone\s*X|iPhone\s*11|...|iPhone\s*17/g) > -1
}条件配置
插件条件注入
app.config.js 根据环境变量条件性注入插件:
js
// 微信客服插件
if (process.env.APP_CONTACT_PLUGIN == 'true') {
config.plugins['contactPlugin'] = { version: '1.4.8', provider: 'wx104a1a20c3f81ec2' }
}
// 直播插件
if (process.env.APP_LIVE == 'true') {
config.plugins['live-player-plugin'] = { version: '1.3.5', provider: 'wx2b03c6e691cd7370' }
}
// Adapay 支付插件
if (process.env.APP_ADAPAY == 'true') {
config.plugins['Adapay'] = { version: 'latest', provider: 'wx308088053f4ecc3a' }
}weapp usingComponents
js
if (process.env.TARO_ENV == 'weapp') {
config.usingComponents = {
'mp-html': './components/sp-html/mp-weixin/index'
}
}产品版本条件
js
if (VERSION_STANDARD) { /* 云店(B2C)逻辑 */ }
if (VERSION_PLATFORM) { /* ECShopX(BBC)逻辑 */ }请求层适配
weapp 和 h5 两个平台的 Taro.request 行为有差异,需要适配(见 src/api/req.js):
| 平台 | 适配内容 |
|---|---|
| H5 | fetch 失败时将 Response 转换为统一格式 |
| 微信 | 直接使用 Taro.request,无额外适配 |
authorizer-appid header
微信小程序请求带 authorizer-appid header:
js
if (isWeixin) {
header['authorizer-appid'] = getAppId()
}company_id 提取差异
| 平台 | 提取方式 |
|---|---|
| H5 | 从域名 m38.shopex123.com 提取 → 38 |
| 微信小程序 | 从 ext.json 的 company_id 字段获取 |
代码中的条件编译
Taro 条件编译
js
// 使用 process.env.TARO_ENV
if (process.env.TARO_ENV === 'weapp') { /* 微信专属逻辑 */ }
if (process.env.TARO_ENV === 'h5') { /* H5 专属逻辑 */ }
// SCSS 条件编译
/* #ifdef weapp */
/* 微信专属样式 */
/* #endif */
/* #ifdef h5 */
/* H5 专属样式 */
/* #endif */产品版本条件
js
if (VERSION_STANDARD) { /* 云店(B2C)逻辑 */ }
if (VERSION_PLATFORM) { /* ECShopX(BBC)逻辑 */ }H5 环境工具
getBrowserEnv()
js
export function getBrowserEnv() {
if (!isWeb) return {}
// 返回: { weixin: true/false, ... }
}H5 分享
js
// 微信浏览器 H5 分享
if (isWxWeb) {
// 使用 wx.updateAppMessageShareData / updateTimelineShareData
}路由拦截器差异
| 平台 | 实现方式 |
|---|---|
| H5 | 重写 window.history.pushState / replaceState |
| 小程序 | 重写 Taro.navigateTo / redirectTo,额外检查页面栈深度 > 8 时自动 redirectTo |
