问题 #578 https://github.com/facebook/create-react-app/issues/578React-create-app 有一个很好的答案。tibdex建议使用public/env.js
是用正确的属性生成的,然后在index.html
add:
<script src="%PUBLIC_URL%/env.js"></script>
That env.js
脚本可以在窗口上设置 API_ROOT:
window.env={'API_ROOT':'https://conduit.productionready.io/api'}
And 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
else 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
会使用它。
update我在 env.js 上设置了五分钟的缓存时间res.setHeader("Cache-Control", "public, max-age=300");
因为设置很少会改变。
update我读到了很多围绕这个主题的困惑,人们的回答都是“改变你的工作流程以与工具的默认设置保持一致”。 12 因素的想法是使用作为工具应遵循的最佳实践而建立的工作流程,而不是反之亦然。具体来说,标记的生产就绪容器应该可以通过环境变量进行配置并通过环境进行升级。然后是经过调试和测试并实时运行的“同一件事”。在这种单页应用程序的情况下,它要求浏览器访问服务器来加载环境变量,而不是将它们烘焙到应用程序中。恕我直言,这个答案是一种简单明了的方法,能够遵循 12 因素最佳实践。
update:@mikesparr 对此问题给出了一个很好的答案https://github.com/facebook/create-react-app/issues/982#issuecomment-393601963 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”的解决方案对于数万行代码的真实业务应用来说,无论是资源消耗还是速度都不能令人满意。恕我直言,这个从服务器获取配置脚本的答案是更好的。