【问题标题】:BundleTransformer.Less inject variables depending on context/requestBundleTransformer.Less 根据上下文/请求注入变量
【发布时间】:2013-06-05 17:10:53
【问题描述】:

我们希望将 System.Web.Optimization 的捆绑机制与 Less 转换器结合使用。

问题是同一个应用程序/服务器为不同品牌的网站提供页面。因此,根据“SiteContext”,使用相同的 .less 文件,但 .less 变量应使用不同的值。因此,我们希望(重新)使用相同的更少文件,但根据请求的上下文使用不同的变量。

我尝试了几种不同的理论:

在所有 3 种情况下,我根据 SiteContext 设置不同的捆绑包。

1 通过使用拦截 variables.less 文件的自定义 VirtualPathProvider 注入带有主题变量的 @import 指令

所以我有:

  • 样式文件如:header.less(导入变量文件)
  • 变量文件:variables.less
  • 一个主题变量文件:variables-theme.less(通过 VirtualPathProvider 注入 variables.less)

这不起作用,因为 BundleTransformer 缓存将此视为同一个文件并且不知道 SiteContext。缓存键基于 IAsset 的 Url,我们无法影响此行为。

2 将 variables.less 导入 替换为 variables-themed.less,并使用在 Less 转换器之前运行的自定义转换器

再次没有运气,同样的缓存问题。

作为副作用,额外的转换器在调试中没有被调用,因为资产没有被捆绑,而是由LessAssetHandler 单独调用。这可以通过编写您自己的调用所有必需转换器的 AssetHandler 来解决。

3 创建由自定义 VirtualPathProvider 解析的主题资产名称 例如。将 header-themeX.less 添加到包中,此文件不存在,但您将此文件解析为 header.less 并使用方法 2 设置正确的变量文件导入。 (将 variables.less 的导入替换为主题版本)。

又一次没有运气。我认为如果不是Bundle.Include(string virtualPath) 在内部执行File.Exists(path),这可以解决缓存问题。它不通过CustomVirtualPathProvider


我想深入解决这个问题吗? 欢迎所有想法,我可以想象随着System.Web.Optimization 库越来越受欢迎,这将成为越来越多的人的问题......

请记住:

  • 我们有很多 .less/css 文件
  • 我们将有 5 个左右的主题
  • 我们喜欢在 Visual Studio 中保持工作(这就是为什么 header.less 有一个对 variables.less 的引用)

感谢您的任何反馈。

