No3.《理解uni-app中的条件编译》

163 阅读3分钟

前几天在面试时被问到 uniapp 的条件编译时,当时回答的模模糊糊的,平时在项目中就只知道怎么用,对于为什么这么用以及底层的实现原理却不太清楚,后面去阅读了下官方文档,对这个问题做下整理(ps:官方文档是了解学习知识的必要途径这句话果然没错,平时还是得多看官方文档!)

我们知道 Uni-APP 是一种跨平台混合开发框架,可以让一套代码在多个平台运行,其底层是因为代码在编译阶段时,最终由不同平台的运行时(runtime)进行解析,从而实现跨平台。

但是,总有一些特殊的东西(比如:组件、API、样式等)是无法让同一个东西在不同平台实现,存在平台间的兼容性,这时就需要利用 条件编译 来解决这些兼容性问题。

说到条件编译,会想到 JavaScript 中的 if...else、switch...case、while等语法,这些都是做条件逻辑处理的。如果直接这些方式,可能会导致代码过于冗余,而且不符合这些语法的使用场景(不同条件对应不同逻辑,而uniapp中的兼容在逻辑上大致一样,只是平台对这些逻辑有不同的处理方式)。最终,uniapp 开发团队采用 C 语言中的条件编译方式来做不同平台的兼容。

什么是条件编译?

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。条件编译的实现依赖于编译工具和构建流程,uniapp 的编译器在编译阶段会解析代码中的条件编译注释,并根据当前的编译目标平台来决定保留或移除哪些代码。

条件编译的使用方法

使用 #ifdef#ifndef%OLATFORM% 开头,以 #endif 结尾。有以下几种使用方式(在html、js/json、css中的不同用法):

<!-- #ifdef H5 -->
<view>只在 H5 平台显示</view>
<!-- #endif -->
// #ifndef MP-WEIXIN
console.log("除了微信小程序平台,都可以执行")
// #endif
/* 在 H5 和 APP 中使用的样式 */
/* #ifdef H5 || APP-PLUS */
.container{
    width: 20px;
    height: 20px;
    background-color: red;
}
/* #endif */

其中 %PLATFORM% 是不同平台标识变量,可取的值有:H5、APP-PLUS、MP-WEIXIN、MP-ALIPAY 等,更多的值可以去文档查看。

这里引出了一个问题,uniapp 是如何获取这些不同平台变量值的呢?

这个应该是在编译阶段获取的,如果是编译运行到多个平台,就会自定义对应平台的宏(也可以理解为一种指令),比如在网页中运行就会定义 H5,在 APP 或微信小程序平台运行就会定义 APP-PLUS 或 MP-WEIXIN,然后根据注释中不同的平台执行不同的代码

除了以上的条件编译,针对不同平台(Android、iOS)的设备,uniapp 也提供了 uni.getSystemInfouni.getSystemInfoSync 来获取设备信息,然后根据不同平台设备来做进一步的兼容处理。