"Site.less"是一个物理路径,但是期望的是一个虚拟路径。

4
我正在我的MVC 4项目中使用DotLess和我在网上找到的LessTransformer.cs。
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');
}

(我已经尝试了各种路径来导入和/w和/wo函数符号url()

这都被引入到我的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'是物理路径,但预期的是虚拟路径。
自从我添加了它后,我得到了简单的值为空。它总是在这一行崩溃,我已经有些急于实现这个less东西和dotless,因为我以前没有使用过它们,但是我似乎找不到任何好的、坚实的文档/教程。所以如果你能帮我解决我的错误,并指引我一些关于此主题的好的教程,我将非常感激。
[编辑] 添加有关less文件和文件结构的详细信息。
My File structure is 

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

等等...

附言:不用担心MyNamespace/MyNamespace的问题,我只是为了清晰起见缩短了它们。


尝试将 StyleBundle("~/bundles/css") 更改为 StyleBundle("~/Content/css/css") - MikeSmithDev
似乎将所有样式捆绑在一起而不是使用“@imports”会更有效率。 - MikeSmithDev
它可能更有效率,但 LESS 规范要求使用 @imports。理论上,BundleTransform 为我们执行“捆绑”操作。 - mxmissile
不行,在 VirtualFileReader.cs 中尝试了一下,也在 LessTransformer.cs 中尝试了一下不加它。我得到了以下错误 {"You are importing a file ending in .less that cannot be found.":"LESS\Site.less"}。 - JTGrime
小问题,但是你的导入语句中不应该使用正斜杠吗? - Dave Hogan
显示剩余3条评论
1个回答

0

我不明白为什么你要使用自定义转换器。

LESS规范指出,如果您使用以下语法,文件将自动捆绑:

@import "LESS/Site";

对我来说它完美地工作,我不需要任何自定义转换器,只需要标准的dotless包。要启用缩小功能,您需要在web.config中进行以下设置:

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

我有大约30个组件和子组件的导入,输出是一个单一的压缩文件。

我建议你不要使用样式捆绑,而是直接指向你的less文件:

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

无点 http 处理程序将启动,将 less 转换为 css 并缓存以供后续请求使用


啊,我其实在几周前就解决了这个问题,只是因为开始新工作一直没有时间回复。不过还是谢谢你的回复。 - JTGrime
@JTGrime 我的答案正确吗?你是用其他方法解决了你的问题吗? - Marco Bettiolo
@MarcoBettiolo使用这种方法进行浏览器缓存会有不良影响吗?意思是,如果您不使用捆绑和缓存键更新,更新将会有问题吗? - ctc
@ctc 我注意到浏览器缓存有了很大的改进。现在打包程序会为特定生成的代码块生成哈希值,只要代码块没有发生变化,它的键就不会变。如果你不使用缓存键,那么你的浏览器可能会缓存错误的样式。我建议使用适当的缓存头来减轻这个问题。 - Marco Bettiolo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接