Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 同构反应中的活环境变量_Javascript_Reactjs_Webpack_Flux_Isomorphic Javascript - Fatal编程技术网

Javascript 同构反应中的活环境变量

Javascript 同构反应中的活环境变量,javascript,reactjs,webpack,flux,isomorphic-javascript,Javascript,Reactjs,Webpack,Flux,Isomorphic Javascript,我已经构建了一个同构的React应用程序,它松散地基于中的初学者工具包。它使用webpack来构建生产代码 问题是,我需要将服务器上的一些环境变量的值公开给浏览器中的客户机代码,而无需重新生成生产代码。我希望能够更改env变量的值,并使其在下一页刷新时对客户端产生影响,而无需重建任何内容。我不想为了完成它而使测试复杂化 我找到了一些解决方案,但没有一个是好的: 使用DefinePlugin for webpack将某些环境变量的值硬编码到生产代码中。类似于所概述的 构建一个API,将环境变量拉入

我已经构建了一个同构的React应用程序,它松散地基于中的初学者工具包。它使用webpack来构建生产代码

问题是,我需要将服务器上的一些环境变量的值公开给浏览器中的客户机代码,而无需重新生成生产代码。我希望能够更改env变量的值,并使其在下一页刷新时对客户端产生影响,而无需重建任何内容。我不想为了完成它而使测试复杂化

我找到了一些解决方案,但没有一个是好的:

  • 使用DefinePlugin for webpack将某些环境变量的值硬编码到生产代码中。类似于所概述的
  • 构建一个API,将环境变量拉入客户端
  • 在webpack系统之外编写一个特殊的.js文件。该文件将被模板化,以便在提供给客户端之前对其进行修改。可能需要将env变量值存储在“窗口”或其他位置的特殊全局变量中
  • 这些方法的问题:

  • 拒绝。这根本不是我想要的。如果更改env变量的值,则需要重新生成代码
  • 不必要的复杂。除此之外,我不需要这个API。一个完整的API只提供2或3个很少改变的值?需要复杂度来确保加载时尽快从API中提取值
  • 最近的,但有点恶心。如果可以避免的话,我真的不想走出网页/反应/流量系统。在window对象上创建特殊的全局变量是可行的,但会增加测试使用这些全局变量的组件/存储/操作的复杂性
  • 我在过去做过2和3,但从没有对这些解决方案感到满意


    有什么建议吗?似乎这应该是一个常见/已解决的问题。也许我想得太多了,3才是正确的选择。

    锅炉板使用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将拾取该数据。另一种方法,您可以使用falcor之类的数据获取api,它可以由客户端操作存储通过falcor http datasource拾取,您不需要falcor的express local,您可以使用falcor express和falcor router构建它,所以我提出的解决方案相当简单。我只编写了一行javascript,将值保存到脚本标记内的本地存储中。然后在应用程序启动时从我的flux应用商店读取本地存储

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

    <script type="text/javascript"><%= config %></script>
    
    然后,当应用程序启动时,我读到:

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

    这将使用
    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>
    

    我希望它能有所帮助。

    3似乎是最好的选择。
    import publicEnv from 'publicEnv.js';
    
    ...
    
    <script>
      window.__ENV__ = ${stringify(publicEnv)};
    
      // Other things you need here...
      window.__INITIAL_STATE__ = ${stringify(initialState)};
    </script>
    
    import publicEnv from 'publicEnv.js';
    
    ...
    
    console.log("Google Analytic code is", publicEnv.GA_ID);