ASP.NET MVC - Thứ tự cấu hình gói


84

Tôi đang cố gắng sử dụng một ngôn ngữ cụ thể (es-CL) trong ứng dụng ASP.NET MVC 5 của mình. Tôi như sau:

  1. Đã thay đổi văn hóa và văn hóa web.config thành "es-CL"
  2. Đã cài đặt gói GlobalizejQuery.Validation.Globalize
  3. Đã thay đổi ngôn ngữ mặc định trong chế độ xem của tôi: <html lang="es-cl">
  4. Đã tạo một Gói mới và đưa vào các chế độ xem thích hợp.

Trong BundleConfig.cs :

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
    .Include("~/Scripts/jquery.validate.js")
    .Include("~/Scripts/jquery.validate.unobtrusive.js"));

bundles.Add(new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js"));

Theo quan điểm thích hợp:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/globalization")
}

Tuy nhiên, mã nguồn được tạo như sau:

<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

<script src="/Scripts/jquery.validate.globalize.js"></script>
<script src="/Scripts/globalize/globalize.js"></script>
<script src="/Scripts/globalize/cultures/globalize.culture.es-CL.js"></script>

Xin lưu ý rằng tập lệnh jquery.validate.globalize.js đang được tải trước globalize.js , đây không phải là điều tôi muốn.

Tại sao chuyện này đang xảy ra? Có thể dựa vào thứ tự bao gồm trong một gói duy nhất hay tôi buộc phải đặt tập lệnh đơn này vào một gói khác và chỉ định nó trong chế độ xem của tôi?



@PaulMcCowat vâng, nhưng tôi chưa sử dụng các phiên bản thu nhỏ. Tôi đang sử dụng Microsoft.AspNet.Web.Optimizations 1.1.0.
Leonardo Herrera

@LeonardoHerrera Tôi sẽ nghĩ rằng nó giống như Chris đã đề cập trong nhận xét của anh ấy, rằng các tệp đã biết được chuyển xung quanh theo thứ tự được chỉ định bởi gói ... nhưng tôi không thể chắc chắn vì tôi không biết những tệp đó là gì, dẫn đến tôi hỏi . Tôi sẽ muốn biết liệu việc sử dụng IBundleOrderer có phù hợp với bạn hay không vì việc chỉ định đơn hàng không phù hợp.
MikeSmithDev

xem câu trả lời của @Softlion trong [liên kết này] [1] [1]: stackoverflow.com/questions/11979718/…
Omid-RH

@section Scripts { @Scripts.Render("~/bundles/jqueryval") }dường như đã giải quyết được vấn đề tập lệnh của tôi tải không theo thứ tự ....
petrosmm.

Câu trả lời:


103

Theo mặc định, thứ tự nhóm là thứ tự bảng chữ cái cho các tên có ký tự đại diện (như được chỉ ra trong các nhận xét). Tuy nhiên, nó cũng sắp xếp thứ tự dựa trên những gì nó cho rằng cây phụ thuộc của bạn là gì và jQuerycác tập lệnh dường như được đưa lên đầu. Bạn cần tạo một đối tượng triển khai IBundleOrder:

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

Điều này ngăn chặn thứ tự mặc định. Bây giờ để sử dụng nó:

var bundle = new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new NonOrderingBundleOrderer();

bundles.Add(bundle);

tham khảo: http://stevescodingblog.co.uk/changed-the-ordering-for-single-bundles-in-asp-net-4/

Để đọc thêm, câu trả lời cho câu hỏi của MikeSmithDev cung cấp thêm thông tin chi tiết về thứ tự mặc định cho các thư viện tập lệnh phổ biến:

Thứ tự các tệp trong một gói - Các thư viện đã biết là gì?


Không phải để nitpick, nhưng "theo mặc định, thứ tự gói là theo thứ tự bảng chữ cái" là đúng khi bạn sử dụng những thứ như thẻ đại diện ... khi bạn chỉ định thứ tự, như anh ta có, nó sẽ sử dụng thứ tự của anh ta. Tôi chỉ có thể giả định rằng trình xử lý gói đang di chuyển xung quanh các loại tệp đã biết và đang bỏ qua thứ tự của mình.
MikeSmithDev

Có vẻ như trình gói cũng ra lệnh bằng cách sử dụng một số logic về các phụ thuộc. Nó nghĩ rằng điều đó jquery.validate.globalize.jslà cần thiết cho hai cái kia. Từ ref: "[The Bundler] thậm chí sẽ tự động đặt các tệp javascript khung đã biết trước vào gói, chẳng hạn như các đoạn mã jQuery hoặc Prototype, để đảm bảo chúng chạy trước khi mã của riêng bạn sử dụng các loại của chúng được thực thi"
Mister Epic

3
Thứ tự cụ thể là: jquery.js jquery-min.js jquery- * jquery-ui * jquery.ui * jquery.unobtrntic * jquery.validate * modernizr- * dojo. * Mootools-core * mootools- * nguyên mẫu.js nguyên mẫu- * scriptaculous- * ext.js ext- *
ravndal

6
đây là nơi mà lập trình không phải là thú vị. tại sao VS làm cho điều này phức tạp?
Jaider

5
Thực tế là điều này tồn tại khiến tâm trí tôi thấy nó thật ngu ngốc. Thực sự .. người gói biết cách sắp xếp các phần phụ thuộc của tôi tốt hơn tôi đã gõ chúng? Gulp.js (hoặc thậm chí là Grunt) FTW!
John Culviner

30

Trong phiên bản cuối cùng của MVC 5 (vào ngày 27 tháng 10 năm 2014), bạn nên sử dụng lớp này thay thế:

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

Và tạo gói giống như phản hồi khác:

var bundle = new ScriptBundle("~/bundles/globalization")
.Include("~/Scripts/globalize/globalize.js")
.Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
.Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new AsIsBundleOrderer();

bundles.Add(bundle);

Tôi có thể tìm thông tin này ở đâu? Bạn có thể cung cấp một liên kết xin vui lòng?
PussInBoots

Tôi chỉ cố gắng sử dụng phương pháp của câu trả lời hiện tại cho câu hỏi này nhưng tôi thấy ảnh selkf của mình có lỗi trong ASP.NET MVC 5, vì vậy tôi kiểm tra giao diện IBundleOrderer và thực hiện các thay đổi
Sebastián Rojas

Không có Tài sản của Người đặt hàng. Tôi đang sử dụng MVC 5.2.x
Legends

1
Tôi chỉ kiểm tra nó với MVC 5.2.3 và tehres là Thuộc tính của Người đặt hàng.
Sebastián Rojas

28

Để giảm mã trong quá trình tạo nhóm, tôi khuyên bạn nên tạo một phương pháp mở rộng.

Yêu cầu các lớp cơ sở hạ tầng:

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


static class BundleExtentions
{
    public static Bundle NonOrdering(this Bundle bundle)
    {
        bundle.Orderer=new NonOrderingBundleOrderer();
        return bundle;
    }
}

Bây giờ chỉ cần sử dụng nó như thế này:

Tất cả trong một lệnh 😎

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
               .NonOrdering()
               .Include(
                    "~/Scripts/globalize/globalize.js",
                    "~/Scripts/globalize/cultures/globalize.culture.es-CL.js",
                    //...
                );

1
Cách suy nghĩ tốt đẹp!
Aruna
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.