Bundler không bao gồm các tệp .min


261

Tôi có một vấn đề kỳ lạ với trình đóng gói mvc4 không bao gồm các tệp có phần mở rộng .min.js

Trong lớp BundleConfig của tôi, tôi tuyên bố

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/Scripts/jquery")
        .Include("~/Scripts/jquery-1.8.0.js")
        .Include("~/Scripts/jquery.tmpl.min.js"));            
}

Theo quan điểm của tôi, tôi tuyên bố

<html>
    <head>
    @Scripts.Render("~/Scripts/jquery")
    </head><body>test</body>
</html>

Và khi nó ám, nó chỉ ám

<html>
    <head>
         <script src="/Scripts/jquery-1.8.0.js"></script>
    </head>
    <body>test</body>
</html>

Nếu tôi đổi tên jquery.tmpl.min.js thành jquery.tmpl.js (và cập nhật đường dẫn trong gói tương ứng), cả hai tập lệnh được hiển thị chính xác.

Có một số cài đặt cấu hình khiến nó bỏ qua các tệp '.min.js' không?


Tôi đang sử dụng gói MVC 4 và nó bao gồm các tệp .min.js.
Eric J.

phiên bản RTM hay RC? nó cũng hoạt động tốt trong RC đối với tôi
Fatal

10
Ý tưởng là làm việc ở chế độ gỡ lỗi, phiên bản "dev" không được thu nhỏ sẽ được sử dụng và khi bạn ở chế độ không gỡ lỗi, phiên bản rút gọn sẽ được chọn. Để xem nó hoạt động, thay đổi giá trị gỡ lỗi web.config của bạn từ true thành false.
Pieter Germishuys

28
trong một số trường hợp, bạn không có phiên bản chưa được rút gọn của tập lệnh. Tôi có thể hiểu nó nếu cả hai tập tin tồn tại.
Gây tử vong

1
Đó là một con số thấp mà nó hoạt động như thế này theo mặc định ... chắc chắn, các tập tin có thể đã được minified , nhưng tôi nghĩ rằng Microsoft thất bại trong việc nhận thấy lợi ích của việc thêm các kịch bản trước minified để bó cho mục đích sửa bộ nhớ cache (ít thoải mái vtham số băm được thêm vào url và thay đổi khi nội dung tệp thay đổi)
cần thiết

Câu trả lời:


257

Giải pháp ban đầu tôi đăng là nghi vấn (là một bản hack bẩn). Hành vi được điều chỉnh đã thay đổi trong gói Microsoft.AspNet.Web.Optimization và tinh chỉnh không hoạt động nữa, như được chỉ ra bởi nhiều người bình luận. Ngay bây giờ tôi không thể tái tạo vấn đề với phiên bản 1.1.3 của gói.

Vui lòng xem các nguồn của System.Web.Optimization.BundleCollection (bạn có thể sử dụng dotPeek chẳng hạn) để hiểu rõ hơn về những gì bạn sắp làm. Cũng đọc câu trả lời của Max Shmelev .

Câu trả lời gốc :

Hoặc đổi tên .min.js thành .js hoặc làm một cái gì đó như

    public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
    {
        if (ignoreList == null)
            throw new ArgumentNullException("ignoreList");
        ignoreList.Ignore("*.intellisense.js");
        ignoreList.Ignore("*-vsdoc.js");
        ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
        //ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
        ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
    }

    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.IgnoreList.Clear();
        AddDefaultIgnorePatterns(bundles.IgnoreList);
        //NOTE: it's bundles.DirectoryFilter in Microsoft.AspNet.Web.Optimization.1.1.3 and not bundles.IgnoreList

        //...your code
     }

4
Cũng cảm ơn tôi - vì vậy, thêm nó vào danh sách gotcha MVC4 của tôi :)
Dan B

27
Đây là thời điểm dài, họ có thể đã thêm các tệp tối thiểu được nhận xét với lý do hoặc kết quả nào đó, bây giờ cả giờ lãng phí không biết ai đang ăn cắp các tập tin kịch bản của tôi từ đầu ra.
Giedrius

5
Theo nhận xét của mỗi Fatal trong OP, giải pháp này sẽ kết thúc việc làm lại các tham chiếu trùng lặp cho cả phiên bản rút gọn và phiên bản thông thường nếu cả hai đều tồn tại (ví dụ như jquery).
danmiser

