css - बंद बंडल ट्रांसफार्मर कम में सापेक्ष पथ परिवर्तित




less asp.net-mvc-5 (2)

मैं एक MVC5 परियोजना में कम संकलन के लिए बंडल ट्रांसफार्मर का उपयोग कर रहा हूं। मेरी कम बंडल में एक एकल मुख्य.अलेस फ़ाइल होती है जो सबफ़ोल्डर्स में स्थित अन्य फाइलें आयात करती है। कुछ फ़ाइलों में ऐसी छवि फ़ाइलों के संदर्भ होते हैं, जैसे - यह फ़ाइल /css/structure/header.less :

.site__logo {
    background: url('../img/logo.png') no-repeat;
    // ...
}

संकलित बंडल में ( /css/lessBundle बंडल) यह हो जाता है:

background: url('/css/img/logo.png') no-repeat;

मुझे अनावश्यक फ़ाइल में रिश्तेदार पथ को संरक्षित किया जाना चाहिए, जब इसे बंडल किया जाता है ताकि यह सही ढंग से /img/logo.png को /img/logo.png , नहीं /css/img/logo.png मुझे लगता है कि बंडल ट्रांसफार्मर रिश्तेदार पथ को परिवर्तित करने के लिए जिम्मेदार है - दस्तावेज़ीकरण में यह पैराग्राफ है, लेकिन आगे विस्तार में नहीं जाता है:

आपको यह भी समझने की आवश्यकता है कि जब आप सीएसएस ट्रांसफॉर्मर और जेएसट्रान्सफ़ॉर्मर वर्ग के उदाहरणों को प्लग करते हैं, तो आप परिवर्तनों का एक सेट प्लग इन करते हैं (डीबग और फाइलों के पूर्व-न्यूनतम संस्करण, मध्यवर्ती भाषाओं से अनुवाद कोड, रनटाइम कोड मिनेशन, रिश्तेदार के परिवर्तन पूर्ण करने के लिए पथ (केवल सीएसएस-कोड के लिए) और कोड संयोजन)। परिवर्तनों का एक सेट आपके द्वारा इंस्टॉल किए गए बंडल ट्रांसफार्मर के मॉड्यूल और Web.config फ़ाइल में निर्दिष्ट सेटिंग्स पर निर्भर करता है।

यहां मेरा बंडल कॉन्फ़िफ़ है:

public class BundleConfig
{
    public const string LessBundlePath = "~/css/lessBundle";

    public static void RegisterBundles(BundleCollection bundles)
    {
        var nullBuilder = new NullBuilder();
        var cssTransformer = new CssTransformer();
        var nullOrderer = new NullOrderer();

        // Skip JS-related stuff

        var lessBundle = new Bundle(LessBundlePath)
            .Include("~/css/main.less");
        lessBundle.Builder = nullBuilder;
        lessBundle.Transforms.Add(cssTransformer);
        lessBundle.Orderer = nullOrderer;
        bundles.Add(lessBundle);

        BundleTable.EnableOptimizations = true;
    }
}

/css/main.less ज्यादातर ज्यादातर आयात का एक गुच्छा है:

@import "bootstrap/bootstrap";
@import "structure/header";
// etc.

html, body {
height: 100%;
}

मैंने web.config में इस सेटिंग के साथ खेलने की कोशिश की है, लेकिन कोई प्रभाव नहीं है:

<css defaultMinifier="NullMinifier" disableNativeCssRelativePathTransformation="true">

यदि संभव हो तो मैं असंख्य फाइलों में फ़ाइलपथों को नहीं बदलना चाहूंगा, क्योंकि वे तृतीय पक्ष द्वारा प्रदान की जाती हैं और सब कुछ उनके एकीकरण सर्वर पर ठीक काम करता है (जो। NET का उपयोग नहीं कर रहा है)। क्या मुझे कुछ और करना है?


