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.
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.
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
/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.
Most helpful comment
This was fixed in 4400467c15ccbf6df222e5d264afb7e3b850ea0d and will be available on the next preview.