2

System.Web.Optimizationレストランスと組み合わせてのバンドリング機構のご利用をお願い致します。

問題は、同じアプリケーション/サーバーが異なるブランドの Web サイトのページを提供することです。そのため、「SiteContext」に応じて同じ .less ファイルが使用されますが、.less 変数では異なる値を使用する必要があります。したがって、リクエストのコンテキストに応じて、同じ少ないファイルを (再) 使用する必要がありますが、変数は異なります。

私はいくつかの異なる理論を試しました:

3 つのケースすべてで、SiteContext に応じて異なるバンドルをセットアップします。

1 variables.less ファイルをインターセプトするカスタム VirtualPathProviderを使用して、テーマ変数を含む @import ディレクティブを挿入します。

ので、私は持っています:

  • スタイリング ファイル例: header.less (変数ファイルをインポートします)
  • 変数ファイル: variables.less
  • テーマ変数ファイル: variables-theme.less (VirtualPathProvider を介して variables.less に挿入されます)

BundleTransformer キャッシュはこれを同じファイルと見なし、SiteContext を認識しないため、これは機能しません。キャッシュ キーは URL に基づいており、IAssetこの動作に影響を与えることはできません。

2 variables-themed.less によるvariables.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つほどのテーマがあります
  • 私たちはビジュアルスタジオで物事を動かし続けるのが好きです (それが、header.less が variables.less への参照を持っている理由です)

フィードバックをお寄せいただきありがとうございます。

4

1 に答える 1

2

マイケル!

マルチテナント環境でMicrosoft ASP.NET Web 最適化フレームワークBundle Transformerを使用するため、System.Web.Optimization の一部のコンポーネントを置き換え、独自のバージョンのデバッグ HTTP ハンドラーを作成する必要があります (「問題: LESS 」を参照)。ファイルのインポートは、BundleResponse.Files コレクション»ディスカッションに追加されます)。私の知る限り、Murat Cakir はSmartStore.NETプロジェクトでこれらすべての問題を解決しています。

Bundle Transformer では、LESS 変数を注入する方法が 2 つあります。

  1. プロパティGlobalVariablesModifyVariablesLESS-translator を調べます。

    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 変数の挿入は、デバッグ モードでは機能しません。

于 2014-04-29T11:42:22.997 に答える