The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BundleTagHelper.cs 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using Microsoft.AspNetCore.Hosting;
  2. using Microsoft.AspNetCore.Mvc.Rendering;
  3. using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
  4. using Microsoft.AspNetCore.Mvc.ViewFeatures;
  5. using Microsoft.AspNetCore.Razor.TagHelpers;
  6. using Microsoft.Extensions.Caching.Memory;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Newtonsoft.Json;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. namespace Teknik.Utilities.TagHelpers
  14. {
  15. [HtmlTargetElement("bundle")]
  16. public class BundleTagHelper : TagHelper
  17. {
  18. private const string VirtualFolder = "./wwwroot/";
  19. private const string ConfigPath = "bundleconfig.json";
  20. private readonly IHostingEnvironment _env;
  21. private readonly IMemoryCache _cache;
  22. [HtmlAttributeNotBound]
  23. [ViewContext]
  24. public ViewContext ViewContext { get; set; }
  25. public bool AppendVersion { get; set; } = false;
  26. public string Src { get; set; }
  27. public BundleTagHelper(IHostingEnvironment env, IMemoryCache cache)
  28. {
  29. _env = env;
  30. _cache = cache;
  31. }
  32. public override void Process(TagHelperContext context, TagHelperOutput output)
  33. {
  34. // Clear the initial wrap tag
  35. output.TagName = string.Empty;
  36. // Clean up the src
  37. Src = Src.TrimStart(new [] { '~', '/' });
  38. List<string> files = new List<string>();
  39. switch (_env.EnvironmentName)
  40. {
  41. case "Test":
  42. case "Production":
  43. files.Add(Src);
  44. break;
  45. case "Development":
  46. var configFile = Path.Combine(_env.ContentRootPath, ConfigPath);
  47. var bundle = GetBundle(configFile, Src);
  48. if (bundle == null)
  49. return;
  50. // Clean up the bundle to remove the virtual folder that aspnetcore provides.
  51. files.AddRange(bundle.InputFiles.Select(file =>
  52. {
  53. if (file.StartsWith(VirtualFolder))
  54. return file.Substring(VirtualFolder.Length);
  55. return file;
  56. }).ToList());
  57. break;
  58. }
  59. foreach (var file in files)
  60. {
  61. // Get the file version for this file
  62. string fullPath = "/" + file;
  63. if (AppendVersion)
  64. {
  65. var _fileVersionProvider = ViewContext.HttpContext.RequestServices.GetRequiredService<IFileVersionProvider>();
  66. fullPath = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.Path, fullPath);
  67. }
  68. if (file.EndsWith(".js"))
  69. {
  70. output.Content.AppendHtml($"<script src='{fullPath}' type='text/javascript'></script>");
  71. }
  72. else if (file.EndsWith(".css"))
  73. {
  74. output.Content.AppendHtml($"<link rel='stylesheet' href='{fullPath}'></link>");
  75. }
  76. }
  77. }
  78. public static Bundle GetBundle(string configFile, string bundlePath)
  79. {
  80. var file = new FileInfo(configFile);
  81. if (!file.Exists)
  82. return null;
  83. var bundles = JsonConvert.DeserializeObject<IEnumerable<Bundle>>(File.ReadAllText(configFile));
  84. return (from b in bundles
  85. where b.OutputFileName.EndsWith(bundlePath, StringComparison.InvariantCultureIgnoreCase)
  86. select b).FirstOrDefault();
  87. }
  88. public class Bundle
  89. {
  90. [JsonProperty("outputFileName")]
  91. public string OutputFileName { get; set; }
  92. [JsonProperty("inputFiles")]
  93. public List<string> InputFiles { get; set; } = new List<string>();
  94. }
  95. }
  96. }