问题 ASP.NET MVC4应用程序无法在生产时编译Bootstrap.LESS,而它在dev上运行


我觉得现在有点卡住了。首先我用nuget来

install-package Bootstrap.less

以及

安装包无点

然后,如图所示 关于捆绑和缩小的Rick Andersons Blogpost 在asp.net mvc中,我创建了一个LessTransform-Class。我设置了两个几乎空的.less文件并创建了一个新的包装包装......

    var lessBundle = new Bundle("~/MyLess").IncludeDirectory("~/Content/MyLess", "*.less", true);
    lessBundle.Transforms.Add(new LessTransformer());
    lessBundle.Transforms.Add(new CssMinify());
    bundles.Add(lessBundle);

这很好用。然后我在主bootstrap.less文件中添加了一个新的StyleBundle(它基本上使用@import来包含bootstrap.less发送的所有其他.less文件)...

    bundles.Add(new StyleBundle("~/Bootstrap").Include("~/Content/Bootstrap/less/bootstrap.less"));

和一个ScriptBundle到引导程序JavaScripts ...

    bundles.Add(new ScriptBundle("~/bundles/Bootstrap").Include("~/Scripts/bootstrap/js/bootstrap-*"));

包括所有发货的bootstrap - * .js文件和TADAA一切正常。 CSS已编译,包括正确加载的所有导入的JavaScript文件。

但是......所有这些只适用于开发模式

    <compilation debug="true" targetFramework="4.5"/>

一旦我禁用调试以查看捆绑到一个文件和缩小是否正常工作我遇到问题。

捆绑过程似乎无法导入导入bootstrap.less的所有无。文件

/* Minification failed. Returning unminified contents.
(11,1): run-time error CSS1019: Unexpected token, found '/'
(11,2): run-time error CSS1019: Unexpected token, found '/'
(12,1): run-time error CSS1031: Expected selector, found '@import'
(12,1): run-time error CSS1025: Expected comma or open brace, found '@import'
(12,27): run-time error CSS1019: Unexpected token, found '/'
(12,28): run-time error CSS1019: Unexpected token, found '/'

 ... here go many many lines like these 

(60,25): run-time error CSS1019: Unexpected token, found ';'
(62,1): run-time error CSS1019: Unexpected token, found '/'
(62,2): run-time error CSS1019: Unexpected token, found '/'
(63,1): run-time error CSS1031: Expected selector, found '@import'
(63,1): run-time error CSS1025: Expected comma or open brace, found '@import'
(63,27): run-time error CSS1019: Unexpected token, found '/'
(63,28): run-time error CSS1019: Unexpected token, found '/'
: run-time error CSS1067: Unexpected end of file encountered
 */
/*!
 * Bootstrap v2.3.1 
 *
 * Copyright 2012 Twitter, Inc
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Designed and built with all the love in the world @twitter by @mdo and @fat.
 */

// Core variables and mixins
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";

... and the rest of the original bootstrap.less... no style definitions

看一下缩小的bootstrap.javascript包也让我很难过。在开发中加载页面后没有问题,现在在bootstrap.javascript捆绑并在Google中缩小了JavaScript控制台状态

Uncaught TypeError: Cannot read property 'Constructor' of undefined

我看过几个与我的问题密切相关的话题,我尝试了一些事情,但到目前为止还没有成功。

非常感谢任何能够为我的情况提供一些启示,并指出我错过或做错的人。最好的问候,Ingo


1075
2018-03-12 21:01


起源

这很棒!!!非常感谢。只有一个人。不使用nuget安装bootstrap创建一个可能会覆盖较少文件中的更改的关联? Tha假设您需要进行更改。 - Arturo Hernandez
嗨,安装Bootstrap.less只需安装.less和.js文件你的应用程序内容/脚本文件夹。安装dotless会在web.config中添加一些条目。 - Ingo
最重要的是,nugets不会覆盖任何东西,由你决定如何使用它们。您可以将.less文件预编译为css,但这不是我想要做的。下面的解决方案将使您的应用程序能够从较少的时间编译css,并且由于我的轻微修改允许您将多个目录作为.less-files的源。 - Ingo
嘿,似乎微软也意识到捆绑过程无法正确应用相关目录。所以他们已经宣布用VS 2013解决这个问题......甚至可能更新了WebEssentials? - Ingo


答案:


如果您希望将bootstrap用作较少的文件,并且另外希望不再担心开发计算机以及生产计算机上的捆绑和缩小,则可以考虑使用以下方法。

注意:如果在启用DEBUGging时只使用Less-Files,则不需要所有这些;但是,只要您希望您的应用程序在Windows Azure等生产服务器上运行,并且仍然只想修改较少的文件而不必关心捆绑和缩小程序......那么......这种方法将会工作

所以为了解决这个问题,我觉得有点陷入困境,我不得不以不同的方式处理问题,并且不得不修改(参见后面的修改2)我认为我想要的“BundleSource”。

