捆绑程序不包括 .min 文件

IT技术 c# javascript asp.net-mvc-4 bundling-and-minification
2021-02-04 01:28:03

我对 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”文件?

6个回答

我最初发布的解决方案是有问题的(是一个肮脏的黑客)。正如许多评论者指出的那样,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
     }
令人难以置信的是,实际的类被称为“IgnoreList”,但它直接派生自 Object。没有 LINQ,没有迭代。- msdn.microsoft.com/en-us/library/...
2021-03-24 01:28:03
M$,当 somefile.min.js 被明确指定时,或者当只有 .min.js 文件存在时,那么只包含 .min.js 文件!否则就应用当前的行为!
2021-03-26 01:28:03
这是一个很长的wtf时刻,他们本可以添加那些因原因或结果而被注释掉的最小文件,现在整个小时都浪费在想知道谁在从输出中窃取我的脚本文件。
2021-03-31 01:28:03
根据 OP 中 Fatal 的评论,如果缩小版本和常规版本都存在(例如 jquery),则此解决方案最终将重新生成重复引用。
2021-04-08 01:28:03
也感谢我 - 所以将它添加到我的 MVC4 陷阱列表中 :)
2021-04-11 01:28:03

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

简洁版本

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

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

长版

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

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

发布中:

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

笔记

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

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

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

user981375,你还需要在web.config文件中设置<compilation debug="false" />
2021-03-19 01:28:03
我更喜欢这个答案,因为它是一种“最佳实践”方法,并解释了如何遵循打包程序的默认规则来实现相同的目标。
2021-03-25 01:28:03
同意,很好的解释,但它根本没有回答 OP 的问题。
2021-03-26 01:28:03
然而,很好的解释是,OP 的问题是某些脚本 ( jquery.tmpl) 没有、没有附带、没有下载文件的非最小版本。如果在调试模式下没有非最小版本,捆绑器会完全忽略脚本文件
2021-04-04 01:28:03
简短版本对我不起作用。“script.js”将包含在这两种发布类型中。我切换了 DEBUG/RELEASE 并且(当我查看源代码时)'script.js' 是选择/渲染的。
2021-04-07 01:28:03

如果您拥有的只是文件的缩小版本,我发现的最简单的解决方案是复制缩小的文件,从复制的文件名中删除 .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 文件应包含在您的包中。

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

不,问题有两个方面:仅.min.js存在一个文件,并且*.js模式与以.min.js.
2021-03-28 01:28:03
您确定它正在呈现文件的“.min.js”版本吗?您使用的是命名空间中System.Web.Optimizations的包还是 nuget 包中的包Microsoft.Web.Optimizations
2021-03-30 01:28:03
当优化被禁用 ( ScriptTable.EnableOptimizations = false)时,它似乎不起作用不呈现包含模式的脚本路径(例如~/Scripts/thirdpartylib/*.js)。何时起作用EnableOptimizations = true,但起作用ScriptBundle
2021-04-04 01:28:03
我也将它与 false 一起使用(在开发期间)并且我没有您描述的问题,因此它可能是其他影响它的东西。您还需要执行 IncludeDirectory 而不是 include 以使模式工作。
2021-04-04 01:28:03
我使用 System.Web.Optimization 并检查它是否呈现最小版本,但我发现我实际上不使用 IncludeDirectory,但如果它不适用于最小版本,那会很奇怪......因为 IncludeDirectory 不是对我来说足够了,我进行了自定义扫描并使用 Include 添加了所有过滤器,因此可能是模式和 IncludeDirectory 在那里无法正常工作,尽管这有点奇怪。
2021-04-04 01:28:03

要渲染*.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.*"));
@Felipe 我遇到了同样的情况,这就是我写这个答案的原因。剑道太可怕了 我希望我的例子有帮助。
2021-03-12 01:28:03
我在生产发布操作中遇到了一些丢失的脚本,并认为这是一个 MVC 问题,我找到了这个答案..瞧,涉及到剑道。使用它太久了,我不惜一切代价摆脱剑道
2021-03-16 01:28:03