文章来源: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. java引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

  2. 运行 jcontrol 报 libXext.so.6: cannot open shared object file 错误

    需要安装额外库: yum install libXext.x86_64 yum install libXrender.x86_64 yum install libXtst.x86_64

  3. IPC——概述

    现代操作系统下的内存 现在的OS都引入了虚拟内存机制.我们说的内存空间,实际上虚拟内存空间,CPU执行PC指向的命令,PC指向的就是虚拟内存空间地址.虚拟内存机制只不过是OS为我们做了一层虚拟内存地址 ...

  4. Google hacking 语法

    a b c 自动对词进行拆分匹配 拆分标准 空格 "a b c " 把a b c 当成一个整体去查 " a*b" *通配符 里面是一个或者多个 以a开头 b结尾 ...

  5. Mybatis3.1-[tp-30-31]-select_resultMap_关联查询_级联属性封装结果__association定义关联对象封装规则

    笔记要点 出错分析与总结 在全局配置中,映射dao包下的全部: <mapper> <package name="com.dao"/> </mapper ...

  6. can't assign to struct fileds in map

    原文: https://haobook.readthedocs.io/zh_CN/latest/periodical/201611/zhangan.html --------------------- ...

  7. Python经典算法-猴子吃桃-思路分析

    问题: 猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个.第二天早上又将剩下的桃子吃了一半,还是不过瘾又多吃了一个.以后每天都吃前一天剩下的一半再加一个.到第10天刚好剩一个.问猴子第一天 ...

  8. Git----常见工作管理总结

    1.工作流程模式: 首先,可以试图用git push origin branch-name推送自己的修改 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并 如果合并有冲突, ...

  9. eclipse跳转到exitCurrentThread

    1.在使用Eclipse时,用Debug模式运行springboot项目,结果总是在项目快启动成功的时候,跳转到exitCurrentException这个地方 2.方法:Eclipse->[P ...

  10. h5格式化微信 nickname 保留第一个字,其余用*显示

    截取微信nickname中需要注意的是,表情符号和特殊字符,如果你不用正则过滤掉的话,使用slice(0,1)直接截取第一个字符串是不行的,因为表情符号占用两个字节,截取一半,ios会报错,andro ...