261

我对 mvc4 bundler 有一个奇怪的问题,不包括扩展名为 .min.js 的文件

在我的 BundleConfig 类中,我声明

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/Scripts/jquery")
        .Include("~/Scripts/jquery-1.8.0.js")
        .Include("~/Scripts/jquery.tmpl.min.js"));            
}

在我看来,我声明

<html>
    <head>
    @Scripts.Render("~/Scripts/jquery")
    </head><body>test</body>
</html>

当它渲染时,它只渲染

<html>
    <head>
         <script src="/Scripts/jquery-1.8.0.js"></script>
    </head>
    <body>test</body>
</html>

如果我将 jquery.tmpl.min.js 重命名为 jquery.tmpl.js(并相应地更新包中的路径),两个脚本都会正确呈现。

是否有一些配置设置导致它忽略“.min.js”文件?

4

9 回答 9

257

我最初发布的解决方案是有问题的(是一个肮脏的黑客)。正如许多评论者所指出的,调整后的行为在 Microsoft.AspNet.Web.Optimization 包中发生了变化,并且调整不再起作用。现在我完全无法使用 1.1.3 版的软件包重现该问题。

请参阅 System.Web.Optimization.BundleCollection 的来源(例如,您可以使用dotPeek),以更好地了解您将要做什么。另请阅读Max Shmelev 的回答

原始答案

将 .min.js 重命名为 .js 或执行类似的操作

    public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
    {
        if (ignoreList == null)
            throw new ArgumentNullException("ignoreList");
        ignoreList.Ignore("*.intellisense.js");
        ignoreList.Ignore("*-vsdoc.js");
        ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
        //ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
        ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
    }

    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.IgnoreList.Clear();
        AddDefaultIgnorePatterns(bundles.IgnoreList);
        //NOTE: it's bundles.DirectoryFilter in Microsoft.AspNet.Web.Optimization.1.1.3 and not bundles.IgnoreList

        //...your code
     }
于 2012-08-17T11:53:38.987 回答
180

微软暗示了以下行为(我更喜欢在我的项目中遵循它):

简洁版本

  1. 您在同一文件夹下的项目中同时拥有调试版本和缩小版本的脚本:
    • 脚本.js
    • 脚本.min.js
  2. 您只将script.js添加到代码中的包中。

因此,您将自动script.js包含在DEBUG模式中,并将script.min.js包含在RELEASE模式中。

长版

你也可以有.debug.js版本。在这种情况下,该文件包含在 DEBUG 中的以下优先级中:

  1. script.debug.js
  2. 脚本.js

在发布:

  1. 脚本.min.js
  2. 脚本.js

笔记

顺便说一句,在 MVC4 中拥有.min版本的脚本的唯一原因是无法自动处理缩小版本的情况。例如以下代码不能自动混淆:

if (DEBUG) console.log("Debug message");

在所有其他情况下,您可以只使用脚本的调试版本。

于 2012-10-15T17:39:36.430 回答
5

如果您只有文件的缩小版本,我发现的最简单的解决方案是复制缩小文件,从复制的文件名中删除 .min ,然后在捆绑包中引用非缩小文件名。

例如,假设您购买了一个 js 组件,他们给了您一个名为 some-lib-3.2.1.min.js 的文件。要在捆绑包中使用此文件,请执行以下操作:

  1. 复制 some-lib-3.2.1.min.js 并将复制的文件重命名为 some-lib-3.2.1.js。在项目中包含这两个文件。

  2. 引用包中的非缩小文件,如下所示:

    bundles.Add(new ScriptBundle("~/bundles/libraries").Include(
        "~/Scripts/some-lib-{version}.js"
    ));
    

仅仅因为名称中没有“min”的文件实际上被缩小了,不应该引起任何问题(除了它本质上不可读的事实)。它仅在调试模式下使用,并作为单独的脚本写出。当不处于调试模式时,预编译的 min 文件应包含在您的包中。

于 2013-12-10T16:20:58.217 回答
4