【问题讨论】:

    标签: c# system.web.optimization bundletransformer


    【解决方案1】:

    迈克尔!

    您在多租户环境中使用Microsoft ASP.NET Web Optimization FrameworkBundle Transformer,因此您需要替换 System.Web.Optimization 的一些组件并创建自己的调试 HTTP 处理程序版本(请参阅«Problem: LESS file imports are added to BundleResponse.Files collection» 讨论)。据我所知,Murat Cakir 在SmartStore.NET 项目中解决了所有这些问题。

    在 Bundle Transformer 中有两种注入 LESS 变量的方法:

    1. 查看LESS-translator的GlobalVariablesModifyVariables属性:

      using System.Collections.Generic;
      using System.Web.Optimization;
      
      using BundleTransformer.Core.Builders;
      using BundleTransformer.Core.Orderers;
      using BundleTransformer.Core.Transformers;
      using BundleTransformer.Core.Translators;
      using BundleTransformer.Less.Translators;
      
      public class BundleConfig
      {
          public static void RegisterBundles(BundleCollection bundles)
          {
              var nullBuilder = new NullBuilder();
              var nullOrderer = new NullOrderer();
      
              var lessTranslator = new LessTranslator
              {
                  GlobalVariables = "my-variable='Hurrah!'",
                  ModifyVariables = "font-family-base='Comic Sans MS';body-bg=lime;font-size-h1=50px"
              };
              var cssTransformer = new CssTransformer(new List<ITranslator>{ lessTranslator });
      
              var commonStylesBundle = new Bundle("~/Bundles/BootstrapStyles");
              commonStylesBundle.Include(
                 "~/Content/less/bootstrap-3.1.1/bootstrap.less");
              commonStylesBundle.Builder = nullBuilder;
              commonStylesBundle.Transforms.Add(cssTransformer);
              commonStylesBundle.Orderer = nullOrderer;
      
              bundles.Add(commonStylesBundle);
          }
      }
      
    2. 创建自定义项转换:

      using System.Text;
      using System.Web.Optimization;
      
      public sealed class InjectContentItemTransform : IItemTransform
      {
          private readonly string _beforeContent;
          private readonly string _afterContent;
      
          public InjectContentItemTransform(string beforeContent, string afterContent)
          {
              _beforeContent = beforeContent ?? string.Empty;
              _afterContent = afterContent ?? string.Empty;
          }
      
          public string Process(string includedVirtualPath, string input)
          {
              if (_beforeContent.Length == 0 && _afterContent.Length == 0)
              {
                  return input;
              }
      
              var contentBuilder = new StringBuilder();
              if (_beforeContent.Length > 0)
              {
                  contentBuilder.AppendLine(_beforeContent);
              }
              contentBuilder.AppendLine(input);
              if (_afterContent.Length > 0)
              {
                  contentBuilder.AppendLine(_afterContent);
              }
      
              return contentBuilder.ToString();
          }
      }
      

    并按如下方式注册此转换:

        using System.Web.Optimization;
    
        using BundleTransformer.Core.Orderers;
        using BundleTransformer.Core.Bundles;
    
        public class BundleConfig
        {
            public static void RegisterBundles(BundleCollection bundles)
            {
                var nullOrderer = new NullOrderer();
    
                const string beforeLessCodeToInject = @"@my-variable: 'Hurrah!';";
                const string afterLessCodeToInject = @"@font-family-base: 'Comic Sans MS';
    @body-bg: lime;
    @font-size-h1: 50px;";
    
                var commonStylesBundle = new CustomStyleBundle("~/Bundles/BootstrapStyles");
                commonStylesBundle.Include(
                   "~/Content/less/bootstrap-3.1.1/bootstrap.less",
                   new InjectContentItemTransform(beforeLessCodeToInject, afterLessCodeToInject));
                commonStylesBundle.Orderer = nullOrderer;
    
                bundles.Add(commonStylesBundle);
            }
        }
    

    两种方式都有缺点:LESS 变量的注入在调试模式下不起作用。

    【讨论】:

    • 有没有办法克服这个问题,即使在调试模式下也能注入内容?也许覆盖 LessAssetHandler httphandler?
    • 埃尔南!我正在努力解决这个问题。等待发布 Bundle Transformer 1.9.0。
    • 埃尔南!在 Bundle Transformer 1.9.0 Beta 1 中实现了这个功能 - bundletransformer.codeplex.com/releases/view/123398。为了调试 HTTP 处理程序可以使用来自捆绑包的转换,需要在 App_Start/BundleConfig.cs 文件的 RegisterBundles 方法中添加以下代码:BundleResolver.Current = new CustomBundleResolver();
    • 感谢您的回答!我还是有问题。一旦文件被注入较少的变量,然后被缓存,如果变量发生变化(例如在数据库中),尽管注入了新变量,我得到了文件的缓存(旧)版本。我尝试用变量的哈希覆盖缓存键,但不起作用。我必须在哪里覆盖 GetCacheKey 以便将新版本的文件发送到浏览器?这是正确的做法吗?
    • 尝试禁用调试 HTTP 处理程序的服务器端缓存。在\configuration\bundleTransformer\core\assetHandler 配置元素的disableServerCache 属性中设置一个等于true 的值。
    猜你喜欢
    • 1970-01-01
    • 2020-06-07
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2014-09-10
    • 1970-01-01
    • 2015-02-06
    相关资源
    最近更新 更多