在uni-app中,可以说条件编译是uni-app实现多端部署的核心思想,通过条件编译,我们可以根据当前的平台、环境或配置选项来控制代码的执行逻辑,从而实现定制化的开发需求。
在我之前的开发项目中,不止需要已有平台的条件编译,还涉及到自定义平台条件编译,以适应项目中同一套代码,多端部署的场景。
接下来我将详细介绍uni-app中条件编译的使用和自定义平台,帮助大家更好地利用条件编译优化自己的应用开发过程。
uni-app为什么能实现一套代码、多端运行,多端部署的功能?其最核心的功能是通过编译器+运行时实现的,我梳理了一下,如下图整体流程图所示:
好家伙,不看不知道,一看吓一跳,一堆小程序平台??
编译器:将uni-app统一代码编译生成每个平台支持的特有代码;如:在小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等代码。
运行时:动态处理数据绑定、事件代理,保证Vue和平台宿主数据的一致性。
uni-app项目根据所依赖的Vue版本不同,编译器的实现也不同,目前uni-app的代码支持Vue2和Vue3两种语言版本。
Vue2版本的uni-app编译器基于Wepback实现,而Vue3版本的uni-app编译器基于Vite实现,编译速度更快。
可以通过manifest.json文件中切换Vue的使用版本,如下图所示:
初始化uni-app项目有两种方式,通过HBuilderX创建和使用cli方式创建,下面来说一下这两种创建方式在编译器方面的使用差异:
因此,为了避免出现一些更新问题,建议使用HBuilderX直接创建项目,便于适时更新到最新版的编译器,优化一些bug。
提示:经常跟随官方更新也会有问题,有些旧版本的代码在新版上有可能会不兼容!注意可能有坑!
uni-app已经将常用的组件、API封装到框架中,我们可以按照uni-app规范开发即可保证多平台兼容,大部分业务均可直接满足,但每个平台有自己的一些特性,因此必然会存在一些无法跨平台的情况。
当我们在写代码涉及到多平台时,由于每个平台的实现代码可能有所不同,因此如果是大量写ifelse,会造成代码执行性能低下和管理混乱,编译到不同的工程后二次修改,会让后续升级变的很麻烦。
由以上这个背景,uni-app参考在C语言中的一些实践经验,为其提供了类似的条件编译手段,通过#ifdef、#ifndef的方式,为小程序端、Web端、App端等不同客户端编译不同的代码,在一个工程里优雅的完成了平台个性化实现。
那么接下来我们看一下什么是条件编译及其使用方法?
条件编译其实是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
条件判断规则
以#ifdef或#ifndef加%PLATFORM%开头,以#endif结尾。
完整的判断方式为:
#ifdef%PLATFORM%此部分为实现对应平台的代码#endif参数说明:
#ifdef:ifdefined仅在某平台存在#ifndef:ifnotdefined除了某平台均存在%PLATFORM%:平台名称
目前uni-app条件编译所支持的平台大概有24个,分别如下:
我们主要可以在以下的文件中使用条件编译,如下所示:
uni-app的条件编译能支持以下几种场景,具体如图所示:
简言之,同一功能实现,可能有不同的逻辑处理,比如:在js文件中,或者在Vue文件中的script代码中有不同的逻辑处理方式,使用方式如下:
//#ifdef%PLATFORM%该平台特有的API实现;//#endif组件的条件编译在template模版中,可能会在不同的平台展示不同的组件,或者是展示效果不同,或者是在某一平台不需要展示,使用方式如下:
/*#ifdef%PLATFORM%*/该平台特有的样式/*#endif*/pages.json的条件编译不同平台下的特有功能,以及小程序平台的分包,都可以通过pages.json的条件编译来更好地实现。这样,就不会在其它平台产生多余的资源,进而减小包体积。
"pages":[//#ifdefH5{"path":"pages/test1","style":{"navigationBarTitleText":"测试1"}},//#endif//#ifdefMP-WEIXIN{"path":"pages/test2","style":{"navigationBarTitleText":"测试2"}},//#endif]特别注意:json的条件编译,一定要注意最后","分隔符的所属问题,不能有多余的逗号,可能会出现异常情况,导致编译失败!
在不同平台,引用的静态资源可能也存在差异,通过static的条件编译可以解决此问题,static目录下新建不同平台的专有目录,目录名称均为小写,专有目录下的静态资源只有在特定平台才会编译进去。
因此,以上这些差异就会要求在代码中处理不同平台之间的差异性,以下是我的实际项目中的自定义平台:
除此之外,还有两个APP平台,但是目前uni-app不支持自定义APP的基准平台!
如何增加uni-app扩展节点,总结一下有以下几个步骤可以快速完成一个全新平台的编译:
在package.json中添加uni-app节点,添加以下配置,使新定义的平台生效:
"uni-app":{"scripts":{"custom-h5":{"title":"自定义H5平台", "browser":"chrome","env":{"UNI_PLATFORM":"h5"},"define":{"CUSTOM-H5":true}},"custom-mp":{"title":"自定义小程序平台","env":{"UNI_PLATFORM":"mp-weixin"},"define":{"CUSTOM-MP":true}}}}参数说明:
正确的结构就是如上所示,下面说一下这几个参数的具体含义
注意事项:
接下来,可以在代码里使用自定义的条件编译,为这个新平台编写专用代码:
条件编译是uni-app实现一套代码、多端运行,多端部署的核心思想,uni-app在条件编译方面不止是处理js,任何代码都可以多端条件编译,因此可以大大降低了在实际项目的多端开发时的繁琐问题。
而关于你是否需要自定义平台,关键在于项目里复用的代码多还是个性的代码多,如果都是复用的代码多,并且对应的服务端是一致的,所以仍然可以自定义平台多端部署,而个性的代码放到不同平台的目录下,进行差异化维护。