文章来源:https://www.freecodecamp.org/news/how-to-implement-runtime-environment-variables-with-create-react-app-docker-and-nginx-7f9d42a91d70/

通常来讲,我们在使用docker build Nodejs容器时,代码中就有预设一些参数,作为各个环境的环境变量,例如数据库的URL等

但作为前端应用react,在编译了代码后,生成的代码使用Nginx代理在浏览器中运行,那么注意,在浏览器中没有环境变量这个东西,所以原本在后台Nodejs服务器中的获取环境变量的方案,在前端React项目中不可用

实际上,process在浏览器环境都不存在,它是特定于Nodejs的,在转换过程中,webpack进程会使用process.env给定的字符串值替换所有出现的内容,这就说明,前端React项目想要获取参数只能在docker build期间进行配置。

找到一个解决方案,当我们启动容器时,是可以注入环境变量的特定时刻,然后我们可以从容器内部读取环境变量。我们可以将它写入一个文件,该文件可以通过Nginx(或者是React应用程序)提供服务,它使用<script>标签导入至index.html

所以在那一刻,我们可以运行一个bash脚本,创建一个JavaScript文件,将环境变量被指定为全局Window对应的属性,将它注入至浏览器,以方便我们的应用在全局可用

创建项目,并创建有内容的.env文件

# Generate React App
create-react-app react-nginx-variable
cd react-nginx-variable # Create default environment variables that we want to use
touch .env
echo "API_URL=https//default.dev.api.com" >> .env

创建脚本env.sh

#!/bin/bash

# Recreate config file
rm -rf ./env-config.js
touch ./env-config.js # Add assignment
echo "window._env_ = {" >> ./env-config.js # Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
fi # Read value of current variable if exists as Environment variable
value=$(printf '%s\n' "${!varname}")
# Otherwise use value from .env file
[[ -z $value ]] && value=${varvalue} # Append configuration property to JS file
echo " $varname: \"$value\"," >> ./env-config.js
done < .env echo "}" >> ./env-config.js

处理的流程

(1)删除旧文件,并创建一个新文件。
(2)编写JS代码,打开对象文字并将其分配给全局窗口对象。
(3)读取.env文件的每一行并分成键/值对。
(4)查找环境变量,如果设置,则使用其值,否则,使用.env文件中的默认值。
(5)将它附加到我们分配给全局窗口对象的对象
(6)关闭对象文字

然后我们在index.html中<head>中添加以下脚本

<script src="%PUBLIC_URL%/env-config.js"></script>

且在首页代码App.js中写一行代码

<p>API_URL: {window._env_.API_URL}</p>

然后react项目的package.json中

  "scripts": {
"dev": "chmod +x ./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build": "react-scripts build'"
},

然后在本机可以使用yarn dev来运行项目,应该可以看到界面上已经成功获取到.env文件中的变量

当然,我们也可以修改React项目中的.env文件中的内容,从而在本地来运行看到结果

但当成到SIT/UAT/PROD环境时,使用docker-compose方式运行项目时

version: "3.2"
services:
web:
image: weschen/workbench:20190627.2
ports:
- "5000:80"
environment:
- "API_URL=weschen.production.example.com"

页面中显示的,即是weschen.production.example.com

源码:https://github.com/ChenWes/react-nginx-variable

