我的 Web 应用程序是从 dotnet core 3.0 Angular 模板构建的。我想将第一个版本部署到生产环境中,但我很难为 Angular 应用程序提供服务。我使用 Kestrel 作为网络服务器(它是一个内部网应用程序)。
我已经使用构建 Asp.net 应用程序的 dotnet publish -c Release -o ../app-dist
发布了应用程序,它触发了 ng
来构建一个客户端的生产发布。生成的文件夹结构包括一个 app-dist/wwwroot
文件夹,其中包含一些 Assets ,例如 favicon,还有一个 app-dist/ClientApp/dist/app
文件夹,其中包含 index.html
和编译后的 js
和 css
资源。如果我通过在 app-dist
中运行 dotnet app.dll
来启动应用程序,Kestrel 会启动但无法为客户端应用程序提供服务。我可以从 wwwroot
访问次要 Assets 以及用于用户身份验证的 Razor 页面。
在我的 docker 部署中,尝试访问 https://host/
或 https://host/index.html
时出现以下错误(以及作为 http
等价物):
System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request. Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually. Alternatively you may wish to switch to the Development environment.
当我在我的 macOS 开发系统上的 app-dist
中运行相同的命令时,我得到了同样的错误(在第一次设置 export ASPNETCORE_ENVIRONMENT=production
之后)。
在我的 Startup.cs
中,我有以下内容:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
在我的 csproj 中:
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<SpaRoot>ClientApp\</SpaRoot>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
<BuildServerSideRenderer>false</BuildServerSideRenderer>
</PropertyGroup>
...
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<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' " />
<ItemGroup>
<DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
<DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
我尝试将 Angular index.html
和编译后的文件复制到 wwwroot
以及 ClientApp
文件夹,但都没有生成区别。我还尝试设置 spa.Options.SourcePath = "ClientApp/dist/app";
。 什么似乎配置不正确,或者接下来我应该调查什么?
最佳答案
如果您想在生产环境中更改服务应用程序的目录,您可以通过以下方式在 ConfigureServices
中进行:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
放弃 configuration.RootPath
应更改为您希望的路径。
关于生产环境中的 Asp.net 核心和 Angular : Spa is not being served,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58882081/