2

I have an Angular7 app built has ServerSide Rendering (with angular universal) that is wrapped inside a .Net Core application and I'm unable to make the deploy to Azure App Service.

When I do the publish through Visual Studio, all the build is done correctly, creating the dist folder with

/dist
   /browser
   /server
   server.js

but then the publish fails when copying the files from node_modules to the obj folder.

Unable to copy file "C:\Work\Repos\website\msSite\ClientApp\node_modules.cache\terser-webpack-plugin\content-v2\sha512\8f\66\f49339db5275a13ef193d46e9a87afb770d173d93548f10a78 a493694695c748602741bec0e9f1f2c503f2d6e48f8034f4cc29da83d689f2f631af6938ba" to "C:\Work\Repos\we bsite\msSite\obj\Release\netcoreapp2.1\PubTmp\Out\ClientApp\node_modules.cache\terser-webpack-plugin\content-v2\sha512\8f\66\f49339db5275a13ef193d46e9a87afb770d173d93548f10a78a493694695c748602741bec0e9f1f2c503f2d6e4 8f8034f4cc29da83d689f2f631af6938ba". The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

AS I understand, because is server side rendering the node_modules are necessary but how can I resolve this problem?

this is part of the .csproj file

<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 --aot" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --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>
  </ResolvedFileToPublish>
</ItemGroup>

NunoRibeiro
  • 511
  • 2
  • 7
  • 22

3 Answers3

0

The 260 character path limit is a limitation within the Windows OS. You will need to reduce the length of the path for this file in order to successfully build and publish. There are a few ways to do this.

  1. You can store the project in a folder closer to the drive root.
  2. You can reduce the length of the file name.
  3. You can set the build output to land somewhere closer to the drive root.

To change the build output folder right-click the project and open up the properties: Image showing the right-click menu for a project with the properties option highlightes

In the properties window make sure you are editing the configuration you are using for publishing (usually Release) and open the Build tab. Near the bottom of the window, you can override the default build path to a different folder: Image of the build properties tab with a custom build output location set.

PerfectlyPanda
  • 3,271
  • 1
  • 6
  • 17
0

There are two solutions for this problem: 1. Don't deploy node_modules cache. CI/CD will take a lot of time.

<ItemGroup>
 <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
 <DistFiles
   Include="$(SpaRoot)node_modules\**"
   Exclude="$(SpaRoot)node_modules\.cache\**; $(SpaRoot)node_modules.cache\**"
   Condition="'$(BuildServerSideRenderer)' == 'true'" />
 <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
   <RelativePath>%(DistFiles.Identity)</RelativePath>
   <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
 </ResolvedFileToPublish>
</ItemGroup>
  1. Deploy package.json and lock file instead of node_modules. It's much faster because you don't have to copy node_modules with a lot of packages including the dev ones. CI/CD has to install node packages. Yarn is used in the example.
<ItemGroup>
 <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
 <DistFiles
   Include="$(SpaRoot)package.json; $(SpaRoot)yarn.lock;"
   Condition="'$(BuildServerSideRenderer)' == 'true'" />
 <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
   <RelativePath>%(DistFiles.Identity)</RelativePath>
   <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
 </ResolvedFileToPublish>
</ItemGroup>
Pavel Levchuk
  • 757
  • 8
  • 11
0

you have to change Terser settings in order to disable cache files.

In Angular 8 it's easy, you have to use angular custom-webpack : Angular CLI custom webpack config

webpack.config.js :

    const TerserPlugin = require('terser-webpack-plugin');
    module.exports = {
    cache: false,
   optimization: {
    minimize: true,
    minimizer: [
     new TerserPlugin({
      cache: false,
      }),
    ],
   },
 };

see terser-webpack-blugin site