2013-02-08 2 views
14

CSS 파일 번들을 렌더링하려하지만 출력 순서가 잘못되었습니다. 나는 해결책을 시도했다 @MVC4 Beta Minification and Bundling: Ordering files and debugging in browser, 그러나 도움이되지 않았다. 당신이 JQuery와 - UI를 상단으로 오는 볼 수 있습니다 여기에 MVC4 StyleBundle이 번들을 올바른 순서로 렌더링하지 않습니다.

bundles.Add(new StyleBundle("~/stylesheet") 
    .Include("~/css/main.css") 
    .Include("~/css/mvc.css") 
    .Include("~/js/jquery.thickbox.css") 
    .Include("~/js/jquery.rating.css") 
    .Include("~/css/ProductListing.css") 
    .Include("~/css/dropdown/dropdown.css") 
    .Include("~/css/dropdown/dropdown.vertical.css") 
    .Include("~/js/fancybox/jquery.fancybox-1.3.1.css") 
    .Include("~/css/scartpopup.css") 
    .Include("~/css/ShoppingCart.css") 
    .Include("~/css/ceebox.css") 
    .Include("~/css/tooltip.css") 
    .Include("~/css/recent_blog_posts.css") 
    .Include("~/css/ProductDetail.css") 
    .Include("~/css/jquery-ui-1.7.3.custom.css") 
    .Include("~/css/filter_box.css") 
    .Include("~/css/custom_page.css") 
    .Include("~/css/Checkout.css") 
    .Include("~/css/CheckoutButton.css") 
); 

그리고

이 결과 다음은 번들입니다.

<link href="/css/jquery-ui-1.7.3.custom.css" rel="stylesheet"/> 
<link href="/css/main.css" rel="stylesheet"/> 
<link href="/css/mvc.css" rel="stylesheet"/> 
<link href="/js/jquery.thickbox.css" rel="stylesheet"/> 
<link href="/js/jquery.rating.css" rel="stylesheet"/> 
<link href="/css/ProductListing.css" rel="stylesheet"/> 
<link href="/css/dropdown/dropdown.css" rel="stylesheet"/> 
<link href="/css/dropdown/dropdown.vertical.css" rel="stylesheet"/> 
<link href="/js/fancybox/jquery.fancybox-1.3.1.css" rel="stylesheet"/> 
<link href="/css/scartpopup.css" rel="stylesheet"/> 
<link href="/css/ShoppingCart.css" rel="stylesheet"/> 
<link href="/css/ceebox.css" rel="stylesheet"/> 
<link href="/css/tooltip.css" rel="stylesheet"/> 
<link href="/css/recent_blog_posts.css" rel="stylesheet"/> 
<link href="/css/ProductDetail.css" rel="stylesheet"/> 
<link href="/css/filter_box.css" rel="stylesheet"/> 
<link href="/css/custom_page.css" rel="stylesheet"/> 
<link href="/css/Checkout.css" rel="stylesheet"/> 
<link href="/css/CheckoutButton.css" rel="stylesheet"/> 

스타일 시트가 올바른 순서로 렌더링되는지 어떻게 확인할 수 있습니까?

+0

하나 이상의 번들에서 참조 된 특정 CSS가 있거나 _Layout.cshtml에 직접 포함 시켰을 때 이런 일이 발생했습니다. – da7rutrak

+0

둘 이상의 번들에서 참조되지 않습니다. _layout.cshtml에 넣으십시오. 모든 페이지에서 사용됩니다. 이상하게도 파일 이름을 jqui.css와 같이 다른 이름으로 변경하면 문제가 사라집니다. –

+0

나는 CSS 파일을 _Layout.cshtml에서 직접 참조했다는 것을 의미했지만 파일에 번들이 포함되어있는 것은 아닙니다. – da7rutrak

답변

21

번들링은 CSS 파일을 동일한 순서로 렌더링하지 않아도되며, 다른 로직을 따릅니다. 당신이 정의로 렌더링해야하는 경우에, 당신은 사용자 정의 IBundleOrderer를 작성하고 필요한 발 주로 번들로 설정해야합니다

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

그리고

var bundle = new StyleBundle("~/stylesheet"); 
bundle.Orderer = new AsDefinedBundleOrderer(); 
bundles.Add(bundle); 

다음이 목록에 아무것도하지 않는 것 그래서 Render는 정확히 같은 순서로 렌더링합니다.

번들링 주문 기본에

업데이트는 Bundle 내에서 항목을 정렬 할 IBundleOrderer의 개념을 사용합니다. Bundle 클래스는 다음과 같습니다 Orderer, 호텔이있다 : 당신은 사용자 정의 주문자으로 덮어 때까지 그래서 기본 주문자 실제로 DefaultBundleOrderer입니다

public IBundleOrderer Orderer 
{ 
    get 
    { 
    if (this._orderer == null) 
     return (IBundleOrderer) DefaultBundleOrderer.Instance; 
    else 
     return this._orderer; 
    } 
    set 
    { 
    this._orderer = value; 
    this.InvalidateCacheEntries(); 
    } 
} 

. 여기,

public interface IBundleOrderer 
{ 
    IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files); 
} 

이의 DefaultBundleOrderer 구현이 BundleContext하여 파일을 주문 OrderFiles의 구현에서 미리보기입니다 :

IBundleOrderer는 다음과 같은 서명이 그래서 다른

foreach (BundleFileSetOrdering ordering in (IEnumerable<BundleFileSetOrdering>) context.BundleCollection.FileSetOrderList) 
    DefaultBundleOrderer.AddOrderingFiles(ordering, (IEnumerable<FileInfo>) list, fileMap, foundFiles, result); 

이 때문에 결과가 발생합니다. 당신이 Application_Start에서이 전화 그래서

