如何使用ASP.Net MVC 4在Release模式捆绑LESS文件? [英] How to use ASP.Net MVC 4 to Bundle LESS files in Release mode?

查看:273
本文介绍了如何使用ASP.Net MVC 4在Release模式捆绑LESS文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的web项目LESS文件,并有4 MVC功能捆绑到电话的带点库打开少进CSS,然后缩小的结果,并给它的浏览器。

I'm trying to have LESS files in my web project, and have the MVC 4 bundling functionality call into the dotLess library to turn the LESS into CSS, then minify the result and give it to the browser.

我发现在 ASP.NET网站为例(下标题的 LESS,CoffeeScript中,SCSS,萨​​斯捆绑。的)。这给了我一个 LessTransform 类,看起来像这样:

I found an example on the ASP.NET site (under the heading LESS, CoffeeScript, SCSS, Sass Bundling.). This has given me a LessTransform class that looks like this:

public class LessTransform : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        response.Content = dotless.Core.Less.Parse(response.Content);
        response.ContentType = "text/css";
    }
}

和此行中我的​​ BundleConfig 类:

bundles.Add(new Bundle(
    "~/Content/lessTest", 
    new LessTransform(), 
    new CssMinify()).Include("~/Content/less/test.less"));

终于我在_Layout.cshtml以下行,在< HEAD>

@Styles.Render("~/Content/lessTest")

如果我在调试模式下的网站,这是呈现给浏览器:

If I have the site in debug mode, this is rendered to the browser:

<link href="/Content/less/test.less" rel="stylesheet"/>

在.LESS文件中的规则被应用,并遵循链接表明LESS已正确转化为CSS

The rules in the .less file are applied, and following that link shows that the LESS has been correctly transformed into CSS.

不过,如果我把网站变成释放模式,这是呈现出来:

However, if I put the site into release mode, this is rendered out:

<link href="/Content/less?v=lEs-HID6XUz3s2qkJ35Lvnwwq677wTaIiry6fuX8gz01" rel="stylesheet"/>

在.LESS文件的规则的的应用,因为下面的链接从IIS提供了一个404错误。

The rules in the .less file are not applied, because following the link gives a 404 error from IIS.

如此看来,一些与捆绑脚麻。我如何得到这个在释放模式工作,或者我怎么找出究竟是怎么了?

So it seems that something is going wrong with the bundling. How do I get this to work in release mode, or how do I find out what exactly is going wrong?

推荐答案

看来,带点引擎需要知道当前处理的包文件的路径来解决@import路径。如果运行过程code,你有上述情况,dotless.Core.Less.Parse的()的结果是,当正在分析的.LESS文件空字符串先后引进其他不太文件。

It appears that the dotless engine needs to know the path of the currently processed bundle file to resolve @import paths. If you run the process code that you have above, the result of the dotless.Core.Less.Parse() is an empty string when the .less file being parsed has other less files imported.

福斯特的回应将解决这个问题,首先读取导入的文件:

Ben Foster's response here will fix that by reading the imported files first:

导入文件和带点

更改您的LessTransform文件如下:

Change your LessTransform file as follows:

public 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();

        var lessParser = new Parser();
        ILessEngine lessEngine = CreateLessEngine(lessParser);

        var content = new StringBuilder(bundle.Content.Length);

        var bundleFiles = new List<FileInfo>();

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

            SetCurrentFilePath(lessParser, bundleFile.FullName);
            string source = File.ReadAllText(bundleFile.FullName);
            content.Append(lessEngine.TransformToCss(source, bundleFile.FullName));
            content.AppendLine();

            bundleFiles.AddRange(GetFileDependencies(lessParser));
        }

        if (BundleTable.EnableOptimizations)
        {
            // include imports in bundle files to register cache dependencies
            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);
    }

    /// <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 IEnumerable<FileInfo> GetFileDependencies(Parser lessParser)
    {
        IPathResolver pathResolver = GetPathResolver(lessParser);

        foreach (var importPath in lessParser.Importer.Imports)
        {
            yield return new FileInfo(pathResolver.GetFullPath(importPath));
        }

        lessParser.Importer.Imports.Clear();
    }

    /// <summary>
    /// Returns an <see cref="IPathResolver"/> instance used by the specified LESS lessParser.
    /// </summary>
    /// <param name="lessParser">The LESS parser.</param>
    private IPathResolver GetPathResolver(Parser lessParser)
    {
        var importer = lessParser.Importer as Importer;
        var fileReader = importer.FileReader as FileReader;

        return fileReader.PathResolver;
    }

    /// <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 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))
        {
            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
        {
            currentFilePath = value;
            currentFileDirectory = Path.GetDirectoryName(value);
        }
    }

    /// <summary>
    /// Returns the absolute path for the specified improted 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;
    }
}

这篇关于如何使用ASP.Net MVC 4在Release模式捆绑LESS文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