- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
react redux realworld.io 应用程序的自述文件位于 https://github.com/gothinkster/react-redux-realworld-example-app说要编辑 src/agent.js
更改 API_ROOT
指向不同的后端 api 实例。我们想要进行设置,以便 API_ROOT
可以由我们运行生产构建的多个环境(例如“staging”和“live”)中不同的环境变量来定义。
我们在 openshift kubernetes 上的容器中运行,遵循 12factor.net 原则,其中代码构建一次,然后通过环境进行推广。我们可以使用单个命令启动新环境,因此我们不想在代码中使用 switch 语句来命名每个环境并对后端进行硬编码 API_ROOT
对于每个环境。相反,我希望能够使用环境变量更改 API_ROOT
在全新环境中运行现有的生产构建容器镜像。指向我们想要测试的正确后端 API。
我查看了许多不同的博客、stackoverflow 答案和官方文档。主要问题是典型的解决方案“烘焙”了 process.env.API_ROOT
构建时的环境变量还有一个开关,可以将所有环境的详细信息硬编码到代码中。这两者都不令人满意,因为我们希望能够在现有容器中获取最新的稳定代码,并使用在那里运行的 API 在新环境中运行它。
到目前为止,我得到的最接近的是编辑代码以呈现 process.env.API_ROOT
进入<script>
将其设置为 window.API_ROOT
的标签多变的。然后检查是否存在,否则在定义 API_ROOT 的 const 时使用默认值。这感觉非常具有侵入性并且有点脆弱,我不清楚在示例应用程序 https://github.com/gothinkster/react-redux-realworld-example-app 中渲染此类脚本标签的最佳位置在哪里。
最佳答案
Issue #578 React-create-app 有一个很好的答案。 tibdex 建议使用 public/env.js
是使用正确的属性生成的,然后在 index.html
中添加:
<script src="%PUBLIC_URL%/env.js"></script>
那个env.js
脚本可以在窗口上设置API_ROOT:
window.env={'API_ROOT':'https://conduit.productionready.io/api'}
和agent.js
可以检查window.env.API_ROOT
否则默认:
function apiRoot() {
if( window.env.API_ROOT !== 'undefined') {
return window.env.API_ROOT
}
else {
return 'https://conduit.productionready.io/api'
}
}
const API_ROOT = apiRoot();
到底如何从环境变量创建该文件,他没有描述,但我能够拥有 npm start
命令生成它。
Moorman 然后建议简单地编写一个服务于 /env.js
的 Express 服务器。否则index.html
:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
const WINDOW_ENV = "window.env={'API_ROOT':'"+process.env.API_ROOT+"'}\n";
app.get('/env.js', function (req, res) {
res.set('Content-Type', 'application/javascript');
res.send(WINDOW_ENV);
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT);
要使其正常工作,请使用 package.json
中的启动脚本。很简单:
"start": "PORT=8080 node server.js",
然后一切正常。如果API_ROOT
在环境变量中定义,然后 server.js
将在 window.env
上生成它和 agent.js
会使用它。
更新 我在 env.js 上使用 res.setHeader("Cache-Control", "public, max-age=300");
设置了五分钟的缓存时间因为设置很少会改变。
更新 我读到了很多关于这个主题的困惑,人们的回答都是“改变你的工作流程以与工具的默认设置保持一致”。 12 因素的想法是使用作为工具应遵循的最佳实践而建立的工作流程,而不是反之亦然。具体来说,标记的生产就绪容器应该可以通过环境变量进行配置并通过环境进行升级。然后是经过调试和测试并实时运行的“同一件事”。在这种单页应用程序的情况下,它要求浏览器访问服务器来加载环境变量,而不是将它们烘焙到应用程序中。恕我直言,这个答案是一种简单明了的方法,能够遵循 12 因素最佳实践。
更新:@mikesparr 在 https://github.com/facebook/create-react-app/issues/982#issuecomment-393601963 给出了这个问题的一个很好的答案。也就是重构package.json来完成启动时生成SPA的webapp工作。我们将此方法视为一种战术解决方法。我们使用的是 saas openshift kubernetes,它会按内存收费。使用 webpack 构建我们的 React 应用程序需要 1.2Gb(并且还在不断增加!)因此,这种将 npm 构建移动到容器启动命令的方法,我们需要为我们启动的每个 pod 分配 1.2Gb,这对于单个页面来说是一笔巨大的额外成本应用程序,而当应用程序预编译时,我们可以使用 128MB 作为内存分配。 webpack 步骤也很慢,因为它是一个大型应用程序。每次启动应用程序时进行构建都会使滚动部署速度减慢很多分钟。如果虚拟机崩溃并且 kubernetes 在新虚拟机上启动替换容器,则需要几分钟才能启动。预编译的应用程序将在几秒钟内启动。所以“启动时webpack”的解决方案对于数万行代码的真实业务应用来说,无论是资源消耗还是速度都不能令人满意。恕我直言,从服务器获取配置脚本的答案是优越的。
关于reactjs - 在不同环境中运行的react.js redux生产构建中将环境变量渲染到浏览器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49975735/
这个问题在这里已经有了答案: How to initialize var? (11 个答案) 关闭 8 年前。 我想给一个变量赋初值 null,并在下一个 if-else block 中赋值,但是编
我正在使用 TypeScript 3.8 编写 JS 和 TS 混合的代码。我写了以下行: export * as Easing from './easing'; 应该是 fair game在 Typ
我需要将 R 代码中的“/”更改为“\”。我有这样的事情: tmp <- paste(getwd(),"tmp.xls",sep="/") 所以我的 tmp是 c:/Study/tmp.xls 我希望
我有个问题。例如我有这个: id truth count 1 1 1 2 1 2 3 0 0 4 1 1 5 1 2 6 1
我正在尝试使用“IN”和“=”来查找一些 bean。我目前正在使用此代码: $ids = array(1,2,3,4); $user = 1; $things = R::find( 'thing'
是否可以在 Xcode 中部署到其他人的手机上?我没有 iPhone,但我想测试我在 friend 手机上制作的应用程序。在我支付 99 美元之前,我想确保这不会造成麻烦。 谢谢。 最佳答案 不会有任
我试图得到一个非常大的数字(超过 unsigned long long int )。所以我把它作为一个字符串,然后一个数字一个数字地转换成整数并使用它。 #include #include int
我在 Rust 中有 C 语言库的绑定(bind),但它们并不完整。 在 C 代码中,我定义了一个简化的宏,如下所示: #define MY_MACROS1(PTR) (((my_struct1
我正在努力解决这个问题。 http://jsfiddle.net/yhcqfy44/ 动画应该自动相对于 滚动到顶部每次出现滚动条时的高度。 我已经写了这个,但没有运气: var hheight =
我正在处理一个将数字作为字符串返回的 JSON API。例如 "12" ,但是,该字段值也可以是非数字的,例如:"-" . 我已将 JSON 数据解析为映射,我想将此字段提取为 elixir 中的整数
我正在尝试编写一个类,将.wav文件转换为.aiff文件作为项目的一部分。 我遇到了几个库Alvas.Audio(http://alvas.net/alvas.audio,overview.aspx)
我想在 Lucene 中将像“New York”这样的“复合词”索引为单个术语,而不是像“new”、“york”那样。这样,如果有人搜索“new place”,则包含“new york”的文档将不会匹
我希望这个解释能让我更好地了解使用宏的优点。 最佳答案 在函数中,所有参数在调用之前都会被评估。 这意味着 or 作为函数不能是惰性的,而宏可以将 or 重写为 if 语句,该语句仅在以下情况下计算分
我有一些看起来像这样的 XML foo ]]> (注意 > 登录 "> foo")和 XSLT 样式表 当我运行xsltproc stylesheet.xs
当我尝试将 Any 转换为 List 时,如下面的示例所示,我得到“Unchecked cast: Any!”到列表'警告。有没有解决此类问题的方法? val x: List = objectOfTy
我正在使用 Python 开发一个简单的爬虫。目的是创建一个 sitemap.xml。(你可以在这里找到真正的 alpha 版本:http://code.google.com/p/sitemappy/
我想知道在 VBScript 中是否可以在多行中中断 If 语句。喜欢: If (UCase(Trim(objSheet.Cells(i, a).Value)) = "YES") Or _ (UCas
for (String item : someList) { System.out.println(item); } 使用“do while”是否等效? 谢谢。 最佳答案 如果列表为空,f
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Split string with delimiters in C 在 C 中将“,”分隔的列表拆分为数组的最佳方法
我有一个如下所示的字符数组: [0, 10, 20, 30, 670] 如何将此字符串转换为整数数组? 这是我的数组 int i=0; size_t dim = 1; char* array = (c
我是一名优秀的程序员,十分优秀!