在 AWS S3 中部署 react-redux 应用程序
Deploying react-redux app in AWS S3
我在堆栈溢出中遇到过很多类似的问题 one。每个人对部署 React 应用程序都有不同的看法。
但是这个问题是针对那些使用redux、react-router和react-router-redux[的人的=20=]。我花了很多时间来找出托管单页应用程序的正确方法。我在这里汇总了所有步骤。
我写了下面的答案,其中包含将 react-redux 应用程序部署到 S3 的步骤。
有一个 video 将 React 应用程序部署到 s3 的教程。这对于在 s3 上部署应用程序很容易,但我们需要在我们的 React 应用程序中做一些更改。由于很难遵循,我将总结为步骤。开始了:
- Amazon AWS -> s3 -> 创建存储桶.
添加bucket policy,让所有人都能访问react app。单击 创建的存储桶 -> 属性 -> 权限。在其中单击 编辑存储桶策略 。这是存储桶策略的示例。
{
"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>/*"
}
]
}
如果需要日志,请创建另一个存储桶并在 properties 的 logs 部分下设置存储桶名称。
您需要有一个 index.html(这是您应用程序的起点)和 error.html 和文件夹中的所有 public 资产(浏览器化的 reactJS 应用程序和其他 CSS、JS、img 文件)。
确保你有相对引用所有这些public文件在index.html.
现在,导航至 属性 -> 静态网站托管。启用 网站托管 选项。将 index.html 和 error.html 分别添加到字段中。保存时,您将收到 Endpoint.
最后,您的 react-redux 应用已部署。你所有的反应路线都会正常工作。但是当您 reload 时,S3 将重定向到该特定路由。由于尚未定义此类路由,因此它呈现 error.html
我们需要在静态虚拟主机下添加一些重定向规则。所以,当404发生时,S3需要重定向到index.html,但这只能通过添加一些前缀来完成,比如#! .现在,当您使用任何 React 路由重新加载页面时,不会转到 error.html,而是会加载相同的 url,但前缀为 #!。单击编辑重定向规则并添加以下代码:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<HostName> [YOUR_ENDPOINT] </HostName>
<ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
在react中,我们需要去掉那个前缀,把路由推送到原来的路由。这是您需要在 React 应用程序中进行的更改。我有我的 main.js 文件,这是反应应用程序的起点。像这样向 browserHistory 添加监听器:
browserHistory.listen(location => {
const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
if (path) {
history.replace(path);
}
});
以上代码会去掉前缀并将历史推送到正确的路由(HTML 5 浏览器历史)。例如:像这样的 http://s3.hosting/#!/event will change to 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);
}
});
因此上传浏览器化或网络打包的 React 应用程序(app.js 文件)将满足要求。由于我发现很难收集所有的东西,所以我将所有这些汇总为步骤。
您可以通过将第 8 个配置编辑为
来忽略第 9 个步骤
<ReplaceKeyPrefixWith>/</ReplaceKeyPrefixWith>
并在 react-router 中使用浏览器历史记录
如果有人遇到这个post,并且由于history.listen函数中的无限循环,解决方案不起作用;对我来说,解决方案是为 history.replace(path) 调用添加一个小的超时。所以它看起来像这样:
history.listen(location => {
const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
if (path) {
setTimeout(() => {
history.replace(path);
}, 100);
}
});
我在堆栈溢出中遇到过很多类似的问题 one。每个人对部署 React 应用程序都有不同的看法。
但是这个问题是针对那些使用redux、react-router和react-router-redux[的人的=20=]。我花了很多时间来找出托管单页应用程序的正确方法。我在这里汇总了所有步骤。
我写了下面的答案,其中包含将 react-redux 应用程序部署到 S3 的步骤。
有一个 video 将 React 应用程序部署到 s3 的教程。这对于在 s3 上部署应用程序很容易,但我们需要在我们的 React 应用程序中做一些更改。由于很难遵循,我将总结为步骤。开始了:
- Amazon AWS -> s3 -> 创建存储桶.
添加bucket policy,让所有人都能访问react app。单击 创建的存储桶 -> 属性 -> 权限。在其中单击 编辑存储桶策略 。这是存储桶策略的示例。
{ "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>/*" } ] }
如果需要日志,请创建另一个存储桶并在 properties 的 logs 部分下设置存储桶名称。
您需要有一个 index.html(这是您应用程序的起点)和 error.html 和文件夹中的所有 public 资产(浏览器化的 reactJS 应用程序和其他 CSS、JS、img 文件)。
确保你有相对引用所有这些public文件在index.html.
现在,导航至 属性 -> 静态网站托管。启用 网站托管 选项。将 index.html 和 error.html 分别添加到字段中。保存时,您将收到 Endpoint.
最后,您的 react-redux 应用已部署。你所有的反应路线都会正常工作。但是当您 reload 时,S3 将重定向到该特定路由。由于尚未定义此类路由,因此它呈现 error.html
我们需要在静态虚拟主机下添加一些重定向规则。所以,当404发生时,S3需要重定向到index.html,但这只能通过添加一些前缀来完成,比如#! .现在,当您使用任何 React 路由重新加载页面时,不会转到 error.html,而是会加载相同的 url,但前缀为 #!。单击编辑重定向规则并添加以下代码:
<RoutingRules> <RoutingRule> <Condition> <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName> [YOUR_ENDPOINT] </HostName> <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith> </Redirect> </RoutingRule> </RoutingRules>
在react中,我们需要去掉那个前缀,把路由推送到原来的路由。这是您需要在 React 应用程序中进行的更改。我有我的 main.js 文件,这是反应应用程序的起点。像这样向 browserHistory 添加监听器:
browserHistory.listen(location => { const path = (/#!(\/.*)$/.exec(location.hash) || [])[1]; if (path) { history.replace(path); } });
以上代码会去掉前缀并将历史推送到正确的路由(HTML 5 浏览器历史)。例如:像这样的 http://s3.hosting/#!/event will change to 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); } });
因此上传浏览器化或网络打包的 React 应用程序(app.js 文件)将满足要求。由于我发现很难收集所有的东西,所以我将所有这些汇总为步骤。
您可以通过将第 8 个配置编辑为
来忽略第 9 个步骤 <ReplaceKeyPrefixWith>/</ReplaceKeyPrefixWith>
并在 react-router 中使用浏览器历史记录
如果有人遇到这个post,并且由于history.listen函数中的无限循环,解决方案不起作用;对我来说,解决方案是为 history.replace(path) 调用添加一个小的超时。所以它看起来像这样:
history.listen(location => {
const path = (/#!(\/.*)$/.exec(location.hash) || [])[1];
if (path) {
setTimeout(() => {
history.replace(path);
}, 100);
}
});