ASP.NET Core 3.1 Angular Web App 在 Windows 上构建和运行,但在 Mac OSX 和 Docker 上失败

Posted

技术标签:

【中文标题】ASP.NET Core 3.1 Angular Web App 在 Windows 上构建和运行,但在 Mac OSX 和 Docker 上失败【英文标题】:ASP.NET Core 3.1 Angular Web App builds and runs on Windows but fails on Mac OSX and in Docker 【发布时间】:2020-10-02 12:49:06 【问题描述】:

我在 Windows 10 机器上使用 Visual Studio 2019 中的 Angular 模板创建了一个基本的 ASP.NET Core 3.1 Web 应用程序。整个项目源码位于这里

git clone https://erotavlas-1@bitbucket.org/dev-issues/webclient.git

当我在 Windows 机器上构建和运行它时,它可以正常工作并在 Microsoft Edge 浏览器中正确启动。

但是,当我将项目复制到我的 Macbook (OS Catalina) 并将其构建到 docker 映像中时,它没有这样做。这些是构建结束时的消息

  > webclient@0.0.0 build /src/WebClient/ClientApp
  > ng build "--prod"

  Browserslist: caniuse-lite is outdated. Please run next command `npm update`
  Killed
  npm ERR! code ELIFECYCLE
  npm ERR! errno 137
  npm ERR! webclient@0.0.0 build: `ng build "--prod"`
  npm ERR! Exit status 137
  npm ERR! 
  npm ERR! Failed at the webclient@0.0.0 build script.
  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

  npm ERR! A complete log of this run can be found in:
  npm ERR!     /root/.npm/_logs/2020-06-12T13_22_34_364Z-debug.log
/src/WebClient/WebClient.csproj(40,5): error MSB3073: The command "npm run build -- --prod" exited with code 137.
The command '/bin/sh -c dotnet publish "WebClient.csproj" -c Release -o /app/publish' returned a non-zero code: 1

然后我认为项目可能有问题,所以我尝试在 Visual Studio for Mac 中打开它,它构建得非常好,没有错误。但是当我运行它时,它会在 Visual Studio 输出中生成以下输出

npm ERR! A complete log of this run can be found in:

)
---> System.InvalidOperationException: The NPM script 'start' exited without indicating that the Angular CLI was listening for requests. The error output was: sh: /Users/username/Documents/DEV/WebClient/WebClient/ClientApp/node_modules/.bin/ng: Permission denied

npm ERR! code ELIFECYCLE

npm ERR! errno 126
npm ERR! webclient@0.0.0 start: `ng serve "--port" "59704"`
npm ERR! Exit status 126
npm ERR! 
npm ERR! Failed at the webclient@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:


---> System.IO.EndOfStreamException: Attempted to read past the end of the stream.
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.StartAngularCliServerAsync(String sourcePath, String npmScriptName, ILogger logger)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.StartAngularCliServerAsync(String sourcePath, String npmScriptName, ILogger logger)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.<>c.<Attach>b__2_0(Task`1 task)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.SpaServices.Extensions.Util.TaskTimeoutExtensions.WithTimeout[T](Task`1 task, TimeSpan timeoutDelay, String message)
   at Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task`1 baseUriTask, CancellationToken applicationStoppingToken, Boolean proxy404s)
   at Microsoft.AspNetCore.Builder.SpaProxyingExtensions.<>c__DisplayClass2_0.<<UseProxyToSpaDevelopmentServer>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

浏览器打开并显示消息

An unhandled exception occurred while processing the request.
AggregateException: One or more errors occurred. (One or more errors occurred. (The NPM script 'start' exited without indicating that the Angular CLI was listening for requests. The error output was: sh: /Users/username/Documents/DEV/WebClient/WebClient/ClientApp/node_modules/.bin/ng: Permission denied

npm ERR! code ELIFECYCLE

npm ERR! errno 126
npm ERR! webclient@0.0.0 start: `ng serve "--port" "59704"`
npm ERR! Exit status 126
npm ERR!
npm ERR! Failed at the webclient@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:

))

当我尝试在 Windows 上构建 docker 映像时,它也失败了。

对此的任何指导表示赞赏。

【问题讨论】:

【参考方案1】:

我使用我的 Mac 对此问题进行了一些调查。事实证明,经过一些修改,我可以成功构建和运行 docker 容器。您可以查看我的详细代码更改here。

我可以通过运行以下命令在 Mac 上成功运行它:

dotnet build
cd WebClient
dotnet run

1。从 csproj 中删除 PublishRunWebpack

当我尝试运行 Dockerfile 来构建映像时,我看到了与所描述的问题相同的错误,这不知怎么把我带到了 this article 并检查了 WebClient.csproj 中的 PublishRunWebpack 任务:

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
  <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:s-s-r -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />

  <!-- Include the newly-built files in the publish output -->
  <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>

PublishRunWebpack任务会在发布应用时运行(即dotnet publish ...),因此不会在开发中触发(即dotnet run),提示npm run build -- --prod在构建时失败Docker 映像或 npm 甚至在您的构建阶段都不存在。

2。在 Dockerfile 中添加构建阶段(用于节点)

因此,我从 WebClient.csproj 中删除了该构建目标,并在 Dockerfile 中添加了一个构建阶段来构建 Angular Web 应用程序。 以下代码段仅显示节点构建阶段和here is the complete Dockerfile。

### some steps to build and publish the dotnet app...

#Angular build
FROM node as nodebuilder

# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY WebClient/ClientApp/package.json /usr/src/app/package.json
RUN npm install
# (use 8.3.14 as I saw package.json is using this)
RUN npm install -g @angular/cli@8.3.14 --unsafe

# add app
COPY WebClient/ClientApp/. /usr/src/app

## this is the original step stated in the .csproj file
RUN npm run build -- --prod

## or, you can use the following command if you enable server-side prerendering
# RUN npm run build:s-s-r -- --prod

### some steps to copy the Angular web app to ClientApp/dist/...

3。修复 Angular 构建错误

当我再次开始构建 Docker 镜像时,我遇到了以下问题,并从 Stack Overflow 获得了解决方案:

作业名称“..getProjectMetadata”不存在:https://***.com/a/60101207/13742790 找不到插件“proposal-numeric-separator”:https://***.com/a/60781705/13742790

构建并运行

之后,我就可以在http://localhost:8080成功构建并运行Docker镜像了:

docker build . -t web-client
docker run -p 8080:80 -d web-client

仪表板显示应用正在运行:

【讨论】:

"我从 WebClient.csproj 中删除了构建目标" 这是 csproj 的 XML 中的整个“目标”节点吗?我还使用了第 2 步中的 dockerfile 并测试了应用程序,但从未出现第 3 步中描述的任何错误。这是最终的 dockerfile 吗? @erotavlas 是的,您需要删除 PublishRunWebpack 节点。删除该节点将跳过构建 Angular 应用程序。因此,在 Dockerfile (this one) 中,我定义了一个阶段(从第 19-40 行开始)来构建 Angular 客户端应用程序。

以上是关于ASP.NET Core 3.1 Angular Web App 在 Windows 上构建和运行,但在 Mac OSX 和 Docker 上失败的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 3.1 Angular Web App 在 Windows 上构建和运行,但在 Mac OSX 和 Docker 上失败

如何使用 ASP.NET Core 3.1 将 Android 应用程序集成到 Identity Server 以进行身份​​验证?

ASP.NET Core--.net core 3.1 部署到 IIS

深入研究 Angular 和 ASP.NET Core 3.0

asp.net core + angular2 JWT 承载

ASP.NET Core和Angular 2双剑合璧