uni-app条件编译需用// #ifdef等独占行注释,仅作用于template、script及js/ts文件,样式中无效;须顶格书写,封装平台api并二次校验,h5端忽略因语法或位置错误。

uni-app 条件编译怎么写才不被 H5 端忽略
条件编译在 uni-app 里不是“写了就生效”,而是依赖编译器预处理阶段识别特定注释语法。如果写在 JS 逻辑里用 if 判断 uni.getSystemInfoSync().platform,那只是运行时分支,不算条件编译——打包时所有代码仍会进入各端产物,白占体积、还可能触发跨端 API 报错。
真正起作用的只有这三类注释形式,且必须独占一行、前后无空格:
-
// #ifdef H5和// #endif:只保留在 H5 编译结果中 -
// #ifndef MP-WEIXIN和// #endif:排除微信小程序,其余端都保留 -
// #ifdef APP-PLUS || MP-ALIPAY:支持多平台用||连接,但不能写成&&
常见错误:把 // #ifdef 写在 export default 对象内部、或缩进后换行;编译器会直接跳过,当成普通注释。
JS 里怎么安全调用平台专属 API
光靠条件编译包裹代码还不够。比如在 onLoad 里写 uni.getBatteryInfo,这个 API 只在 App 端存在,微信小程序和 H5 都会报 undefined is not a function 错误——哪怕你用 // #ifdef APP-PLUS 包了,也得确保 JS 执行流不会走到未定义的调用位置。
实操建议:
- 把平台专属 API 调用封装成独立函数,并用
// #ifdef包裹整个函数定义(不是只包调用) - 在通用逻辑里通过
typeof xxx === 'function'做二次防护,尤其当函数可能被跨端复用时 - 避免在
data()或computed中直接调用平台 API,它们会在组件初始化时同步执行,容易崩
示例:
// #ifdef APP-PLUS
const getBatteryLevel = () => {
return new Promise(resolve => {
uni.getBatteryInfo({
success: res => resolve(res.level)
})
})
}
// #endif
// #ifndef APP-PLUS
const getBatteryLevel = () => Promise.resolve(100)
// #endif
样式文件里条件编译为什么经常失效
很多人以为 style 标签里也能用 // #ifdef,其实不行。CSS 不支持注释语法做条件剔除,uni-app 的条件编译只作用于 .vue 的 <template></template>、<script></script> 和 .js/.ts 文件,<style></style> 里的内容全量输出。
正确做法是:
- 用平台特有 class 名 + 平台前缀:比如给按钮加
class="btn btn--h5",然后在App.vue或页面级样式里用.h5 .btn--h5 { ... }控制 - 利用
uni.getSystemInfoSync().platform动态绑定 class,再配合 CSS 变量做微调 - 把平台差异大的样式抽成单独的
xxx.h5.css、xxx.mp.css,用// #ifdef引入对应文件
注意:import './index.h5.css' 这种写法必须配合 // #ifdef H5 注释,否则 Webpack 会尝试加载所有 import,导致 H5 编译失败。
条件编译和 vite / cli 版本的兼容性坑
新版 uni-app(基于 vite)对条件编译的解析更严格。老项目从 vue-cli 升级后,常出现 // #ifdef 失效、或者编译报 Unexpected token ——大概率是注释没顶格、或混用了中文标点、或出现在 setup 语法糖的 <script setup></script> 顶部注释区以外的位置。
关键检查点:
-
// #ifdef必须紧贴行首,前面不能有空格、制表符或任何字符 - 不要在
<script setup></script>的顶层作用域外使用(比如不能放在defineProps后面再写// #ifdef) - 如果用了
unplugin-vue-components自动导入,确保它没把条件编译块当成普通代码扫描
最稳妥的方式:所有条件编译逻辑集中在 script 模块顶部,或拆到独立的 platformUtils.js 中统一管理。
复杂点在于,条件编译是静态的,而有些需求其实是动态的——比如用户切换主题后想改平台行为。这时候就得放弃条件编译,改用运行时判断 + 容错封装,别硬套 // #ifdef。











