【问题标题】:Don't uglify certain file when using Microsoft Web Optimization Framework使用 Microsoft Web 优化框架时不要丑化某些文件
【发布时间】:2014-05-26 04:46:36
【问题描述】:

我正在尝试使用Microsoft Web Optimization framework 将大量 .js 文件合并为一个文件。一切正常,但在这些文件中,我有几个已经缩小和丑化了,不需要再次处理它们。

例如,我有 recaptcha_ajax.js 文件,它在附加时会导致以下错误:

/* Minification failed. Returning unminified contents.
(715,29-36): run-time error JS1019: Can't have 'break' outside of loop: break t
(714,293-300): run-time error JS1019: Can't have 'break' outside of loop: break t
(678,210-217): run-time error JS1019: Can't have 'break' outside of loop: break t
(671,1367-1374): run-time error JS1019: Can't have 'break' outside of loop: break t
(665,280-287): run-time error JS1019: Can't have 'break' outside of loop: break t
 */

我试图从包中取出 recaptcha_ajax.js 并直接引用它,但随后会弹出其他错误 - 所以,我需要包中某个位置的那个文件。

我只需要能够说 - 不要缩小和丑化 recaptcha_ajax.js - 只需将其添加到包中。

有没有办法做到这一点?这是我的看法:

var b = new ScriptBundle("~/bundles/myjsbundle");

b.IncludeDirectory("~/ScriptsMine/", "*.js", true);

// some command like:
// b.DoNotMinifyOrUglify("~/ScriptsMine/recaptcha_ajax.js");

bundles.Add(b);

【问题讨论】:

  • 你是在scriptmanager中绑定的吗?

标签: c# asp.net asp.net-optimization


【解决方案1】:

捆绑包使用IItemTransform 的集合转换每个文件并连接结果。然后它使用IBundleTransform 的集合转换结果。

默认脚本包通过使用JsMinify(实现IBundleTransform)来缩小完整的包内容。

因此,为了防止某些文件缩小,您必须创建自己的 IBundleBuilder,它使用 IItemTransform 逐个文件缩小捆绑文件。

public class CustomScriptBundle : Bundle
{
    public CustomScriptBundle(string virtualPath)
        : this(virtualPath, null)
    {
    }

    public CustomScriptBundle(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath, null)
    {
        this.ConcatenationToken = ";" + Environment.NewLine;
        this.Builder = new CustomBundleBuilder();
    }
}


public class CustomBundleBuilder : IBundleBuilder
{
    internal static string ConvertToAppRelativePath(string appPath, string fullName)
    {
        return (string.IsNullOrEmpty(appPath) || !fullName.StartsWith(appPath, StringComparison.OrdinalIgnoreCase) ? fullName : fullName.Replace(appPath, "~/")).Replace('\\', '/');
    }

    public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
    {
        if (files == null)
            return string.Empty;
        if (context == null)
            throw new ArgumentNullException("context");
        if (bundle == null)
            throw new ArgumentNullException("bundle");

        StringBuilder stringBuilder = new StringBuilder();
        foreach (BundleFile bundleFile in files)
        {
            bundleFile.Transforms.Add(new CustomJsMinify());
            stringBuilder.Append(bundleFile.ApplyTransforms());
            stringBuilder.Append(bundle.ConcatenationToken);
        }

        return stringBuilder.ToString();
    }
}

public class CustomJsMinify : IItemTransform
{
    public string Process(string includedVirtualPath, string input)
    {
        if (includedVirtualPath.EndsWith("min.js", StringComparison.OrdinalIgnoreCase))
        {
            return input;
        }

        Minifier minifier = new Minifier();
        var codeSettings = new CodeSettings();
        codeSettings.EvalTreatment = EvalTreatment.MakeImmediateSafe;
        codeSettings.PreserveImportantComments = false;

        string str = minifier.MinifyJavaScript(input, codeSettings);

        if (minifier.ErrorList.Count > 0)
            return "/* " + string.Concat(minifier.Errors) + " */";

        return str;
    }
}

然后使用CustomScriptBundle 而不是ScriptBundle

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new CustomScriptBundle("~/bundles/Sample").Include(
                "~/Scripts/a.js",
                "~/Scripts/b.js",
                "~/Scripts/c.js"));
}

