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

ric*_*ver 5 deployment redirect amazon-s3 amazon-web-services reactjs

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

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

我想要做的是在根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>
Run Code Online (Sandbox Code Playgroud)

为此,桶结构看起来像

index.html
    /feature1
        index.html
        /static
    /feature2
        index.html
        /static
    /featuren
        index.html
        /static
Run Code Online (Sandbox Code Playgroud)

我通过 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. 此请求会查看我的存储桶的根目录,其中index.html每个功能只有主目录和“目录”。我的主链接index.html确实将我带到了正确的应用程序,index.html但没有任何脚本或 css 引用是有效的,因为它们基于根。

尝试的解决方案: create-react-app 允许您homepage在package.json用于设置应用程序中的 baseURL 中指定一个选项。我似乎需要的是相对路径,而不是绝对路径,所以我尝试将 homepage 的值设置为"./",然后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>
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用,因为它正在将前缀重写回相同的值。在没有我尝试的解决方案的情况下执行相同类型的重定向规则也不起作用,因为请求不会发送到带有前缀的资源feature1/,而是发送到根。

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

我不害怕为我们将拥有的许多分支编写脚本,但我似乎无法为单个示例子应用程序提供正确的选项。

提前感谢您的帮助,并祝您在自己的编码冒险中好运。

ric*_*ver 5

我能够使用这篇 SO 帖子来完成我需要做的事情。我们已经在其他环境中使用了 Cloudfront 发行版,而且设置起来非常容易。

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

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

    A。将feature1放入bucket目录/前缀中feature1/

    b. /feature1使用原始路径和默认根对象创建分配index.html

    C。干净利落地骑走