我找到了一个至少在 MVC5 中有效的好解决方案,你可以使用Bundle而不是ScriptBundle. ScriptBundle在这种情况下,它没有我们不喜欢的智能行为(忽略 .min 等)。在我的解决方案中,我使用Bundle带有 .min 和 .map 文件的 3d 派对脚本,并ScriptBundle用于我们的代码。我没有注意到这样做的任何缺点。要使其以这种方式工作,您需要添加原始文件,例如 angular.js,它将在调试中加载 angular.js,并在发布模式下捆绑 angular.min.js。

于 2015-07-15T11:16:50.473 回答
3

要渲染*.min.js文件,您必须禁用BundleTable.EnableOptimizations,这是适用于所有包的全局设置。

如果您只想为特定包启用优化,您可以创建自己的ScriptBundle类型,在枚举包中的文件时临时启用优化。

public class OptimizedScriptBundle : ScriptBundle
{
    public OptimizedScriptBundle(string virtualPath)
        : base(virtualPath)
    {
    }

    public OptimizedScriptBundle(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath)
    {
    }

    public override IEnumerable<BundleFile> EnumerateFiles(BundleContext context)
    {
        if (context.EnableOptimizations)
            return base.EnumerateFiles(context);
        try
        {
            context.EnableOptimizations = true;
            return base.EnumerateFiles(context);
        }
        finally
        {
            context.EnableOptimizations = false;
        }
    }
}

使用OptimizedScriptBundle而不是ScriptBundle用于应始终使用缩小文件的捆绑包,无论是否存在非缩小文件。

用于 ASP.NET MVC 的 Kendo UI 示例,它仅作为缩小文件的集合分发。

bundles.Add(new OptimizedScriptBundle("~/bundles/kendo")
        .Include(
            "~/Scripts/kendo/kendo.all.*",
            "~/Scripts/kendo/kendo.aspnetmvc.*",
            "~/Scripts/kendo/cultures/kendo.*",
            "~/Scripts/kendo/messages/kendo.*"));
于 2016-04-20T11:54:39.650 回答
2

就我而言,我使用的是(太棒了!)Knockout.js 库,它作为 Debug/Non 版本提供:

"~/Scripts/knockout-{Version}.js"
"~/Scripts/knockout-{Version}.Debug.js"

为了完成这项工作,我在我的 Bundle 中包含了“Knockout-{Version}.js”(非调试)并获得了 .debug。调试模式下的 js 文件。

于 2012-11-15T06:04:54.537 回答
1

一种简单的方法是重命名 .min 文件,例如您有 abc.min.css,而不是将此文件重命名为 abc_min.css 并将其添加到您的包中。我知道这不是正确的方法,而只是一个临时解决方案。谢谢和快乐的编码。

于 2014-07-09T05:56:49.520 回答
0

Bundler 有很多好处检查这个页面 但是

Microsoft MVC4 平台认为您至少有每个脚本或样式包的缩小版本和未缩小版本(也可以使用其他文件,如 Debug 和 vsdoc)。所以我们在只有这些文件之一的情况下会遇到麻烦。

您可以永久更改 web.config 文件中的调试状态以处理输出:

<compilation debug="false" targetFramework="4.0" />

查看输出变化!文件过滤已更改。为了达到目的,我们必须改变会改变应用程序逻辑的忽略大小写过滤!

于 2013-08-19T20:47:08.377 回答
-21

伙计们,我只会保留它,直到微软一起行动

试试这个

在 RegisterBundles 中为 Kendo 创建这个包

bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
                    "~/Content/kendo/2012.3.1121/kendo.common.min.css",
                     "~/Content/kendo/2012.3.1121/kendo.dataviz.min.css",
                      "~/Content/kendo/2012.3.1121/kendo.blueopal.min.css"
 ));

在 _Layout.cshtml 中输入:

@if (HttpContext.Current.IsDebuggingEnabled)
 { 
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.common.min.css")"      
rel="stylesheet"  type="text/css" />
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.dataviz.min.css")" 
rel="stylesheet" type="text/css" />   
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.blueopal.min.css")"    
rel="stylesheet" type="text/css" />
 }
 else
 {
     @Styles.Render("~/Content/kendo/css")   
 }

通过这种方式,我们在生产中获得了最好的捆绑包,并在调试中获得了参考

当微软修复他们的 MVC 4 代码时修复它

于 2012-12-11T05:29:42.163 回答