捆绑软件不包括.min文件


261

我对mvc4捆绑器有一个奇怪的问题,不包括扩展名为.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”文件?


我正在使用MVC 4捆绑程序,其中包括.min.js文件。
Eric J.

RTM版本还是RC?对于我来说,在RC中也可以正常工作
致命的

10
这个想法是在调试模式下工作,将使用不带缩小版本的“ dev”版本,而在非调试模式下,则选择缩小版本。要查看其运行情况,请将web.config调试值从true更改为false。
Pieter Germishuys 2012年

28
在某些情况下,您没有脚本的非缩小版本。如果两个文件都存在,我可能理解。
致命的2012年

1
很遗憾,默认情况下它像这样工作...当然,该文件可能已经缩小了,但是我认为Microsoft未能看到将预缩小的脚本添加到bundle中以消除缓存的好处(漂亮的小v参数哈希)会添加到url,并在文件内容更改时更改)
没必要,2015年

Answers:


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
     }

4
也感谢我-所以将其添加到我的MVC4陷阱列表中:)
Dan B

27
这是很长的wtf时刻,他们本可以添加那些注释掉的min文件,这些注释是有原因的或会导致某些结果的,但现在却浪费了整整一个小时,想知道是谁在偷我的脚本文件从输出中窃取。
Giedrius 2012年

5
根据OP中Fatal的评论,如果缩小版本和常规版本同时存在(例如jquery),则该解决方案将最终为缩小版本和常规版本重新生成重复引用。
danmiser 2012年

11
M $,当明确指定somefile.min.js或仅存在.min.js文件时,则仅包含.min.js文件!否则,请应用当前行为!
Adaptabi

3
难以置信的是,实际的类称为“ IgnoreList”,但它直接从Object派生。没有LINQ,没有迭代。- msdn.microsoft.com/en-us/library/...
JP 10贝格

176

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

精简版

  1. 您的项目中的脚本的调试版本和精简版本都在同一文件夹下:
    • script.js
    • script.min.js
  2. 您仅将script.js添加到代码中的包中。

结果,您将自动使DEBUG模式中包含script.js和在RELEASE模式中包含script.min.js

长版

您也可以使用.debug.js版本。在这种情况下,文件将包含在DEBUG中的以下优先级中:

  1. script.debug.js
  2. script.js

在发布中:

  1. script.min.js
  2. script.js

注意

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

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

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


6
但是,很好的解释是,OP的问题在于某些脚本(jquery.tmpl)没有,没有附带,没有下载文件的非最小版本。如果捆绑程序在调试模式下没有非Min版本,则捆绑程序将完全忽略脚本文件
Eonasdan 2012年

同意,很好的解释,但它并未回答OP的所有问题。
迭戈

2
短版对我不起作用。这两个发行类型都将包含“ script.js”。我切换了DEBUG / RELEASE,(当我查看源代码时)“ script.js”是选中/渲染的那个。
user981375 2012年

4
user981375,还需要在web.config文件中设置<compilation debug =“ false” />
Max Shmelev 2012年

5
我更喜欢这个答案,因为它是一种“最佳实践”方法,并说明了如何遵循捆绑程序的默认规则来实现相同的目标。
James Reategui 2013年

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文件应包含在您的捆绑软件中。


4

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


停用优化功能(ScriptTable.EnableOptimizations = false)后,它似乎不起作用。包含模式的脚本路径不会呈现(例如~/Scripts/thirdpartylib/*.js)。它确实可以正常工作EnableOptimizations = true,但是确实可以ScriptBundle
史蒂文·里肯斯

我也将它与false一起使用(在开发过程中),并且我没有遇到您描述的问题,因此可能对您有影响的其他原因。您还需要执行IncludeDirectory而不是include才能使模式起作用。
Ilya Chernomordik

您确定它正在呈现文件的“ .min.js”版本吗?您是使用名称空间中System.Web.Optimizations的捆绑包还是nuget包中的捆绑包Microsoft.Web.Optimizations
史蒂文·里肯斯

我使用System.Web.Optimization并检查了它是否显示了最低版本,但是我发现我实际上并不使用IncludeDirectory,但是如果该版本不适用于最低版本,那将很奇怪。因为IncludeDirectory不是对我来说足够了,我进行了自定义扫描,并使用Include添加了所​​有过滤器,因此,虽然模式和IncludeDirectory有点奇怪,但可能在那里无法正常工作。
Ilya Chernomordik

1
否,问题有两个:仅有一个.min.js文件存在,并且*.js模式与以结尾的文件不匹配.min.js
史蒂文·里肯斯

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应始终使用其缩小文件的捆绑软件,无论是否存在非缩小文件。

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

bundles.Add(new OptimizedScriptBundle("~/bundles/kendo")
        .Include(
            "~/Scripts/kendo/kendo.all.*",
            "~/Scripts/kendo/kendo.aspnetmvc.*",
            "~/Scripts/kendo/cultures/kendo.*",
            "~/Scripts/kendo/messages/kendo.*"));

我在生产发布操作中遇到了一些缺少的脚本,并以为这是MVC问题,所以我找到了这个答案。与它合作太久了,我想尽一切办法摆脱剑道
Felipe

@Felipe我处于同样的情况,这就是为什么我写这个答案的原因。剑道太可怕了。希望我的例子对您有所帮助。
史蒂文·里肯斯

2

就我而言,我使用的是(Wonderful!)Knockout.js库,它是Debug / Non版本的:

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

为了使此工作有效,我在捆绑包中包含了“ Knockout- {Version} .js”(非调试),并获得了.debug。调试模式下的js文件。


1

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


1
每次nuget下载文件时,都需要重命名。
Anirudha Gupta

我知道这不是正确的方法,而只是一个临时解决方案
RK Sharma

1
把这行对我有用// BundleTable.EnableOptimizations = true;
Anirudha Gupta

0

Bundler有很多好处,请检查此页面,

Microsoft MVC4平台认为每个脚本或样式捆绑包都至少具有最小版本和未最小版本(也提供Debug和vsdoc等其他文件)。因此,在只有这些文件之一的情况下,我们会遇到麻烦。

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

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

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


1
添加debug =“ false”仍然对我不起作用。即使我也清除了IgnoreList,min.js文件仍然不包括在内
MoSs 2013年

-21

伙计们,我只保留它,直到微软让它共同行动为止。

试试这个

在RegisterBundles中为剑道创建此捆绑包

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")   
 }

这样,我们可以在生产中获得最佳捆绑,并在调试中获得参考

Microsoft修复其MVC 4代码时进行修复


3
我根本不喜欢这种提议的解决方案。您现在必须在(至少)两个地方维护脚本集
致命的

这几乎破坏了捆绑的目的,您不觉得吗?
奥利弗

4
捆绑已经可以这种方式工作了。如果您以调试模式运行项目,则每个CSS文件都会单独加载,但是在发行版中运行时,它们会合并并缩小为一个文件。if块中的代码与在调试模式下自动在页面上呈现的代码相同。
乍得利维
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.