ASP.Net Core-IApplicationBuilder.Map,SPA和静态文件

时间:2019-02-07 20:48:07

标签: angular asp.net-core single-page-application

我想使用Asp.Net Core 2.2来托管我的Angular应用-并处理API请求(在/ api上)。

因此,在Startup.cs的“配置”中,我设置了以下内容:

        app.Map("/home", config =>
        {
            config.UseSpa(spa =>
            {
            ...
            });
         });

但是,问题在于,找不到runtime.js,polyfills.js等,因为它们被引用为http://localhost:port/filename.ext

我尝试使用

    config.UseSpaStaticFiles(new StaticFileOptions { RequestPath = "/runtime.js" });

但无济于事。

在ASP.Net Core中以不同的方式为Angular SPA服务的秘诀是什么?

编辑:回答@Michael-我一直在研究最终托管多个应用程序,但我认为这样做可能不值得。我希望能够在开发应用程序时进行“ ng服务”,并在部署时在Asp.Net Core下运行。如果一件事奏效,另一件事就坏了。因此决定暂时将其摆在餐桌上。

1 个答案:

答案 0 :(得分:1)

我将讨论csproj配置,package.json npm配置以及您的Startup.cs代码。

.csproj文件

在csproj文件的底部,您将找到一组在发布应用程序时运行的npm命令。

    <!--...-->
    <PropertyGroup>
        <SpaRoot>ClientApp\</SpaRoot>
    </PropertyGroup>
    <!--...-->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />
    <!--...-->

如果要部署两个应用程序,则需要对所有这些部署说明加倍。

    <!--...-->
    <PropertyGroup> 
        <!--...-->
        <SpaRoot>ClientApp\</SpaRoot>
        <SpaRoot2>ClientApp2\</SpaRoot2>
        <!--...-->
    </PropertyGroup>
    <!--...-->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <!--...-->
    <Exec WorkingDirectory="$(SpaRoot2)" Command="npm install" />
    <!--...-->

配置package.json

在开发过程中,您可能希望使用nodejs托管应用程序。在这种情况下,我们的服务器未托管我们的客户端应用程序。

您将需要设置servepath以匹配您希望客户端应用程序用完的子目录。

   // ...
   "start": "ng serve --servePath /app/ --baseHref /app/",
   // ...

在这一点上,不要忘记为构建更新baseHref。否则,当csproj中的脚本调用build时,它将不会指向正确的basehref。

"build": "ng build --baseHref /app/",

Startup.cs配置

还记得我在开发服务器时不托管客户端的说法吗?我建议在开发时一次运行一个。重要的是,您更新了package.json servePath,以便测试url路径以及所有内容如何链接在一起。

if (env.IsDevelopment())
{
    app.UseSpaStaticFiles();
    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";
        // this is calling the start found in package.json
        spa.UseAngularCliServer(npmScript: "start");
    });
}
else // Production -- in the next section, 

最后,我们有了我们希望它在生产中表现的方式。

// how you had it, we will create a map 
// for each angular client we want to host. 
app.Map(new PathString("/app"), client =>
{
    // Each map gets its own physical path
    // for it to map the static files to. 
    StaticFileOptions clientAppDist = new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(
                Path.Combine(
                    Directory.GetCurrentDirectory(),
                    @"ClientApp\dist"
                )
            )
    };

    // Each map its own static files otherwise
    // it will only ever serve index.html no matter the filename 
    client.UseSpaStaticFiles(clientAppDist);

    // Each map will call its own UseSpa where
    // we give its own sourcepath
    client.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";
        spa.Options.DefaultPageStaticFileOptions = clientAppDist;
    });
});

您可以通过注释掉开发代码并在运行C#代码之前在各自的clientapp文件夹中运行 npm run build 来测试生产设置。只要确保未将生成的dist文件夹检入git repo中即可。

希望您现在对它在开发环境中如何工作,创建构建指令以及如何在生产环境中运行有了更好的了解。