在AWS S3中部署react-redux应用程序

Lak*_*kar 12 amazon-s3 amazon-web-services reactjs react-router react-router-redux

我已经通过很多的这样的堆栈溢出类似的问题了一个.每个人都有不同的角度来部署反应应用程序.

但是这个问题适用于那些使用redux,react-routerreact-router-redux的人.我花了很多时间来确定托管单页面应用程序的正确方法.我正在汇总这里的所有步骤.

我写了下面的答案,其中包含将react-redux app部署到S3的步骤.

Lak*_*kar 22

有一个视频教程,用于将反应应用程序部署到s3.这将很容易在s3上部署应用程序,但我们需要在我们的反应应用程序中进行一些更改.由于很难遵循,我总结为步骤.在这里:

  1. 亚马逊AWS - > s3 - > 创建存储桶.
  2. 添加存储桶策略,以便每个人都可以访问react应用程序.单击创建的存储桶 - > 属性 - > 权限.在该单击编辑存储桶策略.以下是存储桶策略的示例.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Allow Public Access to All Objects",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::<YOUR_BUCKET_NAME>/*"
            }
        ]
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果需要日志,请创建另一个存储桶并在属性中的logs部分下设置存储桶名称.

  4. 你需要在一个文件夹中有一个index.html(这是你的应用程序的起点)和error.html以及所有公共资产(浏览器化的reactJS应用程序和其他CSS,JS,img文件).

  5. 确保您对index.html中的所有这些公共文件都有相对引用.

  6. 现在,导航到属性 - > 静态网站托管.启用网站托管选项.分别将index.htmlerror.html添加到字段中.保存时,您将收到Endpoint.

  7. 最后,部署了react-redux应用程序.您的所有反应路线都将正常运行.但是当你重新加载时,S3将重定向到该特定路由.由于尚未定义此类路由,因此会呈现error.html

  8. 我们需要在静态Web托管下添加一些重定向规则.因此,当404发生时,S3需要重定向到index.html,但这只能通过添加一些像#这样的前缀来完成..现在,当您使用任何反应路由重新加载页面时,而不是转到error.html,将加载相同的URL,但前缀为#!.单击编辑重定向规则并添加以下代码:

    <RoutingRules>
        <RoutingRule>
            <Condition>
                <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
            </Condition>
            <Redirect>
                <HostName> [YOUR_ENDPOINT] </HostName>      
                <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
            </Redirect>
        </RoutingRule>
    </RoutingRules>
    
    Run Code Online (Sandbox Code Playgroud)
  9. 在反应中,我们需要删除该前缀并将路由推送到原始路由.以下是您在反应应用中需要做的更改.我有我的main.js文件,这是反应应用程序的起点.像这样向browserHistory添加一个监听器:

    browserHistory.listen(location => {
      const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
      if (path) {
          history.replace(path);
       }
     });
    
    Run Code Online (Sandbox Code Playgroud)
  10. 上面的代码将删除前缀并将历史记录推送到正确的路由(HTML 5浏览器历史记录).例如:这样的内容http://s3.hosting/#!/event将更改为http://s3.hosting/event.这样做会使react-router能够理解并相应地改变路由.这是我的main.js文件,以便更好地理解:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {createStore, compose, applyMiddleware} from 'redux';
    import {Provider} from 'react-redux'
    import {Router, Route, IndexRoute, browserHistory, useRouterHistory} from 'react-router';
    import {syncHistoryWithStore} from 'react-router-redux';
    import createLogger from 'redux-logger';
    import thunk from 'redux-thunk';
    
    
    const logger = createLogger();
    const createStoreWithMiddleware = applyMiddleware(thunk, logger)(createStore);
    const store = createStoreWithMiddleware(reducers);
    const history = syncHistoryWithStore(browserHistory, store);
    
    
    browserHistory.listen(location => {
      const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
      if (path) {
          history.replace(path);
       }
     });
    
    Run Code Online (Sandbox Code Playgroud)

因此,上传browserified或webpacked react app(app.js文件)将满足所需的需求.由于我发现难以收集所有内容,因此我将所有这些内容汇总为步骤.

  • 我刚刚对此经历了一些挣扎。现在是 2020 年,S3 允许自定义索引和错误解析为 index.html,无需 RoutingRules(第 8 步)以及 React 16.12+ 和 React-Router 5.x。剩下的一个问题是所请求的文档收到 404 或其他 4xx,即使应用程序在其他方面正常工作。如果您设置了 CloudFront,并且您的 CloudFront 域上只有 React SPA,则可以设置错误页面以使用 200 HTTP 响应代码进行响应。 (2认同)