惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
博客园_首页
美团技术团队
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
H
Help Net Security
J
Java Code Geeks
T
Tailwind CSS Blog
Jina AI
Jina AI
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
爱范儿
爱范儿
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
宝玉的分享
宝玉的分享
小众软件
小众软件
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Visual Studio Blog
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

蚊子的前端博客

微说 | 有的人觉得只要不考XX,一定能考好!-蚊子的前端博客 微说 | 春天来了-蚊子的前端博客 明天和意外不知道哪个先来-蚊子的前端博客 微说 | 既然错过了路口,就及时止损,重新规划路线上路-蚊子的前端博客 微说 | 2025年的出生人口数是792万-蚊子的前端博客 微说 | 工作年终总结,让写对接的接口的数量?-蚊子的前端博客 微说 | 温家宝:没有政治体制改革的成功 经济体制改革不可能进行到底-蚊子的前端博客 微说 | 违法犯罪了该不该被禁言?-蚊子的前端博客 微说 | 不明白为什么在推荐去俄罗斯旅游-蚊子的前端博客 微说 | 易中天论骗子-蚊子的前端博客 微说 | 一场大风吹散了秋天-蚊子的前端博客 微说 | 既要、又要、还要、更要!-蚊子的前端博客 又是一年的国庆雨季-蚊子的前端博客 微说 | 预估下2025年的出生人口数据-蚊子的前端博客 微说 | 可惜了我那些小时候的书本-蚊子的前端博客 微说 | 牛马有的是,驴不够了!-蚊子的前端博客 微说 | 能否有一条非户口也能高考的路-蚊子的前端博客 微说 | 小聊中医-蚊子的前端博客 微说 | 将要制作的一款新产品-蚊子的前端博客 微说 | 做人要有信-蚊子的前端博客 微说 | 好一个正义联盟-蚊子的前端博客 微说 | 都是见过吃过的主儿-蚊子的前端博客 微说 | 追求8小时工作制有错吗?-蚊子的前端博客 微说 | 如果尖锐的批评完全消失-蚊子的前端博客 微说 | 很好!-蚊子的前端博客 微说 | 封禁用户可以,但要告知具体原因-蚊子的前端博客 微说 | 面朝大海,春暖花开-蚊子的前端博客 微说 | 程序员的悲哀是什么?-蚊子的前端博客 微说 | 2025年出生人口的预测-蚊子的前端博客 前端在 LiveKit 中如何获取所有的参与者-蚊子的前端博客
前端项目中如何区分环境-蚊子的前端博客
author · 2022-02-24 · via 蚊子的前端博客

一个项目从开发到上线,大致要经过本地开发、测试环境、预发布环境和正式环境。那么在代码中如何区分这几个环境,然后再与对应的后端接口进行对接呢?

我们经历多几个项目的磨练后,总结出几个区分不同环境的方法。

  1. 从 URL 的域名进行区分;
  2. 构建时传入不同的全局变量;
  3. 容器提前定义好全局变量(一般后端服务使用);

下面我们来一一进行讲解。

沉迷工作

我们先来定义几个环境变量:

enum EnvType {
  LOCAL = 'local', // 本地开发环境
  TESTING = 'testing', // 测试环境
  PRE = 'pre', // 预发布环境
  PRODUCTION = 'production', // 正式环境
}

1. 从 URL 的域名进行区分 #

若不同环境使用不同的域名,最简单的就是从 URL 域名进行区分。我们从 URL 中获取到 hostname 或 origin,然后进行判断。

// 通过url检测环境
const checkUrlHost = (): EnvType => {
  const { hostname } = window.location || { hostname: null };
  if (/test/.test(hostname)) {
    return EnvType.TESTING;
  }
  if (/pre/.test(hostname)) {
    return EnvType.PRE;
  }
  if (/local/.test(hostname)) {
    return EnvType.LOCAL;
  }
  return EnvType.PRODUCTION;
};

注意:不要用整个 URL 地址来进行匹配,因为中间的路径或者携带的参数,可能会干扰到判断。

最开始我们还不能区分域名时,都是在同一个域名里进行开发,然后用不同的路径来区分,不过代码里用的是location.href来区分。然后我们参数里要带着用户的昵称,这个用户的昵称正好有个test的字样。导致项目把这个链接识别成了测试环境,然后就去请求测试环境的接口了。

mixi

2. 构建时传入不同的全局变量 #

现在我们发布项目时,都会先进行构建,然后再把 html 发布出去。那么我们就可以在构建时,把当前要发布的环境对应的变量传进去。

如何传入全局变量,还得看您正在使用的框架,如 React 的脚手架 create-react-app,传入的全局变量必须以REACT_APP_开头;Vue 的脚手架 vue-cli,传入的全局变量必须以VUE_APP_开头。

我们以 create-react-app 为例,使用REACT_APP_SITE_ENV来指定所在的环境。

构建时:

# 本地开发环境
$ REACT_APP_SITE_ENV=local npm run start

# 测试环境
$ REACT_APP_SITE_ENV=testing npm run build

# 预发布环境
$ REACT_APP_SITE_ENV=pre npm run build

# 正式环境
$ npm run build # 不传入
$ REACT_APP_SITE_ENV=production npm run build # 或传入production

代码中获取该全局变量:

// 通过全局变量来检测环境
const getEnv = (): EnvType => {
  const { REACT_APP_SITE_ENV }: any = process.env; // 命令行传入

  // REACT_APP_SITE_ENV只能是EnvType中的值
  // 若没有传入,或者不是这里面的几个值,则返回production
  if (REACT_APP_SITE_ENV) {
    // eslint-disable-next-line no-restricted-syntax
    for (const key in EnvType) {
      const env = (EnvType as any)[key];
      if (env === REACT_APP_SITE_ENV) {
        return REACT_APP_SITE_ENV;
      }
    }
  }
  return EnvType.PRODUCTION;
};

这里我们在构建流水线里指定 REACT_APP_SITE_ENV 为不同的值即可。

不会骗你

3. 容器提前定义好全局变量 #

前端代码一般是只有构建过程,但后端代码(如 nodejs 等),通常是【启动】或者【构建 + 启动】的过程,若有构建过程,则像上面那样在流水线里指定全局变量即可。

而启动这个程序一般是在容器里启动的,而流水线里的全局变量在构建完成后就失效了,留不到启动这一步。因此,若是在容器中启动的程序,您可以在容器里配置好全局变量,这样程序在启动时,就自动能够获取到了。

至于怎么配置,还得看您公司自己的配置。

如我们的配置是:

node_env

4. 总结 #

这里我们主要讲解了下如何在项目中来区分环境,很多开发者还会再额外地定义一些变量或方法,来直接使用,如:

// 定义变量
export const IS_LOCALENV = ENV === EnvType.LOCAL; // 是否是本地环境
export const IS_TESTENV = ENV === EnvType.TESTING; // 是否测试环境
export const IS_PREENV = ENV === EnvType.PRE; // 是否是预发布环境
export const IS_PRODENV = ENV === EnvType.PRODUCTION; // 是否是正式环境

// 定义方法
export const isPro = () => ENV === EnvType.PRODUCTION; // 是否是正式环境

或许未来新的框架或者部署流程,还是出现新的定义环境的方式。