मैंने थोड़ी देर पहले यह हल किया, इससे पहले कि एमवीसी कम फाइलों के लिए किसी तरह का समर्थन करता था बस सत्यापित करने के लिए परीक्षण किया गया है, और यह क्लास सही ढंग से एक @imported। मौजूदा फ़ोल्डर को लागू करेगा जब इसे सीएसएस

बंडलहेल्पर। Cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Optimization;
using dotless.Core;
using dotless.Core.Abstractions;
using dotless.Core.Importers;
using dotless.Core.Input;
using dotless.Core.Loggers;
using dotless.Core.Parser;

public static class BundleHelper
{
    internal class LessBundle : StyleBundle
    {
        public LessBundle(string virtualPath)
            : base(virtualPath)
        {
            // inject LessTransform to the beginning of the Transforms
            Transforms.Insert(0, new LessTransform());
        }

        public LessBundle(string virtualPath, string cdnPath)
            : base(virtualPath, cdnPath)
        {
            // inject LessTransform to the beginning of the Transforms
            Transforms.Insert(0, new LessTransform());
        }
    }

    // TODO: speed improvement - consider not parsing any CSS files that are not LESS
    // TODO: verify that this still works for nested @imports
    internal class LessTransform : IBundleTransform
    {
        public void Process(BundleContext context, BundleResponse bundle)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            if (bundle == null)
                throw new ArgumentNullException("bundle");

            context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

            // initialize variables
            var lessParser = new Parser();
            ILessEngine lessEngine = CreateLessEngine(lessParser);
            var content = new StringBuilder(bundle.Content.Length);
            var bundleFiles = new List<BundleFile>();

            foreach (var bundleFile in bundle.Files)
            {
                bundleFiles.Add(bundleFile);

                // set the current file path for all imports to use as the working directory
                SetCurrentFilePath(lessParser, bundleFile.IncludedVirtualPath);

                using (var reader = new StreamReader(bundleFile.VirtualFile.Open()))
                {
                    // read in the LESS file
                    string source = reader.ReadToEnd();

                    // parse the LESS to CSS
                    content.Append(lessEngine.TransformToCss(source, bundleFile.IncludedVirtualPath));
                    content.AppendLine();

                    // add all import files to the list of bundleFiles
                    ////bundleFiles.AddRange(GetFileDependencies(lessParser));
                }
            }

            // include imports in bundle files to register cache dependencies
            if (BundleTable.EnableOptimizations)
                bundle.Files = bundleFiles.Distinct();

            bundle.ContentType = "text/css";
            bundle.Content = content.ToString();
        }

        /// <summary>
        /// Creates an instance of LESS engine.
        /// </summary>
        /// <param name="lessParser">The LESS parser.</param>
        private ILessEngine CreateLessEngine(Parser lessParser)
        {
            var logger = new AspNetTraceLogger(LogLevel.Debug, new Http());
            return new LessEngine(lessParser, logger, true, false);
        }

        // TODO: this is not currently working and may be unnecessary.
        /// <summary>
        /// Gets the file dependencies (@imports) of the LESS file being parsed.
        /// </summary>
        /// <param name="lessParser">The LESS parser.</param>
        /// <returns>An array of file references to the dependent file references.</returns>
        private static IEnumerable<BundleFile> GetFileDependencies(Parser lessParser)
        {
            foreach (var importPath in lessParser.Importer.Imports)
            {
                var fileName = VirtualPathUtility.Combine(lessParser.FileName, importPath);
                var file = BundleTable.VirtualPathProvider.GetFile("~/Content/test2.less");

                yield return new BundleFile(fileName, file);
            }

            lessParser.Importer.Imports.Clear();
        }

