从Minifying中删除单个文件?

时间:2013-02-25 15:57:11

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

我正在尝试使用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错误。)

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

4 个答案:

答案 0 :(得分:2)

所以问题是所有文件都捆绑在一起,然后整个捆绑包最小化。因此,您不会轻易地跳过一个文件的缩小。执行此操作的最佳方法可能是创建一个新的Transform,它会附加您想要无限制的此文件的内容。然后你将这个Transform附加到你注册的ScriptBundle:

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

AppendFileTransform只会将文件的内容附加到捆绑的响应中。您将不再明确地在包中包含timepicker,但是此变换将包含它,这将有效地为您提供您正在寻找的行为,因为JsMinify转换将首先运行并缩小包,然后您将添加你最终想要的文件是未经证实的。

答案 1 :(得分: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);

答案 2 :(得分:1)

您无法设置Bundle以跳过缩小某些文件并缩小其余文件。

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

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

答案 3 :(得分:0)

这只是基于郝功的答案的完整示例

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