MVC4 Beta压缩和捆绑:文件排序和浏览器调试

14

我开始使用MVC4 Beta附带的打包和缩小功能,但是我遇到了一些问题:

首先,如果我使用经典的<script src="Folder/js" type="text/javascript"/> 打包方式,似乎我必须重命名我的文件以确保它们按正确的顺序打包。

  • 假设我有三个JavaScript文件:“ants.js”、“bugs.js”、“insects.js”
  • “ants.js”依赖于“bugs.js”
  • “bugs.js”依赖于“insects.js”
  • 默认的打包方式似乎按字母顺序打包它们。
  • 为了使它们正确打包,我必须将它们重命名为:“0.insects.js”、“1.bugs.js”、“2.ants.js”
  • 这很不专业,肯定有更好的办法。

我遇到的下一个问题是调试。我希望在测试浏览器中逐步执行JavaScript代码,是否有一种方法在DEBUG模式下仅关闭缩小?

编辑:请注意,我知道我可以从C#创建并注册捆绑包,但这种方法看起来非常丑陋。


相关问题 - https://dev59.com/oGox5IYBdhLWcg3wLhei - resnyanskiy
4个回答

11

为了临时获得非压缩的输出,请使用此方法

  public class NonMinifyingJavascript : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse bundle)
    {
        if(bundle == null)
        {
            throw new ArgumentNullException("bundle");
        }

        context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

        foreach(FileInfo file in bundle.Files)
        {
            HttpContext.Current.Response.AddFileDependency(file.FullName);
        }

        bundle.ContentType = "text/javascript";
        //base.Process(context, bundle);
    }
}

如果你希望根据配置设置来完全基于此进行操作,我想你可以创建一个IBundle转换器,根据你的配置设置委托给这个或JsMinify

为了控制javascript文件的顺序,您需要使用BundleFileSetOrdering。

 var javascriptBundle = new Bundle("~/site/js", new NonMinifyingJavascript());

         //controls ordering for javascript files, otherwise they are processed in order of AddFile calls
         var bootstrapOrdering = new BundleFileSetOrdering("bootstrap");
         //The popover plugin requires the tooltip plugin
         bootstrapOrdering.Files.Add("bootstrap-tooltip.js");
         bootstrapOrdering.Files.Add("bootstrap-popover.js");
         BundleTable.Bundles.FileSetOrderList.Add(bootstrapOrdering);
         javascriptBundle.AddDirectory("~/Scripts", "bootstrap-*.js");

这正好做我需要的事情,可惜不能更无缝地完成,但我会接受现有的结果。 - Ben Lesh

7

我使用MVC默认的NoTransform,而不是chrisortman提出的NonMinifyingJavascript。据我所知,它们的功能相同。 但仍不是最优解。理想情况下,当我想要调试时,我希望每个独立的脚本文件都有一个脚本标签。这使得使用VS11进行调试更加容易(只需一个调试器即可在一个调试会话中调试JS和C#)。 所以我创建了这个小助手:

@helper RenderScriptTags(string virtualPath)
{
    if (Minify /* some appsetting */)
    {
        <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(virtualPath)"></script>
    }
    else
    {
        foreach (var file in System.Web.Optimization.BundleResolver.Current.GetBundleContents(virtualPath))
        {
            <script src="@Url.Content(file)"></script>
        }
    }
}

@RenderScriptTags("~/libraries")

我有一个单页面应用程序,所以我在我的主cshtml文件中包含了这个代码,但是通过将此移动到htmlhelper扩展方法中,它很容易被泛化。效果不错!
如果您设置了BundleFileSetOrdering,则此代码也会考虑其中的内容!

2
也可以看一下RequestReduce。它会根据页面布局来捆绑脚本和CSS,无需编码或配置。它还允许您通过Web.config或通过查询字符串参数RRFilter=disabled关闭捆绑和缩小。

1
这真的很有趣,我可能最终会使用类似的东西。但是,我的一部分确实想坚持使用 MVC 4 打包的内容。 - Ben Lesh
1
如果这能让你稍微安慰一下,这是在许多 MSDN/Technet 属性上使用的东西,包括 MSDN 博客中的捆绑/缩小。 - Matt Wrock
哈哈..我很高兴你理解我需要安慰...因为我确实需要。我有点失望于这个新的神奇功能。 - Ben Lesh
RequestReduce似乎已经从http://requestreduce.com/迁移到http://requestreduce.org/。 - dumbledad

1

昨天我遇到了同样的问题,而且在新的System.Web.Optimization命名空间中找不到好的解决方案。有一些损坏的MSDN链接,所以一切都处于测试版意味着它可能会改变,但我岔开了话题...

您始终可以在开发期间和生产期间以不同的方式加载脚本。使用AppSetting很容易实现:

@if (System.Configuration.
    ConfigurationManager.AppSettings["BundleResources"] != null)
{
    @* load the css & js using bundles *@
}
else
{
    @* load the css & js files individually*@
}

然后,您可以通过在web.config中注释掉一个appsetting来启用/禁用优化功能:

<appSettings>
    ...
    <!--<add key="BundleResources" value="uhuh" />-->
    ...
</appSettings>

哎呀,这太次优了。看起来他们只是制作了功能,但还没有自己使用过。我无法想象它会保持这种状态很长时间。 - Ben Lesh
顺便提一下,我之前用编译器指令 @{ #if DEBUG } 做过类似的事情,但感觉很丑陋。 - Ben Lesh
哈哈,是的,我已经看到一些地方改变了API(新的JsMinify()而不是typeof(JsMinify))。我想这种情况不会持续太久。如果捆绑/缩小很重要,也可以查看Matt广告的RequestReduce。 - danludwig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接