        /// <summary>
        /// Informs the LESS parser about the path to the currently processed file.
        /// This is done by using a custom <see cref="IPathResolver"/> implementation.
        /// </summary>
        /// <param name="lessParser">The LESS parser.</param>
        /// <param name="currentFilePath">The path to the currently processed file.</param>
        private static void SetCurrentFilePath(Parser lessParser, string currentFilePath)
        {
            var importer = lessParser.Importer as Importer;

            if (importer == null)
                throw new InvalidOperationException("Unexpected dotless importer type.");

            var fileReader = importer.FileReader as FileReader;

            if (fileReader != null && fileReader.PathResolver is ImportedFilePathResolver)
                return;

            fileReader = new FileReader(new ImportedFilePathResolver(currentFilePath));
            importer.FileReader = fileReader;
        }
    }

    public class ImportedFilePathResolver : IPathResolver
    {
        private string _currentFileDirectory;
        private string _currentFilePath;

        public ImportedFilePathResolver(string currentFilePath)
        {
            if (String.IsNullOrEmpty(currentFilePath))
                throw new ArgumentNullException("currentFilePath");

            CurrentFilePath = currentFilePath;
        }

        /// <summary>
        /// Gets or sets the path to the currently processed file.
        /// </summary>
        public string CurrentFilePath
        {
            get
            {
                return _currentFilePath;
            }

            set
            {
                var path = GetFullPath(value);
                _currentFilePath = path;
                _currentFileDirectory = Path.GetDirectoryName(path);
            }
        }

        /// <summary>
        /// Returns the absolute path for the specified imported file path.
        /// </summary>
        /// <param name="filePath">The imported file path.</param>
        public string GetFullPath(string filePath)
        {
            if (filePath.StartsWith("~"))
                filePath = VirtualPathUtility.ToAbsolute(filePath);

            if (filePath.StartsWith("/"))
                filePath = HostingEnvironment.MapPath(filePath);
            else if (!Path.IsPathRooted(filePath))
                filePath = Path.GetFullPath(Path.Combine(_currentFileDirectory, filePath));

            return filePath;
        }
    }
}

उदाहरण उपयोग:

  • App_Start / BundleConfig.cs:

    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new BundleHelper.LessBundle("~/Content/css").Include(
                "~/Content/normalStuff.css",
                "~/Content/template.less",
                "~/Content/site.less"));
        }
    }
  • सामग्री / टेम्पलेट। बिना:

    @import "themes/blue/test";
    
    body {
        background: url('../img/logo.png') no-repeat;
    }
    
    footer {
        background: url('img/logo1.png') no-repeat;
    }
  • सामग्री / थीम / नीला / test.less:

    .myTheme {
        background: url('../img/logo2.png') no-repeat;
    }
    
    .myTheme2 {
        background: url('img/logo3.png') no-repeat;
    }

इस बंडल का उपयोग करके निम्नलिखित सीएसएस का उत्पादन होगा, जो कि आप जिस चीज़ की तलाश कर रहे हैं वह होना चाहिए:

  • स्थान: example.com/path/Content/test.less

    .myTheme {
      background: url('themes/img/logo2.png') no-repeat;
    }
    .myTheme2 {
      background: url('themes/blue/img/logo3.png') no-repeat;
    }
    body {
      background: url('../img/logo.png') no-repeat;
    }
    footer {
      background: url('img/logo1.png') no-repeat;
    }

नोट: मेरी पुरानी टिप्पणियों के आधार पर, मुझे यकीन नहीं है कि यह नेस्टेड @ रिपोर्टों को कैसे प्रबंधित करेगा (परीक्षण के अंदर आयात। अभी तक एक अलग फ़ोल्डर नहीं है)

मुझे बताएं कि यह आपके लिए काम नहीं करता है।


बंडल ट्रान्सफॉर्मर में। कम और बंडल ट्रांसफॉर्मरसैस एंड एससीएसएस मॉड्यूल, पूर्ण करने के लिए सापेक्ष पथ के परिवर्तन को अक्षम नहीं कर सकते, क्योंकि यह @import निर्देशों का उपयोग करते समय छवियों के संदर्भ को तोड़ सकता है।

/img/logo.png बजाय /img/logo.png प्राप्त करने के लिए आपको बस स्रोत कोड में एक सापेक्ष पथ को सही ढंग से निर्दिष्ट करना होगा ( ../../img/logo.png बजाय ../img/logo.png ।)