11
M $, khi somefile.min.js được chỉ định rõ ràng hoặc khi chỉ tồn tại tệp .min.js, thì chỉ bao gồm tệp .min.js! Nếu không chỉ cần áp dụng các hành vi hiện tại!
Adaptabi

3
Thật đáng kinh ngạc khi lớp thực tế được gọi là "IgnoreList", nhưng nó xuất phát trực tiếp từ Object. Không LINQ, không lặp lại. - msdn.microsoft.com/en-us/l Library / Google
JP ten Berge

176

Microsoft ngụ ý các hành vi sau (và tôi thích thực hiện theo các dự án của mình):

phiên bản ngắn

  1. Bạn có cả phiên bản gỡ lỗi và rút gọn của tập lệnh trong dự án của mình trong cùng một thư mục:
    • script.js
    • script.min.js
  2. Bạn chỉ thêm script.js vào một gói trong mã của mình.

Kết quả là bạn sẽ tự độngscript.js được bao gồm trong chế độ DEBUGscript.min.js trong chế độ RELEASE .

phiên bản dài

Bạn cũng có thể có phiên bản .debug.js . Trong trường hợp đó, tệp được bao gồm trong mức ưu tiên sau trong DEBUG:

  1. script.debug.js
  2. script.js

trong THÔNG BÁO:

  1. script.min.js
  2. script.js

Ghi chú

Và bằng cách này, lý do duy nhất để có một .min phiên bản của kịch bản của bạn trong MVC4 là trường hợp khi phiên bản minified không thể được xử lý tự động. Ví dụ, đoạn mã sau không thể bị xáo trộn tự động:

if (DEBUG) console.log("Debug message");

Trong tất cả các trường hợp khác, bạn có thể đi chỉ với một phiên bản gỡ lỗi của tập lệnh của mình.


6
Tuy nhiên, lời giải thích hay của OP là một số tập lệnh ( jquery.tmpl) không có, không đi kèm, không được tải xuống phiên bản không phải của tập tin. Trình đóng gói bỏ qua các tệp script hoàn toàn nếu nó không có phiên bản không phải là phút ở chế độ gỡ lỗi
Eonasdan

Đồng ý, giải thích hay nhưng nó không trả lời câu hỏi của OP.
Diego

2
Phiên bản ngắn đã không làm việc cho tôi. "script.js" sẽ được bao gồm trong cả hai loại phát hành này. Tôi đã bật DEBUG / ĐÁNG TIN CẬY và (khi tôi nhìn vào nguồn) 'script.js' là cái được chọn / kết xuất.
dùng981375

4
user981375, bạn cũng cần đặt <compilation debug = "false" /> trong tệp web.config
Max Shmelev

5
Tôi thích câu trả lời này vì đây là cách tiếp cận "thực tiễn tốt nhất" và giải thích cách tuân thủ các quy tắc mặc định của gói để đạt được cùng một mục tiêu.
James Reategui

5

Nếu tất cả những gì bạn có là một phiên bản rút gọn của một tệp, giải pháp đơn giản nhất tôi tìm thấy là sao chép tệp đã rút gọn, xóa .min khỏi tên tệp đã sao chép, sau đó tham chiếu tên tệp không được rút gọn trong gói của bạn.

Ví dụ: giả sử bạn đã mua một thành phần js và họ đã cung cấp cho bạn một tệp có tên some-lib-3.2.1.min.js. Để sử dụng tệp này trong một gói, hãy làm như sau:

  1. Sao chép một số lib-3.2.1.min.js và đổi tên tệp đã sao chép thành some-lib-3.2.1.js. Bao gồm cả hai tập tin trong dự án của bạn.

  2. Tham chiếu tệp không được rút gọn trong gói của bạn, như thế này:

    bundles.Add(new ScriptBundle("~/bundles/libraries").Include(
        "~/Scripts/some-lib-{version}.js"
    ));

Chỉ vì tệp không có 'min' trong tên thực sự bị thu nhỏ nên không gây ra bất kỳ vấn đề nào (ngoài thực tế là nó không thể đọc được). Nó chỉ được sử dụng trong chế độ gỡ lỗi và được viết thành một tập lệnh riêng biệt. Khi không ở chế độ gỡ lỗi, tệp min được biên dịch trước sẽ được bao gồm trong gói của bạn.


4

