WebOptimizer
WebOptimizer copied to clipboard
[Bug] Does not work with .NET 6
Environment: .NET 6, Razor Pages, linux
Does not work.
Here is a MINIMAL repro:
-
dotnet new webapp
(razor pages) -
dotnet add package LigerShark.WebOptimizer.Core
- configure as per README:
- add
app.UseWebOptimizer()
toProgram.cs
- add
builder.Services.AddWebOptimizer()
toProgram.cs
- add
@addTagHelper *, WebOptimizer.Core
to_ViewImports.cshtml
- add
-
ASPNETCORE_ENVIRONMENT=Development dotnet watch
Console log:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.IO.FileNotFoundException: Could not find file '/foo/bar/MyProject/wwwroot/MyProject.styles.css'. File name: '/foo/bar/MyProject/wwwroot/MyProject.styles.css'
The file wwwroot/MyProject.styles.css
is the one dynamically created by RazorPages; I think it's the one related to css isolation.
If I've made a mistake, would appreciate the advice. But I think the above is correct. Coupled with bug in https://github.com/ligershark/WebOptimizer/issues/172, it seems this library does not work with net6.
I think the issue is tied to the "TryGetAssetFromRoute" method and the corresponding call to NormalizeRoute in .NET 6. When the asset is added to the pipeline it adds the "/" in front of the asset route, but when the request comes to get the asset, the route is missing the leading "/" resulting in no match. I've tweaked the "NormalizeRoute method with an if statement to put the "/" back in if it was missing and that seems to resolve the issue, but I'm not sure what implications that would have. @madskristensen or anyone else more familiar with the deep inter-workings could validate that it won't break things? (Or I could put it up in a PR if that's preferred)
Any alternative for .NET 6?
Any alternative for .NET 6?
You can check out my PR for a short-term fix: https://github.com/ligershark/WebOptimizer/pull/240 I think the test just needs to be changed to allow the fix to work, but I also don't know enough about the project as a whole to say if it's the right way to go. I was hoping that someone more familiar with the whole project would step in and point the right direction. All I can say for now is that the proposed fix, when compiled, worked for getting our project up and going with .NET 6. (We use it for js bundling/minification, less compilation, and css bundling/minification)
Any news on this and whether the PR gets included?
The PR has failing tests. When that is fixed it can be merged
This is so much a basic thing to be able to handle ASP.NET Core main CSS bundle. MS recommends WebOptimizer as a way to go and it doesn't hadle ASP.NET default stuff - hilarious!
It looks like this is only an issue when running the project e.g. via dotnet run
or dotnet watch
. If I follow the steps in the original post to reproduce, but run dotnet publish
and then run the resulting executable, it works.
The root issue seems to be that the ProjectName.styles.css
file that ASP.NET generates at build time is placed under a location like obj/Debug/net7.0/scopedcss/bundle/
. When the project is published, it's placed in wwwroot/
. This is where WebOptimizer looks for using the PhysicalFileProvider
, but it can only be found if the project was published. The Microsoft.AspNetCore.StaticWebAssets.ManifestStaticWebAssetFileProvider
would be able to locate it when it's in the obj
folder, but the logic in GetFileProvider is currently resulting in the PhysicalFileProvider
being chosen.
I'm not sure what to do about this though. Should we special-case ProjectName.styles.css
such that it's always using the ManifestStaticWebAssetFileProvider
? Or give ManifestStaticWebAssetFileProvider
a higher precedence over PhysicalFileProvider
when the provider is a CompositeFileProvider
? Currently it just chooses .Last()
as introduced in #238, and before that was just hardcoded to use a PhysicalFileProvider
.
Hi.
For us it's working (published via dotnet publish and in VS) with the following setup:
- Adding
AddJavaScriptBundle()
andAddBundle()
(for css) without specifiying the FileProvider and pre-building a list of available files from theIWebHostEnvironment.WebRootFileProvider
. - Not only using
app.UseWebOptimizer()
(which does not work) but providing theIWebHostEnvironment
explicitly as a parameter. This looks something like this:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Do your stuff here
app.UseWebOptimizer(env);
// Do more stuff
}
I don't know why it's working but it's currently working for me. So shrug. HTH someone.
Sidenote: If you use WebOptimizer to bundle js-files for e.g. Blazor WASM (what we do) you have to exclude the dotnet.7.*.js file from the bundling output. Otherwise I always got a corrupt js-file generated which did not work.
So, does it work with dotnet 7.0 or not? Documentation is not compatible, would be nice to know if its not supported rapidly as even Microsoft docs seems to point here as a solution.
https://learn.microsoft.com/en-us/aspnet/core/client-side/bundling-and-minification?view=aspnetcore-7.0#choose-a-bundling-and-minification-strategy
Hey, in my case I have this setup, resulting in css being bundled, but the js not.. I am a bit frustrated with this tool.
services.AddWebOptimizer(c =>
{
c.AddCssBundle("/cssbundle.css", "/ie10mobile.css", "/bootstrap.min.css", "/bootstrap-responsive.min.css",
"/bootstrap-datetimepicker.min.css", "/font-awesome.min.css", "/durandal.css", "/toastr.css");
c.AddCssBundle("/csslitebundle.css", "/ratchet.min.css", "/featherlight.min.css");
c.AddJavaScriptBundle("/vendor.js", "/Scripts/rachet.min.js");
});
Hey, in my case I have this setup, resulting in css being bundled, but the js not.. I am a bit frustrated with this tool.
services.AddWebOptimizer(c => { c.AddCssBundle("/cssbundle.css", "/ie10mobile.css", "/bootstrap.min.css", "/bootstrap-responsive.min.css", "/bootstrap-datetimepicker.min.css", "/font-awesome.min.css", "/durandal.css", "/toastr.css"); c.AddCssBundle("/csslitebundle.css", "/ratchet.min.css", "/featherlight.min.css"); c.AddJavaScriptBundle("/vendor.js", "/Scripts/rachet.min.js"); });
Hi @lfaletti not sure if you have find a solution for bundling your js files, I able to make it work by using UseContentRoot() method. In your sample it should be something like this:
services.AddWebOptimizer(c =>
{
c.AddJavaScriptBundle("/vendor.js", "/Scripts/rachet.min.js").UseContentRoot();
});
This issue is over a year old. Is there any progress? Should we give up hope? Is WebOptimizer dead? (I hope it's not dead.)
This issue is over a year old. Is there any progress? Should we give up hope? Is WebOptimizer dead? (I hope it's not dead.)
It takes a little getting used to with the pathing. But seems to work fine with .Net 6 and had updates as recent as 3 months ago. It is also still referred to in the MS Docs.
It takes a little getting used to with the pathing. But seems to work fine with .Net 6 and had updates as recent as 3 months ago. It is also still referred to in the MS Docs.
Thanks, but what are you referring to with pathing? I followed the setup instructions as best I could, but they've not been updated for .NET 6 (referencing ASP.NET Core 2.0 project in the setup instructions).
I have not tried it with Publish. I tried it with IIS Express in Visual Studio 2022, as I am in early development, and I need it to work as I develop.
It takes a little getting used to with the pathing. But seems to work fine with .Net 6 and had updates as recent as 3 months ago. It is also still referred to in the MS Docs.
Thanks, but what are you referring to with pathing? I followed the setup instructions as best I could, but they've not been updated for .NET 6 (referencing ASP.NET Core 2.0 project in the setup instructions).
I have not tried it with Publish. I tried it with IIS Express in Visual Studio 2022, as I am in early development, and I need it to work as I develop.
This was the hard part about implementing this. Lots of trial and error getting the Browser's debugger, Sources tab to show what it should.
bundleVars.RootSourcePath: "" bundleVars.BuilderPath: builder.Environment.ContentRootPath;
pipeline.AddCssBundle(bundleVars.KendoCssBundle,
new CssSettings() { MinifyExpressions = bundleVars.IsDevelopment == false },
$"{bundleVars.RootSourcePath}ci/Content/kendo/{bundleVars.KendoVersion}/kendo.common.min.css",
$"{bundleVars.RootSourcePath}ci/Content/kendo/{bundleVars.KendoVersion}/kendo.common-bootstrap.min.css",
$"{bundleVars.RootSourcePath}ci/Content/kendo/{bundleVars.KendoVersion}/kendo.bootstrap-v4.min.css")
.UseFileProvider(new PhysicalFileProvider(bundleVars.BuilderPath));
Thanks a lot for sharing. I don't think that is affecting me. I am using CSS files in the standard wwwroot/css
directory. You appear to be using Kendo UI, which probably complicates things.
Update: I got WebOptimizer working in .NET 6 Razor Pages. Effectively, I made no change; I just toggled between IIS Express and Kestrel. Now, it seems to work in both! :]
We had the same problem with .net 7 projects, so we wrote our own using gulp and a tag helper. Feel free to use it although it does require some initial setup:
https://github.com/sur1969/BundleMinify
Hi.
For us it's working (published via dotnet publish and in VS) with the following setup:
- Adding
AddJavaScriptBundle()
andAddBundle()
(for css) without specifiying the FileProvider and pre-building a list of available files from theIWebHostEnvironment.WebRootFileProvider
.- Not only using
app.UseWebOptimizer()
(which does not work) but providing theIWebHostEnvironment
explicitly as a parameter. This looks something like this:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // Do your stuff here app.UseWebOptimizer(env); // Do more stuff }
I don't know why it's working but it's currently working for me. So shrug. HTH someone.
Sidenote: If you use WebOptimizer to bundle js-files for e.g. Blazor WASM (what we do) you have to exclude the dotnet.7.*.js file from the bundling output. Otherwise I always got a corrupt js-file generated which did not work.
It works, thank you. And may I ask how to avoid this warning?
warn: WebOptimizer.AssetBuilder[1005]
File '/_framework/blazor.server.js' not found. Passing on to next middleware.
I had an issue with CSS bundles not working in .NET 6. The solution was to use AddBundle
instead of AddCssBundle
Before:
pipeline.AddCssBundle(
"/Content/sass/bundled",
"Content/sass/bundled.css")
.UseContentRoot();
After:
pipeline.AddBundle(
"/Content/sass/bundled",
"text/css; charset=UTF-8",
"Content/sass/Bundled.css")
.UseContentRoot();
its not working with .net8 for js files.