expressjs并立即使用zeit创建反应应用程序部署

时间:2020-04-04 21:27:55

标签: express aws-lambda create-react-app serverless vercel

我能够部署一个Create-React-App并使用now.sh表达后端 但是问题是它只获得本地路由(我可以从本地路由到/ about,但是在页面重载/刷新时,我收到404错误)。我尝试了几种配置。请我需要帮助。

  "public": false,
  "version": 2,

  "builds": [
    {
      "src": "server/index.js",
      "use": "@now/node",
      "config": {
        "maxLambdaSize": "20mb"
      }
    },
    {
      "src": "package.json",
      "use": "@now/static-build",
      "config": {
        "distDir": "build"
      }
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "/server/index.js"
    },
    {
      "src": "/(.*)",
      "dest": "/build/$1"
    }
  ]
}

1 个答案:

答案 0 :(得分:0)

这听起来像是这里描述的问题-https://create-react-app.dev/docs/deployment/

如果您使用在后台使用HTML5 pushState历史记录API的路由器(例如,具有BrowserHistory的React Router),则许多静态文件服务器将失败。例如,如果您将React Router与/ todos / 42的路由一起使用,则开发服务器将正确响应localhost:3000 / todos / 42,但为上述生产版本提供服务的Express不会。 这是因为当/ todos / 42重新加载页面时,服务器会查找build / todos / 42文件,但找不到该文件。需要将服务器配置为通过提供index.html来响应对/ todos / 42的请求。例如,我们可以修改上面的Express示例,为所有未知路径提供index.html:

app.use(express.static(path.join(__dirname, 'build')));

-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
   res.sendFile(path.join(__dirname, 'build', 'index.html'));
 });

当用户将您的应用安装到设备的主屏幕时,默认配置将成为/index.html的快捷方式。这可能不适用于希望从/提供应用程序的客户端路由器。编辑位于public / manifest.json的Web应用清单,并更改start_url以匹配所需的URL方案,例如:

"start_url": ".",

当我在Zeit上使用404时,这很有帮助-https://itnext.io/fix-404-error-on-single-page-app-with-zeit-now-b35b8c9eb8fb-

为了解决404错误消息,我们必须确保当用户转到非根URL的任何URL(例如www.myapp.com/somethingwww.myapp.com/dashboard/example)时,以前从未加载过我们的Web应用程序,它们被重定向到根URL。一旦他们加载了根URL,就可以将其重定向回他们尝试访问的页面,并且每个人都很高兴!

步骤1-在项目的公用文件夹中,创建另一个package.json文件-

{
  "name": "myapp-spa",
  "version": "1.0.0",
  "scripts": {
    "start": "serve --single --cache=60000"
  },
  "dependencies": {
    "serve": "latest"
  }
}

第2步-配置404页面

现在正在提供文件,如果有人访问非根URL,服务器将查找404.html文件来发送。这是我们重定向它们并将其带到index.html页面的机会。将404.html文件与索引文件放在同一公用文件夹中。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>404 Not Found | My App</title>
</head>
<body>
  <script>
    (function redirect() {
      if (document && document.location) {
        document.location.replace(`/?redirect=${encodeURIComponent(document.location.pathname)}`);
      }
    }());
  </script>
</body>
</html> 

步骤3-为部署做准备

现在,我们有了重定向代码,我们要做的就是向原始myapp / package.json(这不是我们之前创建的文件)中添加一个deploy命令:

{
  "scripts": {
    ...    
    "deploy": "yarn run build && now ./build --name=myapp-spa",
    "start": "react-scripts start",
    "build": "react-scripts build",
    ...
  }
}

甜,现在我们要做的就是调用yarn run deploy,我们的应用程序应该停止获取404错误页面。

步骤4:清理

为了返回该页面,我们最初要求例如myapp.com/something,我们需要将页面重定向到我们在本教程前面设置的?redirect参数。为此,我们需要安装查询字符串库来解析参数。然后,您可以将以下代码添加到您的应用中,该代码应在路由代码加载后加载的位置。

const queryString = require('query-string');

...

const params = queryString.parse(document.location.search);
const redirect = params.redirect; // this would be "abcdefg" if the query was "?redirect=abcdefg"
if (document.location.pathname === '/' && redirect) {
  document.location.assign(`${document.location.origin}/${redirect}`);
}

重要的是,不要在路由代码存储在浏览器中之前,使用以上代码重定向用户。完成后,您的应用应该可以正常运行。

基本上粘贴了整个内容,但请务必检查文章。 显然还有另一种可能的解决方案,可能值得尝试:

{
  ...
  "builds": [
    { "src": "build/**", "use": "@now/static" }
  ],
  "routes": [
    {
      "src": "/(.*)\\.(.*)",
      "dest": "/build/$1.$2"
    },
    {
      "src": "/",
      "dest": "/build/index.html"
    },
    {
      "src": "/(.*)",
      "status": 301, "headers": { "Location": "/" }
    }
  ]