如何在单个 ASP.NET Core 站点上托管多个 React SPA 应用程序?

Bri*_*nga 5 single-page-application reactjs asp.net-core asp-net-core-spa-services

我正在尝试使用 ASP.NET Core 3.1 和最新的 SpaServices 扩展来运行多个 React SPA 应用程序,但在提供静态资产时遇到了问题。我构建的大部分内容来自一个类似的问题:如何为使用 SpaServices 托管的多个 SPA 配置 ASP.net Core 服务器路由,但这与 Angular 和旧版本的 SpaServices 相关。

我的代码有两个 React 应用程序,ClientApp并且AdminApp我已经使用以下启动代码对每个应用程序进行了配置:

app.Map("/client", clientApp =>
{
    clientApp.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";

        if (env.IsDevelopment())
        {
            spa.UseReactDevelopmentServer(npmScript: "start");
        }
    });
});

app.Map("/admin", adminApp =>
{
    adminApp.UseSpa(spa =>
    {
        spa.Options.SourcePath = "AdminApp";

        if (env.IsDevelopment())
        {
            spa.UseReactDevelopmentServer(npmScript: "start");
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

转到/client/admin路由提供正确的 Reactindex.html文件,但链接的捆绑.js文件不会加载。以下是ClientAppSPA的最终索引 HTML 的示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <base href="/client" />
    <title>Client App</title>
  </head>
  <body>
    <h1>Client App</h1>
    <div id="root"></div>
    <script src="/static/js/bundle.js"></script>
    <script src="/static/js/0.chunk.js"></script>
    <script src="/static/js/main.chunk.js"></script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

问题是链接相对于站点的根目录,/static/js/bundle.js需要相对于 React 应用程序的路径。示例文件路径应分别为/client/static/js/bundle.js/admin/static/js/bundle.js

如何让系统将路径写入 index.html 文件以使用静态文件的正确根路径?谢谢。

cmi*_*nus 5

提出一个可能的解决方案。期望构建 SPA 将其构建目录的内容复制到 .NET Core 项目的 wwwroot 文件夹中的一个文件夹中,该文件夹使用与 SPA 将使用的路由相同的名称。在本例中,我们有两个应用程序,guestuserpayinguser。配置函数中的映射将重定向用户请求,以从相应的 wwwroot 文件夹中提取静态文件。

启动.cs

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddSpaStaticFiles();
}
Run Code Online (Sandbox Code Playgroud)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...

   app.UseStaticFiles(new StaticFileOptions()
   {
       FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"))
   });

   app.Map("/guestuser", mappedSpa=>
   {
       mappedSpa.UseSpa(spa =>
       {
           spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions()
           {
               FileProvider =
                   new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/guestuser"))
           };
           spa.Options.SourcePath = "wwwroot/guestuser";
       });
   });

   app.Map("/payinguser", mappedSpa=>
   {
       mappedSpa.UseSpa(spa =>
       {
           spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions()
           {
               FileProvider =
                   new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/payinguser"))
           };
           spa.Options.SourcePath = "wwwroot/payinguser";
       });
   });
}
Run Code Online (Sandbox Code Playgroud)

在 ReactJS 项目中,您需要更新/添加每个项目的homepage文件属性package.json,以便也使用与 wwwroot 文件夹下托管站点的文件夹相同的名称。这将更新生成代码的路径以在其文件引用中使用路径名。

{
  "name": "guest-user",
  "homepage": "guestuser",
  ...
}
Run Code Online (Sandbox Code Playgroud)