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.8KB

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