Site.less» — это физический путь, но ожидался виртуальный путь

Все, что я использую DotLess с LessTransformer.cs, которое я нашел в Интернете, в моем проекте MVC 4.

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Optimization;
using MyNamespace.Infrastructure.Bundler;
using dotless.Core.configuration;

namespace MyNameSpace.Infrastructure.Transformers.Less
{
    public class LessTransform : IBundleTransform
    {
        private readonly DotlessConfiguration _configuration;

        public LessTransform(DotlessConfiguration configuration)
        {
            _configuration = configuration;
        }

        public LessTransform()
            : this(DotlessConfiguration.GetDefaultWeb())
        { }

        public void Process(BundleContext context, BundleResponse response)
        {
            var builder = new StringBuilder();

            _configuration.MinifyOutput         = false;
            _configuration.ImportAllFilesAsLess = true;
            _configuration.CacheEnabled         = false;
            _configuration.LessSource           = typeof(VirtualFileReader);

            foreach (var file in response.Files)
            {
                if (!File.Exists(file.FullName))
                {
                    continue;
                }

                var content = ResolveImports(file);

                builder.AppendLine((_configuration.Web) ?
                                    dotless.Core.LessWeb.Parse(content, _configuration)
                                    : dotless.Core.Less.Parse(content, _configuration));
            }

            response.ContentType = "text/css";
            response.Content = builder.ToString();
        }

        private static readonly Regex SLessImportRegex =
            new Regex("@import [\"|'](.+)[\"|'];", RegexOptions.Compiled);

        private static string ResolveImports(FileInfo file)
        {
            var content = File.ReadAllText(file.FullName, Encoding.UTF8);

            return SLessImportRegex.Replace(
                content,
                match =>
                {
                    var import = match.Groups[1].Value;

                    // Is absolute path?
                    Uri uri;
                    if (Uri.TryCreate(import, UriKind.Absolute, out uri))
                    {
                        return match.Value;
                    }

                    var path = Path.Combine(file.Directory.FullName, import);

                    if (!File.Exists(path))
                    {
                        throw new ApplicationException(string.Concat("Unable to resolve import ", import));
                    }
                    return match.Value.Replace(import, path);
                });
        }
    }
}

Я с тех пор добавил к этому

_configuration.MinifyOutput         = false;
_configuration.ImportAllFilesAsLess = true;
_configuration.CacheEnabled         = false;
_configuration.LessSource           = typeof(VirtualFileReader);



using System.IO;
using System.Web.Hosting;
using dotless.Core.Input;

namespace MyNamespace.Infrastructure.Bundler
{
    internal sealed class VirtualFileReader : IFileReader
    {
        public byte[] GetBinaryFileContents(string fileName)
        {
            fileName = GetFullPath(fileName);
            return File.ReadAllBytes(fileName);
        }

        public string GetFileContents(string fileName)
        {
            fileName = GetFullPath(fileName);
            return File.ReadAllText(fileName);
        }

        public bool DoesFileExist(string fileName)
        {
            fileName = GetFullPath(fileName);
            return File.Exists(fileName);
        }

        private static string GetFullPath(string path)
        {
            return HostingEnvironment.MapPath("\\Content\\css\\" + path);
        }
    }
}

У меня есть файл Less

@import url('LESS\Site.less');
@import url('LESS\Site.Main.less');

body {
    #featured-posts {
        clear:both;
    }
}

@media all and (max-width:320px) {
   @import url('LESS\Site.Mobile.less');
}

