【问题标题】:Skip single file from Minifying?从缩小中跳过单个文件?
【发布时间】:2013-02-10 20:00:47
【问题描述】:

我正在尝试使用 ASP.Nets BundleTable 来优化一些 javascript 文件,但遇到了一个问题,即在缩小代码时特定插件 (jQuery-Timepicker) 无法工作。见here

捆绑代码目前类似于:

// Add our commonBundle
var commonBundle= new Bundle("~/CommonJS" + culture.ToString());

// JQuery and related entries.
commonBundle.Include("~/Scripts/jquery-1.7.2.js");
commonBundle.Include("~/Scripts/jquery-ui-1.8.22.js");
commonBundle.Include("~/Scripts/jquery.cookie.js");
commonBundle.Include("~/Scripts/jquery-ui/jquery-ui-timepicker-addon.js"); // This is the one that does not work when bundled

// JS Transformer
commonBundle.Transforms.Add(new JsMinify());

BundleTable.Bundles.Add(commonBundle);

如果我删除 jquery-ui-timepicker-addon.js 文件,然后将其单独包含在我的网页中,那么它可以正常工作。 (否则我会收到Uncaught TypeError: undefined is not a function 错误)。

我想知道我是否可以以某种方式设置我的捆绑代码以跳过缩小这个文件(但它仍然包含在捆绑中)?我一直在环顾四周,但没有提出任何解决方案。

【问题讨论】:

  • 您不能将时间选择器的commonBundle.Include 行移到转换后吗?

标签: asp.net-mvc-3 asp.net-mvc-4 bundle asp.net-optimization system.web.optimization


【解决方案1】:

所以问题是所有文件都捆绑在一起,然后整个捆绑包被最小化。因此,您不会轻易地跳过一个文件的缩小。执行此操作的最佳方法可能是创建一个新的转换,该转换附加了您希望未缩小的该文件的内容。然后你会将此 Transform 附加到你注册的 ScriptBundle 中:

commonBundle.Transforms.Add(new AppendFileTransform(""~/Scripts/jquery-ui/jquery-ui-timepicker-addon.js""));

AppendFileTransform 只会将文件的内容附加到捆绑的响应中。您将不再显式地将时间选择器包含在捆绑包中,而是将其包含在此转换中,这将有效地为您提供您正在寻找的行为,因为 JsMinify 转换将首先运行并缩小捆绑包,然后您将添加最后你想要的文件未缩小。

【讨论】:

  • 是的,你是对的,但如果文件被修改,它不会重新创建包。在这种情况下可能可以接受,但不像一般解决方案。
  • 我在下面发布了请求的“提示”;)
【解决方案2】:

这可以从另一个方向更好地解决 - 与其尝试不缩小单个文件,不如为单个项目添加转换。

首先 - 创建一个实现 IItemTransform 的类并使用相同的代码来缩小给定的输入:

public class JsItemMinify : System.Web.Optimization.IItemTransform
{
    public string Process(string includedVirtualPath, string input)
    {
        var min = new Microsoft.Ajax.Utilities.Minifier();
        var result = min.MinifyJavaScript(input);
        if (min.ErrorList.Count > 0)
            return "/*minification failed*/" + input;

        return result;
    }
}

第二 - 将此项目转换添加到单个文件并删除捆绑转换:

var commonBundle= new Bundle("~/CommonJS");
// the first two includes will be minified
commonBundle.Include("~/Scripts/jquery-1.7.2.js", new JsItemMinify());
commonBundle.Include("~/Scripts/jquery-ui-1.8.22.js", new JsItemMinify());

// this one will not
commonBundle.Include("~/Scripts/jquery.cookie.js");

// Remove the default JsMinify bundle transform
commonBundle.Transforms.Clear();

BundleTable.Bundles.Add(commonBundle);

【讨论】:

    【解决方案3】:

    您不能将 Bundle 设置为跳过缩小某些文件并缩小其余文件。

    您可以通过覆盖Bundle.ApplyTransformJsMinify.Process 方法来实现自己的BundleTransform,但您需要注意不要破坏文件的更改跟踪、密钥生成、缓存失效等。 ..(或做一些丑陋的黑客)。这不值得。

    正如你已经提到的,我会保留单独的 js 文件。

    【讨论】:

      【解决方案4】:

      这只是基于郝恭的回答的完整示例

      var myBundle = new ScriptBundle("~/bundles/myBundle").Include(
          "~/Scripts/script1.js",
          "~/Scripts/script2.js",
      );
      myBundle.Transforms.Add(new AppendFileTransform("~/Scripts/excludedFile.min.js"));
      bundles.Add(myBundle);
      

      这里是 AppendFileTransform 的示例实现:

      public class AppendFileTransform : IBundleTransform
      {
          private readonly string _filePath;
      
          public AppendFileTransform(string filePath)
          {
              _filePath = filePath;
          }
      
          public void Process(BundleContext context, BundleResponse response)
          {
              response.Content += File.ReadAllText(context.HttpContext.Server.MapPath(_filePath));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多