运行npm build构建基于create-react-app的项目后,在运行时读取环境变量

5
我刚接触React,并打算部署一个React项目。该项目是由create-react-app创建的,然后通过“npm build”构建生产代码并由Express托管。
在项目中,有一些对API服务器的fetch调用,该URL希望能够进行配置。在开发过程中,我可以通过在文件.env中设置环境变量(例如,REACT_APP_API_URL = http://somewhere/)并在代码中导入来实现这一点。
然而,在运行“npm build”之后,这些环境变量似乎变得静态了,即使在启动服务器时执行类似于“REACT_APP_API_URL = http://otherserver/ node express_server.js”的操作也无法再次更改它们。
我想问一下是否有任何方法可以在“npm build”之后为代码提供一些配置,最好可以从文件或.env中获取,从环境变量中获取也可以。谢谢。
2个回答

3

环境变量在构建过程中嵌入到文件中,因此在调用react-scripts build时,需要为它们分配适当的值。

示例

"scripts": {
  "start": "cross-env REACT_APP_API_URL=http://somewhere/ react-scripts start",
  "build": "cross-env REACT_APP_API_URL=http://otherserver/ react-scripts build",
}

谢谢您的快速回复,那么似乎在 react-scripts build 完成后没有导入或更改配置的方法? - wing999
@wing999 很遗憾,这是不可能的。你可以让服务器将环境变量注入到HTML文件中,然后在浏览器加载JavaScript包时读取这些全局变量,但是没有办法像那样动态地更改实际的JavaScript文件。 - Tholle
1
似乎我需要找到其他解决方法。也许可以在Express中设置代理,使API服务器的URL可配置。 - wing999
@wing999 您的使用情况是什么?您没有运行构建脚本的选项,用于每个不同的域名运行一次吗? - Tholle
这确实是其中一个选项,但我只是想看看是否有可能避免重新构建所有内容。也许是因为我是一个老派的程序员,认为更改某些配置的风险比重建事物要小。 - wing999

0
我发现了一种从后端获取自定义 conf.json 文件并在 React 应用程序的 index.tsx 文件中应用参数的方法,如下所示:
const CURR_ENV = process.env.REACT_APP_ENV;

console.log('ENV: ' + CURR_ENV)

if (CURR_ENV === 'prod') {
    console.log("fetching conf.json ...")
    fetch('conf.json')
        .then(response => response.json())
        .then(data => {
            console.log("data=" + JSON.stringify(data))
            const amplify = data['amplify'];
            console.log("amplify=" + JSON.stringify(amplify))
            Auth.configure(amplify);
            Auth.configure(amplify);

            const backendUrl = data['backendUrl'];
            console.log("backendUrl=" + JSON.stringify(backendUrl))
            localStorage.setItem('backend_url', backendUrl);
            console.log("successfully configured amplify and apigw")
        })
        .catch(error => console.error(JSON.stringify(error)))
}
else {
    localStorage.setItem('backend_url', process.env.REACT_APP_BACKEND_URL?process.env.REACT_APP_BACKEND_URL:"");
    Amplify.configure(awsmobile);
    Auth.configure(awsmobile);
}

ReactDOM.render(
  <Router>
      <div>
          <Route path="/" component={App}/>
      </div>
  </Router>,
  document.getElementById('root')
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接