如果您提供min.js 文件,它将被使用而不是缩小它。

【讨论】:

  • 这不处理当包包含库的最小和非最小版本的情况,对吧?它应该在配置文件中使用 来决定使用哪一个。可以在 BuildBundleContent 方法中的 foreach 之前添加此处理。
  • 此代码未经过全面测试,因此您可以进行一些更改以使其正常工作
【解决方案2】:

优化框架会考虑文件名。

尝试将您的 *.js 文件重命名为 recaptcha_ajax.min.js。如果我是正确的,那么它应该跳过 uglify/minify 过程。

参考数据:http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification (向下滚动一点可以找到这句话:)

前面的代码创建了一个名为 ~/bundles/jquery 包含所有适当的(即调试或 Scripts 文件夹中与 通配符字符串“~/Scripts/jquery-{version}.js”。对于 ASP.NET MVC 4, 这意味着使用调试配置,文件 jquery-1.7.1.js 将 被添加到捆绑包中。在发布配置中, jquery-1.7.1.min.js 将被添加。捆绑框架如下 几种常见的约定,例如:

  • 当“FileX.min.js”和“FileX.js”存在时选择“.min”文件发布。
  • 选择非“.min”版本进行调试。
  • 忽略仅由 IntelliSense 使用的“-vsdoc”文件(例如 jquery-1.7.1-vsdoc.js)。

【讨论】:

  • 如果它像这样工作,那就太棒了。但是,它似乎没有——我已经创建了单独的 hello.js 和 hello.min.js 来进行测试,并且无论 .min 是多少,它都会缩小。名义上。也许我错过了一些设置?
  • 你试过在发布模式下运行它吗?它应该以这种方式工作:s
  • 我认为这只是糟糕的工程 - Web 优化框架有很多开关,似乎直接改变捆绑构建过程是控制它的唯一方法。示例:无论 Debug/Release 模式如何,BundleTable.EnableOptimizations 优先(这是一件好事)。如果 BundleTable.EnableOptimizations = false,将选择 script.js 文件。为真,script.min.js。但是 - 无论文件名如何,两个文件都将被缩小。如果他们开源代码,我会很高兴,这样我们就可以在设计决策上帮助他们一点(即没有缩小文件名中的 .min.js)。
【解决方案3】:

如果您在 ScriptManager 中捆绑 .js 文件,您会注意到脚本是在 &lt;form&gt; 中加载的,而不是在 &lt;head&gt; 中,因此将其从捆绑包中拉出会在其他文件之前加载该文件,这不好如果它依赖于捆绑中的其他东西

这是一个需要按特定顺序添加到捆绑包中的库示例。
这是添加到 App_Start/BundleConfig.vb

'############################################################
' This is a ScriptManager Resource Definition 
' for use in a ScriptManager mapping
'############################################################
    Dim ResourceDef as ScriptResourceDefinition = New ScriptResourceDefinition()
    Dim ResourceName as  String = "ColorBox"

    'add the Resource Definition details
    ResourceDef.Path = "~/Scripts/colorbox/jquery.colorbox-min.js"
    ResourceDef.DebugPath = "~/Scripts/colorbox/jquery.colorbox.js"

    ScriptManager.ScriptResourceMapping.AddDefinition(ResourceName, ResourceDef)
'############################################################

注意ResourceDef.PathResourceDef.DebugPath 的使用。 包含哪个文件将取决于您进行调试或发布发布

  • 调试:没有“丑化”
  • 发布:完全“丑化”

这是我的 ScriptManager 包,注意 ColorBox 的位置,位置意义重大:

<asp:ScriptManager runat="server" >
    <Scripts>
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="ColorBox" />          
        <asp:ScriptReference Name="Infragistics" /> 
        <asp:ScriptReference Name="MsAjaxBundle" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
    </Scripts>
</asp:ScriptManager>

【讨论】:

    猜你喜欢
    • 2013-05-07
    • 1970-01-01
    • 2016-05-14
    • 2012-09-04
    • 1970-01-01
    • 2012-08-19
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多