docker-compose 布署应用nginx中的create-react-app应用获取环境变量的更多相关文章

  1. 在 .NET Core 5 中集成 Create React app

    翻译自 Camilo Reyes 2021年2月22日的文章 <Integrate Create React app with .NET Core 5> [1] Camilo Reyes ...

  2. JAVA中常用需要设置的三个环境变量(JAVA_HOME、CLASSPATH、PATH)

    JAVA中常用需要设置的三个环境变量: JAVA_HOME.CLASSPATH.PATH (一) 配置环境变量:(相对路径) 1. JAVA_HOME=x:/jdk1.6.0 2. 用%JAVA_HO ...

  3. Apache/Nginx为PHP设置、添加$_SERVER服务器环境变量

    在PHP开发中为了区分线上生产环境还是本地开发环境, 如果我们能通过判断$_SERVER['RUNTIME_ENVIROMENT']为 'DEV'还是'PRO'来区分该多好, 可惜的是$_SERVER ...

  4. Titanium系列--安装Titanium Studio 中的Android SDK,JDK以及环境变量的配置(二)

    Ubuntu安装配置JDK 1.先去 Oracle下载Linux下的JDK压缩包,我下载的是jdk-8u25-linux-x64.tar.gz文件,下好后直接解压 Step1:# 将解压好的jdk1. ...

  5. saltstack在jianja模板中,执行salt函数来获取某些变量的值,并且将配置写入到配置文件中?

    问题描述: 通过saltstack的jinja模板方式,可以将变量的值写入到配置文件,即动态获取的方式.这里介绍,通过执行salt函数来获取值的方式. 演示: 1.通过在sls中,增加jinja的模板 ...

  6. 在Win7中修改 系统盘中 “系统” - “用户” 的环境变量映射关系

    1.在此列表中,选中对应登录帐号 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList 2.将Prof ...

  7. create react app 项目部署在Spring(Tomcat)项目中

    网上看了许多,大多数都是nginx做成静态项目,但是这样局限性太多,与Web项目相比许多服务端想做的验证都很麻烦,于是开始了艰难的探索之路,终于在不经意间试出来了,一把辛酸... 正常的打包就不说了. ...

  8. docker必须要sudo,但是sudo的话,又获得不了环境变量怎么办?

    方法1 sudo usermod -a -G docker $USER 方法2 sudo -E docker-compose ... 在sudo后面加上-E

  9. webpack中使用DefinePlugin来传递构建的环境变量给源代码使用

    最近在思考如何提供一种前后端开发功能测试既高效又安全的方案,因为对于我平时的项目是前后端同时进行的,后端我已经有了完备的权限管理,前端不能的角色会有不同的访问数据权限.而在vue前后端分离开发情况下, ...

随机推荐

  1. git 把其他分支上的文件拿来覆盖本地

    1:git checkout oldversion -- 文件地址 2: 一个分支从某个角度讲也像是一次commmit,也是有向无环图的一个点

  2. SQL SERVER-Login搬迁脚本

    USE master GO IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimal GO CREATE PR ...

  3. centos7创建共享文件夹

    0.检查是否已经安装samba rpm -qi samba 1.未安装,安装samba, 如果已安装,请忽略: yum -y install samba samba-client 2.共享一个目录,使 ...

  4. Java枚举的小例子

    有一次工作中,要根据多个参数确定一个值(车辆事件),确定一个值需要的参数大部分的属性名称是相同的,少部分是独有的,但是参数的值几乎都是不同的: 因为参数太多,if-else写起来就太不优雅了,可以参考 ...

  5. 实例演示MaxTenuringThreshold参数及阈值动态调整策略

    在上一次[https://www.cnblogs.com/webor2006/p/11031563.html]学习了一个新的JVM对象晋升到老年代的参数“MaxTenuringThreshold”,它 ...

  6. Java原子类--框架

    根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类. 1. 基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;2. 数组类型: AtomicIn ...

  7. mysql类型为varchar double类型字符串求和多出多个小数

    -- 错误 SELECT SUM(price) FROM m_user -- 正确 SELECT TRUNCATE ( ) FROM m_user u; -- 正确 SELECT ) ) FROM m ...

  8. django命令行安装和卸载

    1. 在dos命令行中输入 pip 如下命令进行安装: 安装最新的版本的 Django 命令如下: pip install django 安装 指定版本的 Django 命令如下: pip insta ...

  9. volatile相关知识

    C中的volatile变量是什么? 回答: 的易失性的关键字是类型限定符防止从编译器optimization.According至C标准的对象,具有挥发性限定类型可以以实施方式未知进行修改或具有其他未 ...

  10. linux 忘记root密码怎么处理。

    这个是不少人纠结的地方.一台服务器,太久没使用,然后又没有一个文件txt,excel记录那些密码相关的东西.所以导致很多信息忘记了. 参考文章:https://blog.csdn.net/cranky ...