diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs index 3fb6e721c9..782e7fc383 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs @@ -26,6 +26,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling private readonly IServiceProvider _serviceProvider; private readonly IDynamicFileProvider _dynamicFileProvider; private readonly IBundleCache _bundleCache; + private readonly IWebRequestResources _requestResources; public BundleManager( IOptions options, @@ -35,7 +36,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling IServiceProvider serviceProvider, IDynamicFileProvider dynamicFileProvider, IBundleCache bundleCache, - IHybridWebRootFileProvider webRootFileProvider) + IHybridWebRootFileProvider webRootFileProvider, + IWebRequestResources requestResources) { _hostingEnvironment = hostingEnvironment; _scriptBundler = scriptBundler; @@ -43,6 +45,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling _dynamicFileProvider = dynamicFileProvider; _bundleCache = bundleCache; WebRootFileProvider = webRootFileProvider; + _requestResources = requestResources; _styleBundler = styleBundler; _options = options.Value; } @@ -59,17 +62,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling protected virtual IReadOnlyList GetBundleFiles(BundleConfigurationCollection bundles, string bundleName, IBundler bundler) { - var bundleRelativePath = _options.BundleFolderName.EnsureEndsWith('/') + bundleName + "." + bundler.FileExtension; + var files = _requestResources.TryAdd(CreateFileList(bundles, bundleName)); - var cacheItem = _bundleCache.GetOrAdd(bundleRelativePath, () => + if (!IsBundlingEnabled()) { - var files = CreateFileList(bundles, bundleName); + return files; + } - if (!IsBundlingEnabled()) - { - return new BundleCacheItem(files); - } + var bundleRelativePath = + _options.BundleFolderName.EnsureEndsWith('/') + + bundleName + "." + files.JoinAsString("|").ToMd5() + "." + bundler.FileExtension; + var cacheItem = _bundleCache.GetOrAdd(bundleRelativePath, () => + { var cacheValue = new BundleCacheItem( new List { @@ -187,7 +192,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling contributor.ConfigureBundle(context); } - return context.Files; + return context.Files; //TODO: Distinct? } } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/SimpleBundleContributor.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/SimpleBundleContributor.cs index 470fb05046..5dd357cefd 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/SimpleBundleContributor.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/SimpleBundleContributor.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling { @@ -13,7 +14,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling public override void ConfigureBundle(BundleConfigurationContext context) { - context.Files.AddRange(Files); + foreach (var file in Files) + { + context.Files.AddIfNotContains(file); + } } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelper.cs new file mode 100644 index 0000000000..3a5e85fc7a --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelper.cs @@ -0,0 +1,19 @@ +using System; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers +{ + [HtmlTargetElement("abp-bundle-contributor", TagStructure = TagStructure.NormalOrSelfClosing, ParentTag = "abp-style-bundle")] + [HtmlTargetElement("abp-bundle-contributor", TagStructure = TagStructure.NormalOrSelfClosing, ParentTag = "abp-script-bundle")] + public class AbpBundleContributorTagHelper : AbpTagHelper + { + public Type Type { get; set; } + + public AbpBundleContributorTagHelper(AbpBundleContributorTagHelperService service) + : base(service) + { + + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelperService.cs new file mode 100644 index 0000000000..f34f47b280 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleContributorTagHelperService.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers +{ + public class AbpBundleContributorTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.SuppressOutput(); + + var files = (List)context.Items[AbpTagHelperConsts.ContextBundleItemListKey]; + files.Add(new BundleTagHelperItem(TagHelper.Type)); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleFileTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleFileTagHelperService.cs index 129043e2a3..f9e5b22fda 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleFileTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleFileTagHelperService.cs @@ -6,14 +6,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers { public class AbpBundleFileTagHelperService : AbpTagHelperService { - public const string ContextFileListKey = "AbpBundleFileTagHelperService.BundleFiles"; - public override void Process(TagHelperContext context, TagHelperOutput output) { output.SuppressOutput(); - var files = (List)context.Items[ContextFileListKey]; - files.Add(TagHelper.Src); + var files = (List)context.Items[AbpTagHelperConsts.ContextBundleItemListKey]; + files.Add(new BundleTagHelperItem(TagHelper.Src)); } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperServiceBase.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperServiceBase.cs index b5d0f59cb6..6dc089c4c6 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperServiceBase.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpBundleTagHelperServiceBase.cs @@ -24,10 +24,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers output.TagName = null; var bundleName = TagHelper.Name; - var files = await GetFileList(context, output); + var files = await GetBundleItems(context, output); if (bundleName.IsNullOrEmpty()) { - bundleName = GenerateBundleName(context, output, files); + bundleName = GenerateBundleName(files); } CreateBundle(bundleName, files); @@ -48,21 +48,21 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers } } - protected abstract void CreateBundle(string bundleName, List files); + protected abstract void CreateBundle(string bundleName, List bundleItems); protected abstract IReadOnlyList GetBundleFiles(string bundleName); protected abstract void AddHtmlTag(TagHelperContext context, TagHelperOutput output, string file); - protected virtual string GenerateBundleName(TagHelperContext context, TagHelperOutput output, List fileList) + protected virtual string GenerateBundleName(List bundleItems) { - return fileList.JoinAsString("|").ToMd5(); + return bundleItems.JoinAsString("|").ToMd5(); } - protected virtual async Task> GetFileList(TagHelperContext context, TagHelperOutput output) + protected virtual async Task> GetBundleItems(TagHelperContext context, TagHelperOutput output) { - var fileList = new List(); - context.Items[AbpBundleFileTagHelperService.ContextFileListKey] = fileList; + var fileList = new List(); + context.Items[AbpTagHelperConsts.ContextBundleItemListKey] = fileList; await output.GetChildContentAsync(); //TODO: Suppress child execution! return fileList; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpScriptBundleTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpScriptBundleTagHelperService.cs index 87f8370577..9df29c8106 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpScriptBundleTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpScriptBundleTagHelperService.cs @@ -17,11 +17,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers } - protected override void CreateBundle(string bundleName, List files) + protected override void CreateBundle(string bundleName, List bundleItems) { BundleManager.CreateScriptBundle( bundleName, - configuration => configuration.AddFiles(files.ToArray()) + configuration => bundleItems.ForEach(bi => bi.AddToConfiguration(configuration)) ); } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpStyleBundleTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpStyleBundleTagHelperService.cs index 308989f1a2..b8005535ef 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpStyleBundleTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpStyleBundleTagHelperService.cs @@ -17,11 +17,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers } - protected override void CreateBundle(string bundleName, List files) + protected override void CreateBundle(string bundleName, List bundleItems) { BundleManager.CreateStyleBundle( bundleName, - configuration => configuration.AddFiles(files.ToArray()) + configuration => bundleItems.ForEach(bi => bi.AddToConfiguration(configuration)) ); } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperConsts.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperConsts.cs new file mode 100644 index 0000000000..4353476591 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpTagHelperConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers +{ + public static class AbpTagHelperConsts + { + public const string ContextBundleItemListKey = "AbpBundleFileTagHelperService.BundleFiles"; + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/BundleTagHelperItem.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/BundleTagHelperItem.cs new file mode 100644 index 0000000000..6c36320f63 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/BundleTagHelperItem.cs @@ -0,0 +1,38 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers +{ + public class BundleTagHelperItem + { + public string File { get; } + + public Type Type { get; } + + public BundleTagHelperItem(string file) + { + File = file; + } + + public BundleTagHelperItem(Type type) + { + Type = type; + } + + public override string ToString() + { + return File ?? Type.FullName ?? "?"; + } + + public void AddToConfiguration(BundleConfiguration configuration) + { + if (File != null) + { + configuration.AddFiles(File); + } + else if (Type != null) + { + configuration.AddContributors(Type); + } + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/IWebRequestBundleCoordinator.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/IWebRequestBundleCoordinator.cs new file mode 100644 index 0000000000..226c641724 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/IWebRequestBundleCoordinator.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling +{ + public interface IWebRequestResources + { + /// + /// Adds resouces to to current web request except the ones added before. + /// + /// Candidate resources to be added + /// Resources actually added + List TryAdd(IEnumerable resources); + + bool TryAdd(string resource); + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/WebRequestBundleCoordinator.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/WebRequestBundleCoordinator.cs new file mode 100644 index 0000000000..c3f1e580ef --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Resources/WebRequestBundleCoordinator.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Resources +{ + public class WebRequestResources : IWebRequestResources, IScopedDependency + { + protected List Resources { get; } + + public WebRequestResources() + { + Resources = new List(); + } + + public virtual List TryAdd(IEnumerable resources) + { + var newFiles = resources.Except(Resources).ToList(); + Resources.AddRange(newFiles); + return newFiles; + } + + public bool TryAdd(string resource) + { + return Resources.AddIfNotContains(resource); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/HighlightJs/HighlightJsScriptContributor.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/HighlightJs/HighlightJsScriptContributor.cs index e135aba3a0..03cfe30d01 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/HighlightJs/HighlightJsScriptContributor.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/HighlightJs/HighlightJsScriptContributor.cs @@ -13,11 +13,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.HighlightJs context.Files.AddIfNotContains("/libs/highlight.js/highlight.js"); //TODO: Add related languages by configuration (these can be default!) - context.Files.AddIfNotContains("/libs/highlight.js/languages/cs.js"); - context.Files.AddIfNotContains("/libs/highlight.js/languages/css.js"); - context.Files.AddIfNotContains("/libs/highlight.js/languages/javascript.js"); - context.Files.AddIfNotContains("/libs/highlight.js/languages/json.js"); - context.Files.AddIfNotContains("/libs/highlight.js/languages/xml.js"); + //context.Files.AddIfNotContains("/libs/highlight.js/languages/cs.js"); + //context.Files.AddIfNotContains("/libs/highlight.js/languages/css.js"); + //context.Files.AddIfNotContains("/libs/highlight.js/languages/javascript.js"); + //context.Files.AddIfNotContains("/libs/highlight.js/languages/json.js"); + //context.Files.AddIfNotContains("/libs/highlight.js/languages/xml.js"); } } } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Lodash/LodashScriptContributor.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Lodash/LodashScriptContributor.cs index 3d24671fc6..e900224fc8 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Lodash/LodashScriptContributor.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Lodash/LodashScriptContributor.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Lodash { public override void ConfigureBundle(BundleConfigurationContext context) { - context.Files.AddIfNotContains("/libs/loadash/lodash.min.js"); + context.Files.AddIfNotContains("/libs/lodash/lodash.min.js"); } } }