使用一个S3存储桶托管多个React应用

时间:2019-05-01 05:14:52

标签: reactjs amazon-web-services redirect amazon-s3 deployment

我在我的开发和生产环境中将S3静态网站托管用于React应用程序,并且效果很好。我使用dev-myapp-mycompanyprod-myapp-mycompany之类的存储桶命名方案,并为每个环境使用专用存储桶。

我的团队不断创建需要测试的功能分支,虽然我可以为每个新分支创建一个新存储桶,但我们必须要求在几个冲刺内增加存储桶,然后经常修剪它们。

我想做的是在根目录下有一个单独的存储桶feature-myapp-mycompany,并带有一个简单的index.html,这将提供到当前已部署到该功能存储桶中的每个应用程序的链接。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Feature Bucket</title>
</head>
<body>
    <h1>Feature Branches</h1>
    <ul>
        <li>
            <a href="./feature1/index.html">Feature 1</a>
        </li>
        <li>
            <a href="./feature2/index.html">Feature 2</a>
        </li>
        ...
        <li>
            <a href="./featuren/index.html">Feature n</a>
        </li>
    </ul>
</body>
</html>

为此,存储桶结构看起来像

index.html
    /feature1
        index.html
        /static
    /feature2
        index.html
        /static
    /featuren
        index.html
        /static

我通过AWS cli部署了所有应用程序,因此编写脚本不是挑战。我用类似的东西

  1. npm run build
  2. aws s3 sync ./build s3://%bucket%/%feature% --delete --profile=%profile% --region=us-east-1

将代码发布到存储桶中没问题。这是我卡住的地方:

我的问题: 我已经如上所述部署了代码,但是create-react-app项目从域的根定义了它的静态依赖项。因此,Feature1的index.html具有类似/static/css/main.9fac6334.chunk.css的href。该请求继续进行,并查看了我的存储桶的根,其中每个主功能只有主index.html和一个“目录”。我在主index.html上的链接确实将我带到了正确的应用index.html,但由于它们基于根,因此脚本或CSS引用均无效。

尝试的解决方案: create-react-app允许您在homepage中指定一个package.json选项,该选项用于在应用程序中设置baseURL。我似乎需要的是相对路径,而不是绝对路径,因此我尝试将首页的值设置为"./",然后设置为http://feature-myapp-mycompany.s3-website-us-east-1.amazonaws.com/feature1。在这两种情况下,这些链接都将我带到正确的位置片刻,然后将我重定向到根目录下的主index.html文件。我知道这是可行的,因为在重定向网站之前,我花了几秒钟时间查看了网站的样式和主题。我什至在Chrome的“网络”标签中看到了正确的请求,但是在尝试所有请求之后,我看到它重定向回根目录下的主索引文档。

尝试的解决方案(续): S3静态托管允许重定向规则。我尝试了各种重定向选项,最终使我陷入了导致请求失败的同一资源的无限循环中。我的配置就像

 <RoutingRules>
    <RoutingRule>
    <Condition>
      <KeyPrefixEquals>feature1/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyPrefixWith>feature1/</ReplaceKeyPrefixWith>
    </Redirect>
    </RoutingRule>
  </RoutingRules>

当然,这没有用,因为它将前缀重新写回了相同的值。在没有我的“未尝试的解决方案”的情况下执行相同的重定向规则也无法正常工作,因为该请求不是去到前缀为feature1/的资源,而是去往了根。

我理想的解决方案: 我想将homepage中的package.json选项与一些重定向规则结合起来使用,以将每个应用程序中对静态资源的请求重定向回各自功能分支目录的根目录。例如,对/static/css/main.9fac6334.chunk.css的请求应在feature1目录内,而不是根目录下。

我不惧怕为我们将拥有的许多分支编写脚本,但是我似乎并没有为单个示例子应用找到正确的选项。

在此感谢您在自己的编码冒险中为您提供的帮助和运气。

1 个答案:

答案 0 :(得分:0)

我能够使用this SO post完成我需要做的事情。我们已经在其他环境中使用了Cloudfront发行版,这很容易设置。

以下是我们在这里学到的摘要:

  1. 绝对有可能在同一个存储桶中托管多个React应用
  2. 您可以将每个应用放入您选择的目录/前缀
  3. 使用以下设置为每个指向您的存储桶的应用创建一个Cloudfront发行版

    a。将Feature1放入存储区目录/前缀feature1/

    b。使用原始路径/feature1和默认根对象index.html

    创建分发

    c。骑得干净