我怎么能指定一个明确的ScriptBundle包括订单?(How can I specify an

2019-06-17 17:56发布

我想出来的MVC4 System.Web.Optimization 1.0 ScriptBundle功能 。

我有以下配置:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        // shared scripts
        Bundle canvasScripts =
            new ScriptBundle(BundlePaths.CanvasScripts)
                .Include("~/Scripts/modernizr-*")
                .Include("~/Scripts/json2.js")
                .Include("~/Scripts/columnizer.js")
                .Include("~/Scripts/jquery.ui.message.min.js")
                .Include("~/Scripts/Shared/achievements.js")
                .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(canvasScripts);
    }
}

和以下观点:

<script type="text/javascript" src="@Scripts.Url(BundlePaths.CanvasScripts)"></script>

其中BundlePaths.CanvasScripts"~/bundles/scripts/canvas" 。 它呈现这样的:

<script type="text/javascript" src="/bundles/scripts/canvas?v=UTH3XqH0UXWjJzi-gtX03eU183BJNpFNg8anioG14_41"></script>

到目前为止好,除了~/Scripts/Shared/achievements.js是捆绑源的第一个脚本。 这取决于包括之前的每脚本ScriptBundle我怎样才能确保它的荣誉,我加包含语句捆绑的顺序?

更新

这是一个相对较新的ASP.NET MVC应用4,但它引用的优化框架预先发布包。 我删除,并添加了来自RTM包http://nuget.org/packages/Microsoft.AspNet.Web.Optimization 。 随着RTM版本的调试=在web.config中真, @Scripts.Render("~/bundles/scripts/canvas")使得以正确的顺序各个脚本标签。

随着调试=假在web.config中,结合脚本首先有achievements.js剧本,但因为它的函数的定义(对象构造)这就是后来被称为,它在运行时错误。 也许minifier是足够聪明弄清楚的依赖?

我也试过IBundleOrderer实现,达林季米特洛夫建议用两种调试选项RTM和它的表现一样。

因此,缩小的版本是不是在我所期望的顺序,但它的作品。

Answer 1:

我没有看到在RTM位,您使用的是微软的ASP.NET Web优化框架1.0.0位此行为: http://nuget.org/packages/Microsoft.AspNet.Web.Optimization ?

我用了一个类似摄制来样,基于掀起了新MVC4互联网应用的网站。

我加入BundleConfig.RegisterBundles:

        Bundle canvasScripts =
            new ScriptBundle("~/bundles/scripts/canvas")
                .Include("~/Scripts/modernizr-*")
                .Include("~/Scripts/Shared/achievements.js")
                .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(canvasScripts); 

然后在默认的索引页,我说:

<script src="@Scripts.Url("~/bundles/scripts/canvas")"></script>

我证实,在捆绑包的精缩的JavaScript的achievements.js内容是Modernizr的后...



Answer 2:

你可以写一个自定义捆绑订货( IBundleOrderer ),这将确保束都包含在您注册的顺序排列:

public class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

然后:

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        var bundle = new Bundle("~/bundles/scripts/canvas");
        bundle.Orderer = new AsIsBundleOrderer();
        bundle
            .Include("~/Scripts/modernizr-*")
            .Include("~/Scripts/json2.js")
            .Include("~/Scripts/columnizer.js")
            .Include("~/Scripts/jquery.ui.message.min.js")
            .Include("~/Scripts/Shared/achievements.js")
            .Include("~/Scripts/Shared/canvas.js");
        bundles.Add(bundle);
    }
}

在您的视图:

@Scripts.Render("~/bundles/scripts/canvas")


Answer 3:

谢谢达林。 我已经添加的扩展方法。

internal class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

internal static class BundleExtensions
{
    public static Bundle ForceOrdered(this Bundle sb)
    {
        sb.Orderer = new AsIsBundleOrderer();
        return sb;
    }
}

用法

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js",
                    "~/Scripts/jquery-migrate-{version}.js",

                    "~/Scripts/jquery.validate.js",
                    "~/Scripts/jquery.validate.messages_fr.js",
                    "~/Scripts/moon.jquery.validation-{version}.js",

                    "~/Scripts/jquery-ui-{version}.js"
                    ).ForceOrdered());


Answer 4:

更新由SoftLion提供来处理MVC 5(包文件VS FileInfo的)变化的答案。

internal class AsIsBundleOrderer : IBundleOrderer
{
    public virtual IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

internal static class BundleExtensions
{
    public static Bundle ForceOrdered(this Bundle sb)
    {
        sb.Orderer = new AsIsBundleOrderer();
        return sb;
    }
}

用法:

    bundles.Add(new ScriptBundle("~/content/js/site")
        .Include("~/content/scripts/jquery-{version}.js")
        .Include("~/content/scripts/bootstrap-{version}.js")
        .Include("~/content/scripts/jquery.validate-{version}")
        .ForceOrdered());

我喜欢用流利的语法,但它也可以用一个方法调用和作为参数传递的所有脚本。



Answer 5:

你应该能够与BundleCollection.FileSetOrderList的帮助下设置的顺序。 看看这个博客帖子: http://weblogs.asp.net/imranbaloch/archive/2012/09/30/hidden-options-of-asp-net-bundling-and-minification.aspx 。 在您的实例中的代码会是这样的:

BundleFileSetOrdering bundleFileSetOrdering = new BundleFileSetOrdering("js");
bundleFileSetOrdering.Files.Add("~/Scripts/modernizr-*");
bundleFileSetOrdering.Files.Add("~/Scripts/json2.js");
bundleFileSetOrdering.Files.Add("~/Scripts/columnizer.js");
bundleFileSetOrdering.Files.Add("~/Scripts/jquery.ui.message.min.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/achievements.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/canvas.js");
bundles.FileSetOrderList.Add(bundleFileSetOrdering);


Answer 6:

您应该考虑使用盒式http://getcassette.net/它支持基于每个文件里面找到脚本引用脚本依赖自动检测。

如果你更喜欢坚持MS网络优化解决方案,但像基于脚本引用安排脚本的想法,你应该在阅读我的博客文章http://blogs.microsoft.co.il/oric/2013/12/27/building-single -page应用束-订货者/



Answer 7:

@Darin季米特洛夫的回答完全适用于我,但我的项目是用VB写的,所以这里是他的答案转换为VB

Public Class AsIsBundleOrderer
    Implements IBundleOrderer

    Public Function IBundleOrderer_OrderFiles(ByVal context As BundleContext, ByVal files As IEnumerable(Of FileInfo)) As IEnumerable(Of FileInfo) Implements IBundleOrderer.OrderFiles
        Return files
    End Function
End Class

使用方法:

Dim scriptBundleMain = New ScriptBundle("~/Scripts/myBundle")
scriptBundleMain.Orderer = New AsIsBundleOrderer()
scriptBundleMain.Include(
    "~/Scripts/file1.js",
    "~/Scripts/file2.js"
)
bundles.Add(scriptBundleMain)


文章来源: How can I specify an explicit ScriptBundle include order?