同构反应中的实时环境变量

时间:2015-09-25 02:28:28

标签: javascript reactjs webpack flux isomorphic-javascript

我在this repo中基于入门套件松散地构建了一个同构的React应用程序。它使用webpack来构建生产代码。

事实上,我需要将服务器上的一些环境变量的值暴露给浏览器中的客户端代码,而无需重建生产代码。我希望能够更改env变量的值,并让它在下一页刷新客户端的效果,而不必重建任何东西。而且我不想让测试复杂化。

我找到了一些解决方案,其中没有一个很好:

  1. 使用DefinePlugin for webpack将某些环境变量的值硬编码到生产代码中。类似于概述here
  2. 的内容
  3. 构建API只是为了将env变量拉入客户端。
  4. 编写一个特殊的.js文件,该文件位于webpack系统之外。此文件将被模板化,以便在将其提供给客户端之前进行修改。可能要求env变量值存储在' window'中的特殊全局变量中。什么的。
  5. 这些方法存在问题:

    1. REJECTED。这不能做我想做的事。如果我更改了env变量的值,我需要重建代码。
    2. 不必要的复杂。我不需要这个API用于其他任何事情。一个完整的API只是为了提供很少改变的2或3个值?需要复杂性以确保在加载时从API ASAP中提取值。
    3. 最近但是有点粗糙。如果我可以避免它,我真的不想去webpack / React / Flux系统。在窗口对象上创建特殊的全局变量会起作用,但会为测试使用这些全局变量的组件/存储/操作带来复杂性。
    4. 我过去曾做过2和3,但这些解决方案从来没有真正满足于理智。

      有什么建议吗?这似乎应该是一个常见/解决的问题。也许我只是过度思考它,3是可行的方法。

3 个答案:

答案 0 :(得分:2)

锅炉板使用express,您可以使用express'local。

将服务器env变量暴露给客户端
var serverVariable = 'this is a server variable'
app.get('/somelink', function (req, res, next) {
    res.locals.data = {
      FluxStore: { serverlocal: serverVariable  }
   }
   next()
})

然后通过React.renderToString传递本地,这将由FluxStore在客户端上选择。另一种方法,你可以使用数据获取api像falcor,可以通过客户端Action Store通过falcor-http-datasource选择,你不需要快速本地为falcor你用falcor-express和falcor-router构建它

答案 1 :(得分:0)

所以我提出的解决方案非常简单。我只是编写了一行javascript来将值保存到脚本标记内的本地存储中。然后在应用程序启动时从我的flux store读取本地存储。

这是添加到index.html的相关标记:

<script type="text/javascript"><%= config %></script>

这是我在使用模板之前将其拼接到index.html中的字符串:

let configJs = 'localStorage.setItem(\'ADMIN_API\', JSON.stringify(\'' + process.env.ADMIN_API + '/v3/' + '\'));';
const html = template({config: configJs});
res.status(200).send(html);

然后,一旦应用程序启动,我就用它阅读:

import ls from 'local-storage';
....
let api = ls.get('ADMIN_API');

答案 2 :(得分:0)

这使用window中的窗口全局变量来传递值,但为您提供了一个通用接口来访问浏览器和节点上的值。

publicEnv.js

// Env variable to push to the client. Careful on what you put here!
const publicEnv = [
  'API_URL',
  'FACEBOOK_APP_ID',
  'GA_ID'
];

// These 2 lines make sure we pick the value in the right place on node and the browser
const isBrowser = typeof window !== 'undefined';
const base = (isBrowser ? window.__ENV__ : process.env) || {};

const env = {};
for (const v of publicEnv) {
  env[v] = base[v];
}
export default env;

在我的页面的HTML模板文件中:

import publicEnv from 'publicEnv.js';

...

<script>
  window.__ENV__ = ${stringify(publicEnv)};

  // Other things you need here...
  window.__INITIAL_STATE__ = ${stringify(initialState)};
</script>

所以现在我可以在前端和后端获取env变量的值:

import publicEnv from 'publicEnv.js';

...

console.log("Google Analytic code is", publicEnv.GA_ID);

我希望它可以提供帮助。