public static void AddDefaultFileOrderings(IList<BundleFileSetOrdering> list) 
{ 
    if (list == null) 
    throw new ArgumentNullException("list"); 
    BundleFileSetOrdering bundleFileSetOrdering1 = new BundleFileSetOrdering("css"); 
    bundleFileSetOrdering1.Files.Add("reset.css"); 
    bundleFileSetOrdering1.Files.Add("normalize.css"); 
    list.Add(bundleFileSetOrdering1); 
    BundleFileSetOrdering bundleFileSetOrdering2 = new BundleFileSetOrdering("jquery"); 
    bundleFileSetOrdering2.Files.Add("jquery.js"); 
    bundleFileSetOrdering2.Files.Add("jquery-min.js"); 
    bundleFileSetOrdering2.Files.Add("jquery-*"); 
    bundleFileSetOrdering2.Files.Add("jquery-ui*"); 
    bundleFileSetOrdering2.Files.Add("jquery.ui*"); 
    bundleFileSetOrdering2.Files.Add("jquery.unobtrusive*"); 
    bundleFileSetOrdering2.Files.Add("jquery.validate*"); 
    list.Add(bundleFileSetOrdering2); 
    BundleFileSetOrdering bundleFileSetOrdering3 = new BundleFileSetOrdering("modernizr"); 
    bundleFileSetOrdering3.Files.Add("modernizr-*"); 
    list.Add(bundleFileSetOrdering3); 
    BundleFileSetOrdering bundleFileSetOrdering4 = new BundleFileSetOrdering("dojo"); 
    bundleFileSetOrdering4.Files.Add("dojo.*"); 
    list.Add(bundleFileSetOrdering4); 
    BundleFileSetOrdering bundleFileSetOrdering5 = new BundleFileSetOrdering("moo"); 
    bundleFileSetOrdering5.Files.Add("mootools-core*"); 
    bundleFileSetOrdering5.Files.Add("mootools-*"); 
    list.Add(bundleFileSetOrdering5); 
    BundleFileSetOrdering bundleFileSetOrdering6 = new BundleFileSetOrdering("prototype"); 
    bundleFileSetOrdering6.Files.Add("prototype.js"); 
    bundleFileSetOrdering6.Files.Add("prototype-*"); 
    bundleFileSetOrdering6.Files.Add("scriptaculous-*"); 
    list.Add(bundleFileSetOrdering6); 
    BundleFileSetOrdering bundleFileSetOrdering7 = new BundleFileSetOrdering("ext"); 
    bundleFileSetOrdering7.Files.Add("ext.js"); 
    bundleFileSetOrdering7.Files.Add("ext-*"); 
    list.Add(bundleFileSetOrdering7); 
} 

:

BundleConfig.RegisterBundles(BundleTable.Bundles); 

은 실제로 당신이 정의 된 기본 BundleCollection 전달이되지 물론 임의의 정렬 알고리즘 : 규칙은 BUndleCollection 클래스에 정의되어있다 도서관에서.우리는 우리가 라이브러리 파일의 어떤 종류를 선호 말할 수있는 프로세스를 단순화하려면

private static void AddOrderingFiles(BundleFileSetOrdering ordering, IEnumerable<FileInfo> files, Dictionary<string, HashSet<FileInfo>> fileMap, HashSet<FileInfo> foundFiles, List<FileInfo> result) 
{ 
    foreach (string key in (IEnumerable<string>) ordering.Files) 
    { 
    if (key.EndsWith("*", StringComparison.OrdinalIgnoreCase)) 
    { 
     string str = key.Substring(0, key.Length - 1); 
     foreach (FileInfo fileInfo in files) 
     { 
     if (!foundFiles.Contains(fileInfo) && fileInfo.Name.StartsWith(str, StringComparison.OrdinalIgnoreCase)) 
     { 
      result.Add(fileInfo); 
      foundFiles.Add(fileInfo); 
     } 
     } 
    } 
    else if (fileMap.ContainsKey(key)) 
    { 
     List<FileInfo> list = new List<FileInfo>((IEnumerable<FileInfo>) fileMap[key]); 
     list.Sort((IComparer<FileInfo>) FileInfoComparer.Instance); 
     foreach (FileInfo fileInfo in list) 
     { 
     if (!foundFiles.Contains(fileInfo)) 
     { 
      result.Add(fileInfo); 
      foundFiles.Add(fileInfo); 
     } 
     } 
    } 
    } 
} 

결론

:

그래서 우리는 BundleFileSetOrdering 인스턴스에 하나씩 합격 한 여러 가능성이 발견되면 다른 파일을 정렬합니다. 이것은 대부분의 경우 예상되는 동작입니다. 그러나 볼 수 있듯이 AsDefinedBundleOrderer으로 쉽게 대체 할 수 있으므로 주어진 파일 세트에 아무런 영향을 미치지 않으므로 순서가 원래대로 유지됩니다.

+0

완벽, 고마워 :) –

+1

"번들링은 동일한 순서로 CSS 파일을 렌더링하지 않아야합니다". 이 정보를 어디에서 찾았습니까? 나는 [여기] 튜토리얼 (http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification)을 읽고있어 올바른 접근법처럼 들리므로 올바른 것을 얻는다. 순서는 명시 적으로 원하는 순서대로 파일을 추가하는 것입니다. – bbak

+0

그리고 명확히하기 위해, 나는 똑같은 문제를 안고 있었고 당신의 대답이 그것을 해결했습니다. StyleBundles의 순서가 어떻게 작동하는지 그리고 왜 ScriptBundles의 순서와 다르게 작동하는지 이해하고 싶습니다. 내 ScriptBundles은 사용자 지정 IBundleOrderer를 사용하지 않고도 정의한대로 파일을 정렬합니다. – bbak