9

I have a project which has separate client and server folders and my goal is to include client files during the server's publish process. The folder structure looks like this

|- server
|  |- src
|     |- MyProject
|        |- MyProject.csproj
|- client
   |- src
      |- dist

Using the default SPA template which defines SpaRoot, in my case ../../../client/src/ and the following item group definition

<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>

From the logs I can see this results in copying the files elsewhere Copying file from "C:\MyProject\client\src\dist\img\ic_mail.svg" to "C:\MyProject\server\src\MyProject\obj\Release\client\src\dist\img\ic_mail.svg". while the target path should be C:\MyProject\server\src\MyProject\obj\Release\netcoreapp3.1\PubTmp\Out\appsettings.Development.json. I'm assuming it's caused by the different parent directory because the common parent is 3 levels up the hierarchy and the files are also copied to a directory 3 levels higher than they should be.

I tried prefixing the SpaRoot with $(ProjectDir), but that did not help. My goal is to copy the files from the dist folder to wwwroot located at the root of the publish folder. I attempted to adjust the ResolvedFileToPublish, but I was not able to retrieve the items' relative path (relative to the dist folder).

Edit: A csproj based workaround was to copy the files manually to wwwroot in the BeforeTargets hook. Can this produce any unforeseen problems? (mostly the <ClientDistFile/>)

<ItemGroup>
    <ClientDistFiles Include="$(SpaRoot)dist/**/*.*"/>
</ItemGroup>

<Target Name="PublishRunWebpack" BeforeTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="yarn install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="yarn build:$(TargetEnvironment)" />

    <Copy
        SourceFiles="@(ClientDistFiles)"
        DestinationFiles="@(ClientDistFiles->'wwwroot\%(RecursiveDir)%(Filename)%(Extension)')"
    />
</Target>
pikausp
  • 1,142
  • 11
  • 31

1 Answers1

0

I had a similar issue, here is a code that resolved it:

<ItemGroup>
    <DistFiles Include="$(SpaRoot)dist\**"/>
    <DistFiles>
        <PublishPath>$([System.String]::Copy('%(RelativeDir)').Replace($(SpaRoot)dist, 'wwwroot'))</PublishPath>
    </DistFiles>
    <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.PublishPath)%(DistFiles.FileName)%(DistFiles.Extension)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>True</ExcludeFromSingleFile>
    </ResolvedFileToPublish>
</ItemGroup>

The fourth line is basically the magic here. It will create new metadata property on each file in DistFiles containing relative path for the publish directory. Then it is just putted together on the seventh line with file names and extensions.

Erlin
  • 1