diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index 2434b2b8fb..1695c359bb 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -139,9 +139,10 @@ namespace Umbraco.Tests.Integration.TestServerTest public override void ConfigureServices(IServiceCollection services) { services.AddTransient(); + IWebHostEnvironment webHostEnvironment = TestHelper.GetWebHostEnvironment(); TypeLoader typeLoader = services.AddTypeLoader( GetType().Assembly, - TestHelper.GetWebHostEnvironment(), + webHostEnvironment, TestHelper.GetHostingEnvironment(), TestHelper.ConsoleLoggerFactory, AppCaches.NoCache, @@ -154,7 +155,7 @@ namespace Umbraco.Tests.Integration.TestServerTest .AddConfiguration() .AddUmbracoCore() .AddWebComponents() - .AddRuntimeMinifier() + .AddRuntimeMinifier(webHostEnvironment) .AddBackOfficeCore() .AddBackOfficeAuthentication() .AddBackOfficeIdentity() diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 2a1e9a9298..cc56b250ac 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -215,7 +215,7 @@ namespace Umbraco.Tests.Integration.Testing builder.AddConfiguration() .AddUmbracoCore() .AddWebComponents() - .AddRuntimeMinifier() + .AddRuntimeMinifier(webHostEnvironment) .AddBackOfficeAuthentication() .AddBackOfficeIdentity() .AddTestServices(TestHelper, GetAppCaches()); diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs index 6587f3c6e4..9cbcdf7054 100644 --- a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs @@ -20,6 +20,7 @@ using Umbraco.Web.BackOffice.Trees; using Umbraco.Web.Common.Authorization; using Umbraco.Web.Common.DependencyInjection; using Umbraco.Web.WebAssets; +using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IWebHostEnvironment; namespace Umbraco.Web.BackOffice.DependencyInjection { @@ -31,11 +32,11 @@ namespace Umbraco.Web.BackOffice.DependencyInjection /// /// Adds all required components to run the Umbraco back office /// - public static IUmbracoBuilder AddBackOffice(this IUmbracoBuilder builder) => builder + public static IUmbracoBuilder AddBackOffice(this IUmbracoBuilder builder, IWebHostEnvironment webHostEnvironment) => builder .AddConfiguration() .AddUmbracoCore() .AddWebComponents() - .AddRuntimeMinifier() + .AddRuntimeMinifier(webHostEnvironment) .AddBackOfficeCore() .AddBackOfficeAuthentication() .AddBackOfficeIdentity() diff --git a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs index e8097335d6..7c64d4adbd 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs @@ -12,7 +12,9 @@ using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; using Serilog; using Smidge; using Smidge.Nuglify; @@ -207,9 +209,11 @@ namespace Umbraco.Web.Common.DependencyInjection /// /// Add runtime minifier support for Umbraco /// - public static IUmbracoBuilder AddRuntimeMinifier(this IUmbracoBuilder builder) + public static IUmbracoBuilder AddRuntimeMinifier(this IUmbracoBuilder builder, IWebHostEnvironment webHostEnvironment) { - builder.Services.AddSmidge(builder.Config.GetSection(Core.Constants.Configuration.ConfigRuntimeMinification)); + var smidgePhysicalFileProvider = new SmidgePhysicalFileProvider(webHostEnvironment.ContentRootFileProvider, webHostEnvironment.WebRootFileProvider); + + builder.Services.AddSmidge(builder.Config.GetSection(Core.Constants.Configuration.ConfigRuntimeMinification), smidgePhysicalFileProvider); builder.Services.AddSmidgeNuglify(); return builder; @@ -394,5 +398,29 @@ namespace Umbraco.Web.Common.DependencyInjection return new AspNetCoreHostingEnvironment(wrappedHostingSettings,wrappedWebRoutingSettings, webHostEnvironment); } + + /// + /// This file provider lets us serve physical files to Smidge for minification from both wwwroot and App_Plugins (which is outside wwwroot). + /// This file provider is NOT intended for use anywhere else, as it exposes files from the content root. + /// + private class SmidgePhysicalFileProvider : IFileProvider + { + private readonly IFileProvider _contentRootFileProvider; + private readonly IFileProvider _webRooFileProvider; + + public SmidgePhysicalFileProvider(IFileProvider contentRootFileProvider, IFileProvider webRooFileProvider) + { + _contentRootFileProvider = contentRootFileProvider; + _webRooFileProvider = webRooFileProvider; + } + + public IFileInfo GetFileInfo(string subpath) => subpath.InvariantStartsWith(Core.Constants.SystemDirectories.AppPlugins) + ? _contentRootFileProvider.GetFileInfo(subpath) + : _webRooFileProvider.GetFileInfo(subpath); + + public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotSupportedException(); + + public IChangeToken Watch(string filter) => throw new NotSupportedException(); + } } } diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index c3d3d18451..cbb8bec2da 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.UI.NetCore { #pragma warning disable IDE0022 // Use expression body for methods services.AddUmbraco(_env, _config) - .AddBackOffice() + .AddBackOffice(_env) .AddWebsite() .AddComposers() .Build();