所以不要忘记阅读本答案底部的第二次修改/警告!


10
2018-03-27 00:02



太棒了,你救了我的一天(或者节省了我一天的工作) - 谢谢! - Sebastian K
关于不允许以“〜/ Content”开头的包的提示+1。 - Mark Meuer


我已经修改了Ingo解决方法来摆脱每个目录的自定义类。 此外,我添加了适当的异常输出(因为否则所有异常都是静默的,如果出现错误,您只需要空文件少)。

public class LessTransform : IItemTransform
{
    [ThreadStatic]
    internal static string CurrentParsedFileDirectory;


    public string Process (string includedVirtualPath, string input)
    {
        CurrentParsedFileDirectory = Path.GetDirectoryName (includedVirtualPath);

        var config = new DotlessConfiguration
        {
            MinifyOutput = false,
            CacheEnabled = false,
            MapPathsToWeb = true,
            ImportAllFilesAsLess = true,
            LessSource = typeof (VirtualFileReader),
            Logger = typeof (ThrowExceptionLogger)
        };

        return Less.Parse (input, config);
    }
}


internal class VirtualFileReader : IFileReader
{
    public bool UseCacheDependencies
    {
        get { return false; }
    }


    public byte[] GetBinaryFileContents (string fileName)
    {
        return File.ReadAllBytes (GetFullPath (fileName));
    }


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


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


    public string GetFullPath (string path)
    {
        if (string.IsNullOrEmpty (path))
            return string.Empty;

        return HostingEnvironment.MapPath (path[0] != '~' && path[0] != '/'
                                               ? Path.Combine (LessTransform.CurrentParsedFileDirectory, path)
                                               : path);
    }
}


public class ThrowExceptionLogger : Logger
{
    public ThrowExceptionLogger (LogLevel level) : base (level)
    {
    }


    protected override void Log (string message)
    {
        if (string.IsNullOrEmpty (message))
            return;

        if (message.Length > 100)
            message = message.Substring (0, 100) + "...";

        throw new LessTransformException (message);
    }
}


[Serializable]
public sealed class LessTransformException : Exception
{
    public LessTransformException (string message) : base (message)
    {
    }
}

用法:

bundles.Add (new StyleBundle ("~/styles-bundle/common")
    .Include ("~/content/bootstrap/bootstrap.less", new LessTransform ()));

3
2017-12-25 12:26



可爱,谢谢:-)尤其是添加异常处理的想法......不知怎的,我一定忘记了 - 嗯 - 我想我已经习惯了只检查空的少文件;-) - Ingo
使用它,它只是工作:)竖起大拇指 - Michael Kire Hansen


我今天遇到了同样的问题,我找到了解决办法,但我也想要一个更好的解决方案。我也试图像你拥有的那样使用无点和自定义变换。

解决方法:

预建活动:

"$(SolutionDir)packages\dotless.1.3.1.0\tool\dotless.compiler.exe" "$(ProjectDir)Content\less\bootstrap.less"

这将创造一个 bootstrap.css 然后您可以将其包含为常规文件 CSS 代替 LESS

这个解决方案并不理想,因为每次更新无点时都必须更新构建事件,并且使用bundle处理它也更清晰。


2
2018-03-13 08:04



我已经考虑过预编译它,但我真的更喜欢有人知道如何修复内置行为。我实际上期望asp.net-mvc内置捆绑和缩小为我做那个Job。每当我更改设置时,我都不是“我必须记住......”的粉丝。到目前为止,我没有得到这个工作,但将继续尝试。再次感谢解决方法! - Ingo


我真的,真的建议安装 WebEssentials 2012 代替。

它会从你的.less生成一个css文件和一个缩小的css文件,你可以引用css。它会在你每次更改你的.less时自动更新css,所以不需要记住任何预构建步骤或任何东西......

安装WebEssentials时,您还可以获得其他甜蜜的功能,如CoffeeScript,TypeScript和LESS的预览。 JSHint,自动缩小和更多“好东西”!


0
2018-06-25 08:46



是的,WebEssentials 2012就是这样做的,但我必须引用css,而我的解决方案允许我修改我的“LESS”文件而不需要做任何事情......我的解决方案是否完美?可能不是,它优雅吗?也许不是,但我可以在我的懒惰规模上给它奖励很多点:-)然而我完全同意在最终的生产系统中我更喜欢使用预编译的css文件 - Ingo
我不是说你的解决方案不优雅。我只是说没有自定义代码和NuGet包的另一种方式。我知道它违背了我们作为开发人员的本性,但是当你可以在商店购买时,我们不需要建造一扇门(或者在这种情况下,免费获得一个!)。 ;-) - RickardN
+1:够了:-) - Ingo
好吧,遗憾的是,Visual Studio 2010上没有WebEssentials 2012 - MEYWD
在VS2010达到EOL之前差不多还有一年......不是生活中的婊子! ;) - RickardN