Aspnetcore: [Blazor Wasm] Razor Class libraries static assets are not published in the dist folder

Created on 14 Aug 2019  路  11Comments  路  Source: dotnet/aspnetcore

When publishing a Blazor Webassembly App referencing a razor class library the _content folder for the class library is created in the publish/wwwroot/ path instead of publish/ProjectName/dist/ along with all the other app files.

To Reproduce

  1. Create a default Blazor Webassembly App named TestBlazorApp
  2. Create a default Razor Class Library
  3. In the Blazor app add a reference to the class library, a reference to the component in the index.cshtml file and a reference to the css in the index.html file
  4. The component should render correctly with the development server
  5. Perform a dotnet publish and inspect the bin\Debug\netstandard2.0\publish\TestBlazorApp\dist: the _content folder is missing but is present at bin\Debug\netstandard2.0\publish\wwwroot\_content

Expected behavior

The static assets for a Razor class library should be published in the same folder of the the other assets of a referencng Blazor Webassembly app.

Additional context

The static assets are published correctly for a Blazor Server app.

dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview8-013656
 Commit:    8bf06ffc8d

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100-preview8-013656\

Host (useful for support):
  Version: 3.0.0-preview8-28405-07
  Commit:  d01b2fb7bc
Done area-blazor blazor-wasm bug

Most helpful comment

This was fixed in 4400467c15ccbf6df222e5d264afb7e3b850ea0d and will be available on the next preview.

All 11 comments

/cc @javiercn

We might need to do some tweaks here. We can talk about when to get the changes in.

Is there any workaround?

In server-side Blazor copying the files manually is working, but in client-side Blazor, not. In my project a necessary JavaScript file is not copied and the app is crashing.

@arivoir from my tests publishing a server-side project was working correctly but maybe I didn't check well enough. On client-side my temporary workaround is to copy the content of the publish/wwwroot/ into the publish/ProjectName/dist/ folder.

From what I can tell, if a referenced Razor Class Library contains the "EmbeddedResource" elements that were present in early versions of the framework, the static assets of these projects will show up in the dist/_content folder. If the project does not contain the EmbeddedResource elements, it will show up in the wwwroot folder, as described by @ghidello.

To work around this, you can make sure the static content is in a folder called content in the referenced library (not wwwroot), and the following is in the csproj file:

  <ItemGroup>
    <!-- .js/.css files will be referenced via <script>/<link> tags; other content files will just be included in the app's 'dist' directory without any tags referencing them -->
    <EmbeddedResource Include="content\**\*.js" LogicalName="blazor:js:%(RecursiveDir)%(Filename)%(Extension)" />
    <EmbeddedResource Include="content\**\*.css" LogicalName="blazor:css:%(RecursiveDir)%(Filename)%(Extension)" />
    <EmbeddedResource Include="content\**" Exclude="**\*.js;**\*.css" LogicalName="blazor:file:%(RecursiveDir)%(Filename)%(Extension)" />
  </ItemGroup>

I personally don't know much about how the EmbeddedResource feature works, but it seems the folder name content is significant. It doesn't work if the folder is called wwwroot.

Seems to be related to removing the feature by which static files are automatically added to the deployed project (#13279). According to what was discussed in that issue, this "workaround" may not continue to work in the future.

I got this working in client-side app that references Infragistics.Blazor.dll that has _content/Infragistics.Blazor/app.bundle.js file.

I reference it in index.html as follows.
<script src="_content/Infragistics.Blazor/app.bundle.js"></script>

I manually copied the wwwroot content into the dist folder and the app works fine. Even as a PWA deployed to Azure Blob Storage.

Be great if Publish added the wwwroot content to the dist folder.

However : the wwwroot folder can contain files that should not be deployed such as .map files.

Be good to add an ability to filter files copied from wwwroot to dist.

I was able to come up with a solution for app devs dealing with broken/misconfigured libraries (with the help of this StackOverflow post). Just paste the following at the bottom of your project file:

  <Target Name="CopyMissingBlazorContent" BeforeTargets="BlazorCompleteStandalonePublish">
    <PropertyGroup>
      <FullPublishDir>$(PublishDir)</FullPublishDir>
      <FullPublishDir Condition=" $(FullPublishDir.Contains(':')) != 'true' ">$(MSBuildThisFileDirectory)$(PublishDir)</FullPublishDir>
    </PropertyGroup>

    <Message Text="PublishIntermediateOutputPath: $(PublishIntermediateOutputPath)" Importance="high" />
    <Message Text="OutDir: $(OutDir)" Importance="high" />
    <Message Text="BlazorPublishDistDir: $(BlazorPublishDistDir)" Importance="High" />
    <Message Text="PublishDir: $(PublishDir)" Importance="High" />
    <Message Text="FullPublishDir: $(FullPublishDir)" Importance="High" />

    <CreateItem Include="$(FullPublishDir)wwwroot\**\*.*">
      <Output TaskParameter="Include" ItemName="FilesToCopy" />
    </CreateItem>
    <Copy SourceFiles="@(FilesToCopy)"
          DestinationFolder="$(FullPublishDir)$(BlazorPublishDistDir)%(RecursiveDir)"
          SkipUnchangedFiles="true"
          OverwriteReadOnlyFiles="true"
          Retries="3"
          RetryDelayMilliseconds="300"/>
    <RemoveDir Directories="$(FullPublishDir)wwwroot" />
    <Delete Files="$(FullPublishDir)$(BlazorPublishDistDir)**\*.map" />
  </Target>

You can test this by running the following command in your Blazor client-side project: dotnet publish /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true, and then navigating to the Zip file in the /bin/{Configuration} folder. Open the zip, and dig all the way down to the "publish" folder. Inside, you should NOT see a "wwwroot" folder, and the correct files should be in "dist".

For @kdawg1406, I added another task that deletes *.map files from the destination.

HTH!

@robertmclaws WOW, thanks. Question: The Infragistics wwwroot contains hug .map files. Is there a way to exclude these? Or is it possible to use two CreateItem statements, one for .js and one for .css?

Apologies for my lack of build tasks.

Alright @everyone, I updated my post above to cover issues I ran into with Azure DevOps. The last version worked fine locally, but didn't work during a Pipeline build. I also added in the ability to clean out wwwroot and to delete any *.map files in the _dist folder.

HTH!

This was fixed in 4400467c15ccbf6df222e5d264afb7e3b850ea0d and will be available on the next preview.

How can RCL be used with Blazor WASM? A Blazor WASM project is .Net standard, but a RCL is Core 3.1? How can static files be used with Blazor WASM? Previously i used a class library with the automatic include options but this has now been removed, but the alternative (_content/...) solution is not working.

Was this page helpful?
0 / 5 - 0 ratings