博览会和发布渠道...如何识别dev/prod和真实渠道

Expo and release channels...how to recognise dev/prod and a real channel

我在 expo 发布渠道上遇到了一些问题。 我不是 React Native 和 Expo 的专家,这让事情变得更容易:

如果我使用本地开发环境,则不会设置频道(这是有道理的)。

而且最终发布还是"production"不会有频道集, 这让我很不清楚我应该如何识别 'production' 和 'development'.

然后,如果我想添加一个频道,则会添加一个新的复杂度级别...例如 'staging',它将有一个频道...

锦上添花的是,在我的部署系统(Circle)中,我必须在频道中构建'development'(否则NODE_ENV将是"production")

有人知道如何正确使用频道吗? :)

基本上,我没有找到比这个更好的解决方案:

import { Constants } from 'expo'
const ENV= {production:{},staging:{},development:{}}

// Having fun with channels
const channel = Constants.manifest.releaseChannel;
if (channel === null || channel === undefined || channel === '') {
  if (process.env.NODE_ENV === 'production') {
    return ENV.production;
  }
  if (process.env.NODE_ENV === 'development') {
    return ENV.development;
  }
}
if (channel === 'staging') {
  return ENV.staging;
}
if (channel === 'development') {
  return ENV.development;
}
return ENV.production;

非常感谢!

我认为你漏掉了什么是发布渠道。

当您的应用程序使用 exp build 构建时,它会绑定到一个发布渠道(默认为 default)。 稍后,如果您想进行 OTA 更新,只需 运行 exp publish 即可将您的代码发布到发布频道(同样:默认为 default)。

当您向用户发布独立版本时,您不想通过 OTA 向他们提供未经测试的代码等,因此您希望用户将发布渠道设置为 ex。 prod.

这与 NODE_ENV 完全不同,我真的看不出将它们捆绑在一起的意义。

值得注意的是,process.env.NODE_ENV === 'production' 构造仅在捆绑构建过程中才有意义 - 捆绑器将是 运行,NODE_ENV 变量设置为特定环境。

production 环境中,这意味着捆绑器的内置压缩器会将所有出现的 process.env.NODE_ENV 替换为其实际值 (production f.e), metro 打包器默认是这样配置 minifier 的。 F.e:

if (process.env.NODE_ENV !== 'production') {
   ... some dev-only code, like 'assert(something)' or 'console.log(some debug info)'
}

会变成

if ('production' !== 'production') {
   ... some dev-only code, like 'assert(something)' or 'console.log(some debug info)'
}

然后会进一步缩小到

if (false) {
   ... some dev-only code, like 'assert(something)' or 'console.log(some debug info)'
}

然后将从结果代码中完全消除,因为 if 语句中的代码无论如何都不会执行。

例如,您的代码在开发模式下将被视为:

if (channel === null || channel === undefined || channel === '') {
  if ('development' === 'production') {
    return ENV.production;
  }
  if ('development' === 'development') {
    return ENV.development;
  }
}

... further simplified to:

if (channel === null || channel === undefined || channel === '') {
    return ENV.development;
}

在产品模式下:

if (channel === null || channel === undefined || channel === '') {
  if ('production' === 'production') {
    return ENV.production;
  }
  if ('production' === 'development') {
    return ENV.development;
  }
}

... further simplified to:

if (channel === null || channel === undefined || channel === '') {
    return ENV.production;
}

你应该记住,react-native 代码 运行 在设备上的本机应用程序中,而不是在某些 Node 实例中,因此它对严格的节点特定 ecosystem/environment 变量(不过,您可以通过一些库(如 dot-env 等)使用自定义值猴子修补 process.env),这是 npm 中的某些节点 utils/packages 不能的原因之一不能按原样用于 react-native 应用程序,因为它们是节点特定的 (fs f.e.).

这与在提供给客户端浏览器的前端代码上使用 process.env.NODE_ENV 变量相同 - 浏览器中没有可用的 process 实例,并且除非您使用缩小器并将其配置为用某些特定值替换 process.env.NODE_ENV 的出现,否则您的代码只会抛出未定义的变量访问错误。 Metro bundler 为您处理这个特定的用例,但我认为无论如何都值得一提。