Tôi đã tìm thấy một giải pháp tốt hoạt động ít nhất trong MVC5, bạn chỉ có thể sử dụng Bundlethay vì ScriptBundle. Nó không có hành vi thông minh ScriptBundlemà chúng ta không thích (bỏ qua .min, v.v.) trong trường hợp này. Trong giải pháp của tôi, tôi sử dụng Bundlecho các tập lệnh bên 3d với các tệp .min và .map và tôi sử dụng ScriptBundlecho mã của chúng tôi. Tôi đã không nhận thấy bất kỳ nhược điểm của việc làm nó. Để làm cho nó hoạt động theo cách này, bạn sẽ cần thêm tệp gốc, ví dụ như angular.js và nó sẽ tải angular.js trong gỡ lỗi và nó sẽ bó angular.min.js trong chế độ phát hành.


Nó dường như không hoạt động khi tối ưu hóa bị vô hiệu hóa ( ScriptTable.EnableOptimizations = false). Đường dẫn tập lệnh chứa mẫu không được hiển thị (ví dụ ~/Scripts/thirdpartylib/*.js). Nó làm việc khi EnableOptimizations = true, nhưng cũng vậy ScriptBundle.
Steven Liekens

Tôi cũng sử dụng nó với false (trong quá trình phát triển) và tôi không gặp vấn đề gì mà bạn mô tả, vì vậy nó có thể là một thứ khác ảnh hưởng đến nó. Bạn cũng cần phải thực hiện Bao gồm thay vì để mô hình hoạt động.
Ilya Chernomordik

Bạn có chắc chắn nó đang hiển thị phiên bản ".min.js" của tệp của bạn không? Bạn đang sử dụng các gói từ không gian tên System.Web.Optimizationshoặc từ gói nuget Microsoft.Web.Optimizations?
Steven Liekens

Tôi sử dụng System.Web.Optimization và tôi đã kiểm tra xem nó có phiên bản tối thiểu không, nhưng thực tế tôi đã nhận ra rằng tôi không sử dụng Bao gồm cả trên thực tế, nhưng sẽ thật lạ nếu điều đó không hoạt động với phiên bản tối thiểu mặc dù ... Vì Bao gồm cả đủ cho tôi Tôi thực hiện quét tùy chỉnh và thêm tất cả bộ lọc bằng Bao gồm, do đó, có thể mẫu và Bao gồm thư mục không hoạt động chính xác ở đó, mặc dù điều đó hơi lạ.
Ilya Chernomordik

1
Không, vấn đề là hai lần: chỉ .min.jstồn tại một tệp và *.jsmẫu không khớp với các tệp kết thúc bằng .min.js.
Steven Liekens

3

Để kết xuất *.min.jstệp, bạn phải tắt BundleTable.EnableOptimizations, đây là cài đặt chung áp dụng cho tất cả các gói.

Nếu bạn chỉ muốn bật tối ưu hóa cho các gói cụ thể, bạn có thể tạo ScriptBundleloại riêng của mình tạm thời cho phép tối ưu hóa khi liệt kê các tệp trong gói.

public class OptimizedScriptBundle : ScriptBundle
{
    public OptimizedScriptBundle(string virtualPath)
        : base(virtualPath)
    {
    }

    public OptimizedScriptBundle(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath)
    {
    }

    public override IEnumerable<BundleFile> EnumerateFiles(BundleContext context)
    {
        if (context.EnableOptimizations)
            return base.EnumerateFiles(context);
        try
        {
            context.EnableOptimizations = true;
            return base.EnumerateFiles(context);
        }
        finally
        {
            context.EnableOptimizations = false;
        }
    }
}

Sử dụng OptimizedScriptBundlethay vì ScriptBundlecho các gói có tệp rút gọn phải luôn được sử dụng, bất kể có tồn tại tệp không rút gọn hay không.

Ví dụ về giao diện người dùng Kendo cho ASP.NET MVC, được phân phối dưới dạng tập hợp các tệp được thu nhỏ.

bundles.Add(new OptimizedScriptBundle("~/bundles/kendo")
        .Include(
            "~/Scripts/kendo/kendo.all.*",
            "~/Scripts/kendo/kendo.aspnetmvc.*",
            "~/Scripts/kendo/cultures/kendo.*",
            "~/Scripts/kendo/messages/kendo.*"));

Tôi đã bắt gặp một số tập lệnh bị thiếu trong một hành động xuất bản sản xuất và nghĩ rằng đó là một vấn đề MVC, tôi đã tìm thấy câu trả lời này .. lo và kìa, kendo có liên quan. Làm việc với nó quá lâu, tôi làm bất cứ điều gì để thoát khỏi kendo
Felipe

@Felipe Tôi đã ở trong tình huống tương tự đó là lý do tại sao tôi viết câu trả lời này. Kendo thật kinh khủng. Tôi hy vọng ví dụ của tôi là hữu ích.
Steven Liekens

2

Trong trường hợp của tôi, tôi đã sử dụng thư viện Knockout.js (tuyệt vời!), Phiên bản Debug / Non:

"~/Scripts/knockout-{Version}.js"
"~/Scripts/knockout-{Version}.Debug.js"

Để thực hiện công việc này, tôi đã bao gồm "Knockout- {Phiên bản} .js" (không gỡ lỗi) trong Gói của tôi và có .debug. tập tin js trong chế độ Gỡ lỗi.


1

Một cách dễ dàng chỉ là Đổi tên tệp .min, ví dụ bạn có abc.min.css thay vì chỉ đổi tên tệp này thành abc_min.css và thêm tệp này vào gói của bạn. Tôi biết nó không phải là cách đúng đắn để làm điều đó, nhưng chỉ là một giải pháp tạm thời. cảm ơn và mã hóa hạnh phúc.


1
Mỗi khi nuget tải tập tin, bạn cần đổi tên sau đó.
Anirudha Gupta

Tôi biết đó không phải là cách đúng đắn để làm điều đó, nhưng chỉ là một giải pháp tạm thời
RK Sharma

1
đặt dòng này đang làm việc cho tôi // BundleTable.EnableOptimizes = true;
Anirudha Gupta

0

Bundler có rất nhiều lợi ích kiểm tra trang này NHƯNG :

Microsoft MVC4 Platform Considers mà bạn có ít nhất cả phiên bản rút gọn & phiên bản chưa hoàn thành cho mỗi Script hoặc Gói kiểu (cũng có sẵn các tệp khác như Debug và vsdoc). Vì vậy, chúng tôi gặp rắc rối trong các tình huống chỉ có một trong những tệp này.

Bạn có thể thay đổi trạng thái gỡ lỗi trong tệp web.config vĩnh viễn để xử lý đầu ra:

<compilation debug="false" targetFramework="4.0" />

Xem các thay đổi đầu ra! Lọc tập tin đã thay đổi. Để đáp ứng mục đích, chúng ta phải thay đổi bỏ qua lọc trường hợp sẽ thay đổi logic ứng dụng!


1
Thêm debug = "false" vẫn không hiệu quả với tôi. Các tệp min.js vẫn không được bao gồm ngay cả khi tôi cũng xóa IgnoreList ...
MoSs

-21

Mọi người tôi sẽ giữ nó đơn giản cho đến khi Microsoft làm cho nó hoạt động cùng nhau

Thử cái này

Trong RegisterBundles tạo gói này cho Kendo

bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
                    "~/Content/kendo/2012.3.1121/kendo.common.min.css",
                     "~/Content/kendo/2012.3.1121/kendo.dataviz.min.css",
                      "~/Content/kendo/2012.3.1121/kendo.blueopal.min.css"
 ));

Trong _Layout.cshtml đặt cái này:

@if (HttpContext.Current.IsDebuggingEnabled)
 { 
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.common.min.css")"      
rel="stylesheet"  type="text/css" />
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.dataviz.min.css")" 
rel="stylesheet" type="text/css" />   
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.blueopal.min.css")"    
rel="stylesheet" type="text/css" />
 }
 else
 {
     @Styles.Render("~/Content/kendo/css")   
 }

Bằng cách này, chúng tôi có được các gói tốt nhất trong Sản xuất và tham chiếu trong Gỡ lỗi

Khắc phục sự cố khi Microsoft sửa mã MVC 4 của họ


3
Tôi không phải là một fan hâm mộ của giải pháp đề xuất này cả. Bây giờ bạn phải duy trì tập hợp các tập lệnh ở (ít nhất) hai vị trí
Fatal

Điều này khá nhiều đánh bại mục đích của gói, bạn không nghĩ sao?
Oliver

4
Gói đã hoạt động theo cách này. Nếu bạn chạy dự án ở chế độ gỡ lỗi, mỗi tệp CSS được tải riêng lẻ, tuy nhiên khi bạn chạy trong bản phát hành, chúng sẽ được kết hợp và rút gọn thành một. Mã trong khối if giống hệt với những gì được hiển thị trên trang trong chế độ gỡ lỗi.
Chad Levy
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.