条件编译必须用“// #ifdef 平台标识符”格式,严格满足双斜杠+空格+平台标识符+单独成行;平台标识符大小写、短横线敏感,如MP-WEIXIN、APP-PLUS、H5;template/style/pages.json中语法一致但位置不同;禁用process.env.UNI_PLATFORM运行时判断,因其无法剔除无用代码。

// #ifdef H5 为什么必须写成注释格式
因为 #ifdef 不是 JavaScript 语法,而是 uni-app 编译器在构建阶段识别的标记。它只在源码被解析时起作用,运行时完全不存在。一旦写成 #ifdef H5(没双斜杠)或 //#ifdef H5(缺空格),编译器就当普通文本忽略,导致本该剔除的代码意外打进所有平台包里。
常见错误现象:
-
#ifdef MP-WEIXIN直接写在 script 里 → 编译不报错但无效,H5 包里也出现uni.navigateToMiniProgram() -
//#ifdef H5中间没空格 → 被当成普通注释,整段代码照常编译 -
// #ifdef H5 console.log('h5')把逻辑写在同一行 → 编译器只认纯注释行,后面代码仍会被保留
正确写法必须严格满足三要素:双斜杠 + 空格 + #ifdef 或 #ifndef + 平台标识符 + 单独成行。
APP-PLUS、MP-WEIXIN、H5 这些平台标识怎么记准
大小写、短横线、全大写都敏感,不能靠猜。比如微信小程序是 MP-WEIXIN,不是 weixin、mini-program 或 MP_WEIXIN;鸿蒙是 APP-HARMONY,和 APP-PLUS 互斥;H5 就是 H5,不是 WEB 或 BROWSER。
容易混淆的点:
-
APP≠APP-PLUS:前者是旧版别名,已弃用;后者才是当前标准值,指 iOS/Android 原生 App -
APP-NVUE和APP-PLUS-VUE3是细分场景,只在启用对应编译模式时生效 -
MP-QQ、MP-BAIDU等需确认项目中是否启用了对应平台支持(如未勾选 QQ 小程序 SDK,即使写了// #ifdef MP-QQ也不会编译进去)
template 和 style 里也能用条件编译吗
能,而且语法完全一致,只是写法位置不同。
在 template 中用 HTML 注释包裹:
<!-- #ifdef H5 -->
<input type="text" placeholder="H5 原生输入框" />
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<input wx:if="{{true}}" placeholder="小程序 input" />
<!-- #endif -->在 style 中用 CSS 注释包裹:
/* #ifdef H5 */
.input-h5 { border: 1px solid #ccc; }
/* #endif */
/* #ifdef MP-WEIXIN */
.input-mp { padding: 8px; }
/* #endif */注意:pages.json 里也支持,但逗号位置极易出错——比如在 // #ifdef H5 块末尾多加一个逗号,会导致 JSON 解析失败,编译直接中断。
为什么不能用 process.env.UNI_PLATFORM 做运行时判断
因为它是构建时注入的静态字符串,在生产环境下可能被压缩工具删掉(比如 UglifyJS 会干掉未引用的 process 对象),更关键的是:它无法剔除无用代码。
典型问题:
- 写了
if (process.env.UNI_PLATFORM === 'MP-WEIXIN') { uni.navigateToMiniProgram() }→ H5 包里依然包含uni.navigateToMiniProgram调用,运行时报undefined is not a function - 某些平台 API(如
plus.device.vibrate)只存在于 App 环境,打进 H5 包后会触发全局报错,甚至阻塞首屏渲染 - 样式或组件引用也会一并打包进去,徒增包体积,尤其对小程序 2MB 限制很危险
真正安全的做法,是把整个调用逻辑(包括 import、变量定义、函数体)都包进 // #ifdef MP-WEIXIN → // #endif 块里,让编译器从源头隔离。


