(Я пробовал различные пути для импорта и URL-адреса обозначения функции /w и /wo ()

Что все вытащил в моем BundleConfig

    Bundle siteStyles = new      StyleBundle("~/bundles/css").Include("~/Content/css/Main.less");
    siteStyles.Transforms.Add(new LessTransform());
    siteStyles.Transforms.Add(new CssMinify());
    bundles.Add(siteStyles);

прежде чем я добавил VirtualFileReader, я получил сообщение об ошибке: -

C:/SourceControl/Git/MyNameSpace/MyNameSpace/Content/css/LESS/Site.less — это физический путь, но ожидался виртуальный путь.

так как я добавляю его, я получаю просто значение null для dotless.Core.LessWeb.Parse(content, _configuration)

он всегда взрывается в этой строке, учитывая, что я был немного осторожен в реализации этого меньшего количества вещей и без точек, потому что я не использовал ни того, ни другого раньше, но я не могу найти хорошую надежную документацию/учебники по нему. Поэтому, если бы вы могли помочь мне с моей ошибкой, это было бы здорово, и указать мне направление на несколько хороших руководств по этому вопросу, я был бы очень благодарен.

[EDIT] добавление сведений о меньшем количестве файлов и файловой структуре.

My File structure is 

Content/css/Main.less
Content/css/LESS/Site.less
Content/css/LESS/Mobile.less

и т.д... ТИА.

p.s. не беспокойтесь о MyNamespace/MyNamespace, я просто сократил все это для ясности.


person JTGrime    schedule 08.04.2013    source источник
comment
Попробуйте изменить StyleBundle("~/bundles/css") на StyleBundle("~/Content/css/css")   -  person MikeSmithDev    schedule 08.04.2013
comment
Также кажется, что было бы более эффективно объединить все ваши стили вместо использования @imports.   -  person MikeSmithDev    schedule 08.04.2013
comment
Это может быть более эффективно, но спецификация LESS требует @imports. И в теории BundleTransform сделает это за нас.   -  person mxmissile    schedule 08.04.2013
comment
Нет, пробовал с VirtualFileReader.cs и без LessTransformer.cs. Я получаю следующую ошибку {Вы импортируете файл, оканчивающийся на .less, который не может быть найден.: LESS\\Site.less}   -  person JTGrime    schedule 08.04.2013
comment
Незначительный момент, но разве вы не должны использовать косую черту в своих операторах импорта?   -  person Dave Hogan    schedule 08.04.2013
comment
@JTGrime Я дважды шел по этому пути, сдался. В итоге не использовал встроенную связку и просто использовал вещи без точек, как обычно. Мне интересно посмотреть, как это выйдет.   -  person mxmissile    schedule 08.04.2013
comment
@DaveHogan Я пробовал оба, пройдясь по нему прошлой ночью, я обнаружил, что он использует «\», а не «/», поэтому я сопоставил его. Я почти перепробовал все комбинации, которые только мог придумать с точки зрения меньшего количества кода.   -  person JTGrime    schedule 08.04.2013
comment
@mxmissile да, я действительно хочу довести это до конца, у меня в голове есть хорошая небольшая идея для шаблона для динамического создания клиентских пакетов.   -  person JTGrime    schedule 08.04.2013


Ответы (1)


Я не понимаю, почему вы используете пользовательский трансформатор.

Спецификация LESS говорит, что если вы используете следующий синтаксис, файл будет объединен автоматически:

@import "LESS/Site";

У меня он работает отлично, мне не нужны никакие кастомные трансформаторы, только стандартная безточечная упаковка. Чтобы включить минификацию, вам нужен этот параметр в web.config:

<dotless minifyCss="true" cache="true" web="true" />

У меня есть около 30 импортов компонентов и подкомпонентов, и на выходе получается один мини-файл.

Я предлагаю вам не использовать набор стилей, а указать прямо на ваш файл less:

<link href="~/Content/css/main.less" rel="stylesheet" />

Включится обработчик http без точек, преобразует less в css и кэширует его для последующих запросов.

person Marco Bettiolo    schedule 23.05.2013
comment
ааа, я действительно решил это несколько недель назад, у меня просто не было времени ответить на него с тех пор, как я начал новую работу. Спасибо за ответ. - person JTGrime; 24.05.2013
comment
@JTGrime Мой ответ был правильным? Вы решили проблему по-другому? - person Marco Bettiolo; 25.05.2013
comment
@MarcoBettiolo Существуют ли неблагоприятные последствия для кэширования браузера при использовании этого подхода? То есть, если вы не используете связку с обновлениями ключей кеша, это будет проблематично? - person ctc; 17.10.2013
comment
@ctc Я заметил хорошее улучшение в кешировании браузера, объединение генерирует хеш-значение для конкретного сгенерированного пакета, пока пакет не меняется, ключ остается прежним. Если вы не используете ключи кеша, то ваш браузер мой кеширует неправильный стиль. Я предлагаю использовать правильные заголовки кеша, чтобы смягчить эту проблему. - person Marco Bettiolo; 24.10.2013