[asp.net-mvc] 명시적인 ScriptBundle 포함 순서를 어떻게 지정할 수 있습니까?

나는 밖으로 시도하고 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. 번들에 include 문을 추가하는 순서를 준수하는지 어떻게 확인할 수 있습니까?

최신 정보

이것은 비교적 새로운 ASP.NET MVC 4 응용 프로그램 이었지만 최적화 프레임 워크 사전 릴리스 패키지를 참조하고있었습니다. 나는 그것을 제거하고 http://nuget.org/packages/Microsoft.AspNet.Web.Optimization 에서 RTM 패키지를 추가했습니다 . web.config에서 debug = true 인 RTM 버전을 사용 @Scripts.Render("~/bundles/scripts/canvas")하면 개별 스크립트 태그를 올바른 순서로 렌더링합니다.

web.config에서 debug = false를 사용하면 결합 된 스크립트가 먼저 achievements.js 스크립트를 가지지 만 나중에 호출되는 함수 정의 (객체 생성자)이므로 오류없이 실행됩니다. 아마도 미니 파이어가 의존성을 알아낼만큼 똑똑할까요?

또한 IBundleOrdererDarin Dimitrov가 두 디버그 옵션을 사용하여 RTM에서 제안한 구현을 시도 했으며 동일하게 작동했습니다.

따라서 축소 된 버전은 내가 예상 한 순서가 아니지만 작동합니다.



답변

RTM 비트에서이 동작이 보이지 않습니다. Microsoft ASP.NET 웹 최적화 프레임 워크 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>

번들의 축소 된 자바 스크립트에서 achievements.js의 내용이 modernizr 이후임을 확인했습니다.


답변

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")


답변

다린 감사합니다. 확장 방법을 추가했습니다.

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


답변

MVC 5 (BundleFile vs FileInfo)의 변경 사항을 처리하기 위해 SoftLion에서 제공하는 답변을 업데이트했습니다.

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

나는 유창한 구문을 사용하는 것을 좋아하지만 단일 메서드 호출과 매개 변수로 전달 된 모든 스크립트에서도 작동합니다.


답변

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


답변

Cassette http://getcassette.net/ 사용을 고려해야 합니다. 각 파일에서 찾은 스크립트 참조를 기반으로 스크립트 종속성 자동 감지를 지원합니다.

MS 웹 최적화 솔루션을 선호하지만 스크립트 참조를 기반으로 스크립트를 배열하려는 아이디어가 마음에 들면 http://blogs.microsoft.co.il/oric/2013/12/27/building-single 에서 내 블로그 게시물을 읽어야합니다. -page-application-bundle-orderer /


답변

@Darin Dimitrov의 답변은 저에게 완벽하게 작동하지만 내 프로젝트는 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)