<p>应使用条件编译而非uni.getSystemInfoSync().platform判断平台,因其返回底层环境而非目标平台;条件编译需用/ #ifdef 平台 /注释格式,严格匹配宏名且不可跨文件传递。</p>
在真机上 uni.getSystemInfoSync().platform 有时返回 "ios" 或 "android",但 H5 环境下它可能返回 "web",而小程序平台(如微信、支付宝)反而可能返回空字符串或 "devtools"。这不是 bug,是 API 设计本意:它返回的是「底层运行环境」,不是「当前编译目标平台」。
真正需要判断「当前代码跑在哪个平台(微信小程序?H5?App?)」时,必须用条件编译,不能依赖运行时 API。
uni.getSystemInfoSync() 适合查屏幕宽高、是否支持 vibration 等设备能力,不适合做平台路由platform 常为 "devtools",和真机行为不一致,容易误判uni-app 的条件编译必须写成注释格式,且紧贴代码上下文,中间不能有空行或其它注释干扰。常见错误是加了多余空格、用了双斜杠 // 而非 /* #ifdef ... */,或者放在 export default 外部导致整个模块被跳过。
正确写法示例:
/* #ifdef H5 */console.log('这是 H5 平台')/* #endif */<p>/<em> #ifdef MP-WEIXIN </em>/wx.login()/<em> #endif </em>/</p><p>/<em> #ifdef APP-PLUS </em>/uni.getBatteryInfo()/<em> #endif </em>/
H5、MP-WEIXIN、MP-ALIPAY、APP-PLUS、APP-PLUS-NVUE
/* #ifdef H5,MP-WEIXIN */
#ifndef,比如 /* #ifndef APP-PLUS */ 表示「非 App 平台」process.env.NODE_ENV 是 Node.js 构建环境变量,uni-app 编译时会注入,但它只区分 "development" 和 "production",**完全不反映平台信息**。有人误用它做平台判断,结果 H5 和小程序都输出 "production",逻辑直接崩掉。
__UNI_MP_VERSION 是 uni-app 内部注入的常量,仅在小程序平台存在,值为对应基础库版本号(如 "2.7.0"),但它无法区分微信、支付宝等不同小程序——所有小程序平台都会定义它。
PLATFORM 常量/* #ifdef H5 */const PLATFORM = 'h5'/* #endif *//* #ifdef MP-WEIXIN */const PLATFORM = 'mp-weixin'/* #endif */
条件编译可以嵌套,但深度建议控制在两层以内,否则可读性骤降。JS 文件中使用没问题,但要注意:不能在对象字面量或函数参数里直接写宏,必须整块代码包裹。
错误写法:
const config = { /* #ifdef H5 */ api: 'https://h5.api.com', /* #endif */ timeout: 10000} —— 这会导致语法错误,因为宏展开后 JSON 结构被破坏。/* #ifdef H5 */const config = { api: 'https://h5.api.com', timeout: 10000 }/* #endif *//* #ifdef MP-WEIXIN */const config = { api: 'https://mp.api.com', timeout: 15000 }/* #endif */
<script>、<template>、<style> 都支持独立条件编译,互不影响require 动态路径,require(`./api/${PLATFORM}.js`) 这种写法无效实际项目里最常踩的坑,是把条件编译当运行时 if 用,或者指望某个变量能跨平台统一取值。它本质是“编译期代码剪枝”,不是“运行时分支判断”——这点没理清,后面所有逻辑都会偏。