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

时间:2016-09-30 03:16:21

标签: amazon-web-services reactjs amazon-s3 react-router react-router-redux

我在堆栈溢出中遇到了很多类似的问题,如one。每个人都有不同的角度来部署反应应用程序。

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

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

3 个答案:

答案 0 :(得分:20)

有一个video教程,用于将反应应用程序部署到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>/*"
            }
        ]
    }
    
  3. 如果您需要日志,请在属性中的日志部分下创建另一个存储桶并设置存储桶名称。

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

  5. 确保您对 index.html 中的所有公开文件有相对引用。

  6. 现在,导航至属性 - &gt; 静态网站托管。启用网站托管选项。分别在字段中添加 index.html error.html 。保存时,您将收到端点

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

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

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

    browserHistory.listen(location => {
      const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
      if (path) {
          history.replace(path);
       }
     });
    
  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);
       }
     });
    
  11. 因此,上传browserified或webpacked react应用程序(app.js文件)将满足所需的需求。由于我发现难以收集所有内容,因此我将所有这些内容汇总为步骤。

答案 1 :(得分:0)

如果有人偶然发现了此帖子,并且由于history.listen函数中的无限循环而导致解决方案不起作用;对我来说,解决方案是为history.replace(path)调用添加一个小的超时。所以看起来像这样:

    history.listen(location => {
      const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
        if (path) {
          setTimeout(() => {
            history.replace(path);
          }, 100);
        }
      });

答案 2 :(得分:-2)

您可以通过将第8个配置编辑为

来忽略第9步
 <ReplaceKeyPrefixWith>/</ReplaceKeyPrefixWith>

并在react-router

中使用browserHistory