写点什么

鸿蒙多环境配置 (一)

作者:龙儿筝
  • 2024-10-31
    上海
  • 本文字数:2978 字

    阅读完需:约 10 分钟

鸿蒙多环境配置(一)

在实际开发过程中,你是否遇到了如下一些问题。项目分多套环境,如开发环境,生产环境,甚至还有灰度环境,不同的环境请求的服务器地址不一样,不同环境依赖的库也不一样,使用的三库 key 也不一样。测试会问开发环境的包和生产环境的包可以同时安装在手机上吗,我怎么区分哪个是生产环境的包,开发环境能否加个入口等等。

是否可以使用 debug 和 release 来区分不同的环境

大多数情况下,我们可能只需要区分开发环境和生产环境,那么有人会问,只有 2 套环境,是否可以用 debug 代表开发环境,release 来代表生产环境呢?在代码编译阶段,会生成一个BuildProfile文件,在代码中使用BuildProfile.DEBUG就能区分了。


这种方式在部分场景下也许可行,但有存在一些问题,比如后面在上线前增加灰度环境怎么处理,遇到问题要在生产环境调试怎么办?所以我们并不推荐使用此方式来区分不同的环境,鸿蒙提供了ProductTarget概念来很好的处理多环境配置需要。

认识 Product 和 Target

我们将需要编译打包的应用定义为一个 Product,当想打多个不同应用时,就可以定义多个不同的 Product,执行打包时,也需要选择相应的 Product。


每一个 Module 都可以设定自己的源码目录,资源目录,运行的设备,分发规则等等,我们将这些行为定义成一个 Target,不同的 Target 可以有不同的行为。每一个 Target 都需要配置应用到哪些 Product 中,这样就建立了 Product 与 Target 的关联关系。


下图是选择 Product 和 Target 的方式。


配置多环境产物

如何在手机上同时安装开发包和生产包

要想同时安装开发包和生产包,需要有 2 个 bundleName,我们可以定义 2 个 Product,在 Product 中设置不同的 bundleName,示例如下


{  "app": {    "signingConfigs": [],    "products": [      {        "name": "default",//开发环境        "bundleName": "com.aloe.moment.dev"      },      {        "name": "prod",//生产环境        "bundleName": "com.aloe.moment"      }    ]  }}
复制代码

如何区分开发包和生产包

手机桌面上同时安装了开发包和生产包,该如何区分哪个是生产包呢,是否能对 APP 设置不同的名称和 icon 呢?答案是可以的,我们可以在不同的 target 中设置针对每一个 ability 设置不同的名称和 icon,示例如下


{    "apiType": 'stageMode',    "buildOption": {    },    "targets": [      {        "name": "default",        "source": {        "abilities": [          {            "name": "EntryAbility",            "icon":"$media:layered_image",            "label":"$string:EntryAbility_label",            "launchType": "singleton"          }        ]      }     },      {        "name": "prod",        "source": {        "abilities": [          {            "name": "EntryAbility",            "icon":"$media:layered_image",            "label":"$string:EntryAbility_label",            "launchType": "multiton"          }        ]      }     }   ]  }
复制代码


其实 Target 还可以定制不同的资源目录,如果我们想针对不同的 Product 设置不同的名称和 icon,完全可以定制不同的资源目录,然后将名称和 icon 放在不同的资源目录中。示例如下


{  "apiType": "stageMode",  "targets": [    {      "name": "default",      "resource": {        "directories": [          "./src/default/resources",          "./src/main/resources"        ]      }    },    {      "name": "prod",      "resource": {        "directories": [          "./src/prod/resources",          "./src/main/resources"        ]      }    }  ]}
复制代码

不同的环境设置不同的参数

在开发过程中,我们经常会根据不同的环境来设置不同的参数,比如 debug 和 release 环境,所使用的参数有所不同,或者开发环境与生产环境使用的第三方 key 有所不同,这些场景都可以通过编译期间生成的BuildProfile来实现,避免直接在代码中判断不同的环境来设置不同的值 。下面以不随环境变化的COMMON_TYPE参数,区分debugrelease环境的BUILD_TYPE参数,区分开发环境和生产环境的KEY参数来举例说明


{  "apiType": "stageMode",  "buildOption": {    "arkOptions": {      "buildProfileFields": {        "COMMON_TYPE": "common_type"      }    }  },  "buildOptionSet": [    {      "name": "release",      "arkOptions": {        "buildProfileFields": {          "BUILD_TYPE": "build_release"        }      }    },    {      "name": "debug",      "arkOptions": {        "buildProfileFields": {          "BUILD_TYPE": "build_debug"        }      }    }  ],  "targets": [    {      "name": "default",      "config": {        "buildOption": {          "arkOptions": {            "buildProfileFields": {              "KEY": "default_key"            }          }        }      }    },    {      "name": "prod"      "config": {        "buildOption": {          "arkOptions": {            "buildProfileFields": {              "KEY": "prod_key"            }          }        }      }    }  ]}
复制代码


这样配置后,编译时会自动根据不同的环境来生成不同的参数,在代码中就可以直接使用,不用额外判断环境了。

不同的环境如何区分不同的业务逻辑

现在有这样一个需求,生产环境正常显示 APP 的版本名称和版本号,开发环境为了区分当前提测包是否为最新包,需要额外显示一个打包时间或最新代码提交时间,这种需求除了在代码中判断环境,还能如何处理呢?测试要求在开发包中额外增加一个配置入口,方便他们直接修改相关配置,可以不判断环境,统一处理吗?


针对上面的问题,我们可以在 Target 中设置不同的源码目录,然后根据各自的环境,实现不同的业务逻辑。我们先在 Target 中配置不同的源码目录,示例如下


{  "apiType": "stageMode",  "targets": [    {      "name": "default",      "source": {        "sourceRoots": ["./src/default"]      }    },    {      "name": "prod",      "source": {        "sourceRoots": ["./src/prod"]      }    }  ]}
复制代码


然后在各自的源码目录中实现相关逻辑,我们以实现一个AppUtil.getName获取名称和testConfig添加测试配置入口为例,相关代码如下


//开发环境的实现export namespace AppUtil{  export function getName():string{    return 'develop'  }}@Builderexport function testConfig(){  Button('测试入口')}
//生产环境的实现export namespace AppUtil{ export function getName():string{ return 'produce' }}@Builderexport function testConfig(){}
复制代码


在页面中使用方式如下


import { AppUtil,testConfig } from 'entry/ets/utils/AppUtil';
@Entry@Componentstruct Index {
build() { Column() { Text(AppUtil.getName()) testConfig() } .height('100%') .width('100%') }}
复制代码


最终运行到手机上的效果是开发环境界面显示 develop 并在下方显示了一个测试入口的按钮,而在生产环境仅显示了 produce,没有显示测试入口的按钮。


发布于: 刚刚阅读数: 4
用户头像

龙儿筝

关注

还未添加个人签名 2024-10-27 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙多环境配置(一)_鸿蒙_龙儿筝_InfoQ写作社区