Bundler ไม่รวมไฟล์. min


261

ฉันมีปัญหาแปลก ๆ กับตัวรวม mvc4 ไม่รวมไฟล์ที่มีนามสกุล. min.js

ในคลาส BundleConfig ของฉันฉันประกาศ

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

ในมุมมองของฉันฉันประกาศ

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

และเมื่อมันแสดงผลก็เพียงแสดงผล

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

หากฉันเปลี่ยนชื่อ jquery.tmpl.min.js เป็น jquery.tmpl.js (และอัพเดตพา ธ ในบันเดิลตามลำดับ) สคริปต์ทั้งคู่จะแสดงผลอย่างถูกต้อง

มีการตั้งค่าการกำหนดค่าบางอย่างที่ทำให้ละเว้นไฟล์ '.min.js' หรือไม่


ฉันกำลังใช้ตัวรวม MVC 4 และมันรวมไฟล์. min.js ด้วย
Eric J.

รุ่น RTM หรือ RC? มันทำงานได้ดีใน RC สำหรับฉันด้วย
Fatal

10
แนวคิดคือการทำงานในโหมดดีบักซึ่งจะใช้รุ่น "dev" โดยไม่มีการลดขนาดและเมื่อคุณอยู่ในโหมดที่ไม่ใช่การดีบัก หากต้องการดูการทำงานให้เปลี่ยนค่าการดีบัก web.config จาก true เป็น false
Pieter Germishuys

28
ในบางกรณีคุณไม่มีสคริปต์เวอร์ชันที่ไม่ย่อเล็กสุด ฉันอาจจะเข้าใจถ้ามีไฟล์ทั้งสองอยู่
ร้ายแรง

1
เป็นคนเกียจคร้านที่ทำงานเช่นนี้โดยค่าเริ่มต้น ... แน่นอนว่าไฟล์อาจถูกลดขนาดลง แต่ฉันคิดว่า Microsoft ไม่เห็นประโยชน์ของการเพิ่มสคริปต์ที่ลดขนาดล่วงหน้าลงในชุดรวมเพื่อวัตถุประสงค์ในการป้องกันแคช ( vแฮชพารามิเตอร์เล็กน้อยที่ได้รับเพิ่มไปยัง URL และเมื่อมีการเปลี่ยนแปลงเนื้อหาของแฟ้มการเปลี่ยนแปลง)
nothingisnecessary

คำตอบ:


257

โซลูชันที่ฉันโพสต์ในตอนแรกนั้นน่าสงสัย (เป็นแฮ็คที่สกปรก) พฤติกรรม tweaked มีการเปลี่ยนแปลงในแพคเกจ Microsoft.AspNet.Web.Optimization และ tweak ไม่ทำงานอีกต่อไปตามที่ชี้ให้เห็นโดยผู้แสดงความคิดเห็นจำนวนมาก ตอนนี้ฉันไม่สามารถทำซ้ำปัญหาได้เลยด้วยแพ็คเกจรุ่น 1.1.3

โปรดดูที่มาของ System.Web.Optimization.BundleCollection (คุณสามารถใช้dotPeekเป็นต้น) เพื่อความเข้าใจที่ดีขึ้นเกี่ยวกับสิ่งที่คุณกำลังจะทำ อ่านคำตอบของ Max Shmelevด้วย

คำตอบเดิม :

เปลี่ยนชื่อ. min.js เป็น. js หรือทำสิ่งที่ต้องการ

    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
ขอบคุณข้อมูลจากฉันเกินไป - เพื่อเพิ่มนี้รายการ gotcha MVC4 ของฉัน :)
แดน B

27
นี่เป็นช่วงเวลาที่ยาวนานพวกเขาอาจเพิ่มไฟล์ min ที่แสดงความคิดเห็นด้วยเหตุผลหรือบางสิ่งบางอย่างที่จะเกิดขึ้นตอนนี้ทั้งชั่วโมงก็สงสัยว่าใครขโมยไฟล์สคริปต์ของฉันจากเอาท์พุท
Giedrius

5
ตามความคิดเห็นของ Fatal ใน OP วิธีนี้จะสิ้นสุดการอ้างอิงที่ซ้ำกันซ้ำสำหรับทั้งรุ่นย่อและรุ่นธรรมดาหากมีอยู่ทั้งคู่ (เช่น jquery)
danmiser

11
M $, เมื่อ somefile.min.js มีการระบุอย่างชัดเจนหรือเมื่อมีเพียงไฟล์. min.js อยู่แล้วจะรวมเฉพาะไฟล์. min.js เท่านั้น! มิฉะนั้นเพียงแค่ใช้พฤติกรรมปัจจุบัน!
Adaptabi

3
เหลือเชื่อว่าคลาสจริงเรียกว่า "IgnoreList" แต่มันมาจาก Object โดยตรง ไม่มี LINQ ไม่มีการวนซ้ำ - msdn.microsoft.com/en-us/library/ ......
JP ten Berge

176

Microsoft แสดงถึงพฤติกรรมดังต่อไปนี้ (และฉันชอบที่จะติดตามมันในโครงการของฉัน):

เวอร์ชั่นสั้น

  1. คุณมีสคริปต์เวอร์ชัน debug และ minified ในโครงการของคุณภายใต้โฟลเดอร์เดียวกัน:
    • script.js
    • script.min.js
  2. คุณเพิ่มscript.jsเท่านั้นลงในชุดข้อมูลในรหัสของคุณ

เป็นผลให้คุณจะโดยอัตโนมัติมีดังscript.jsรวมอยู่ในการดีบักโหมดและscript.min.jsในการปล่อยโหมด

รุ่นยาว

คุณสามารถมีรุ่น. debug.jsได้เช่นกัน ในกรณีนั้นไฟล์จะรวมอยู่ในลำดับความสำคัญต่อไปนี้ใน DEBUG:

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

ในการเปิดตัว:

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

บันทึก

และด้วยเหตุผลเพียงเหตุผลเดียวที่มีสคริปต์รุ่น. min ใน MVC4 เป็นกรณีเมื่อรุ่นย่อไม่สามารถประมวลผลได้โดยอัตโนมัติ ตัวอย่างเช่นรหัสต่อไปนี้ไม่สามารถทำให้งงงันโดยอัตโนมัติ:

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

ในกรณีอื่น ๆ ทั้งหมดคุณสามารถไปกับสคริปต์รุ่นของการดีบัก


6
คำอธิบายที่ดีอย่างไรก็ตามปัญหาของ OP คือสคริปต์บางตัว ( jquery.tmpl) ไม่มี, ไม่ได้มาพร้อม, ไม่ได้ดาวน์โหลดไฟล์เวอร์ชันที่ไม่ใช่นาที ตัวรวมจะละเว้นไฟล์สคริปต์ทั้งหมดหากไม่มีเวอร์ชันที่ไม่ใช่นาทีในโหมดดีบัก
Eonasdan

เห็นด้วยคำอธิบายที่ดี แต่ไม่ตอบคำถามของ OP ทั้งหมด
Diego

2
เวอร์ชั่นสั้นไม่ทำงานสำหรับฉัน "script.js" จะรวมอยู่ในทั้งสองประเภทการเปิดตัวเหล่านี้ ฉันสลับ DEBUG / RELEASE และ (เมื่อฉันดูแหล่งที่มา) 'script.js' เป็นสิ่งที่ถูกเลือก / แสดงผล
user981375

4
user981375 คุณต้องตั้ง <compilation debug = "false" /> ในไฟล์ web.config
Max Shmelev

5
ฉันชอบคำตอบนี้เพราะเป็น "แนวทางปฏิบัติที่ดีที่สุด" และอธิบายว่ากฎเริ่มต้นของ Bundler สามารถปฏิบัติตามเพื่อให้บรรลุเป้าหมายเดียวกันได้อย่างไร
James Reategui

5

หากสิ่งที่คุณมีเป็นไฟล์ย่อเล็กสุดวิธีแก้ปัญหาที่ง่ายที่สุดที่ฉันพบคือคัดลอกไฟล์ย่อส่วนลบ. min จากชื่อไฟล์ที่คัดลอกแล้วอ้างอิงชื่อไฟล์ที่ไม่ย่อเล็กสุดในบันเดิลของคุณ

ตัวอย่างเช่นสมมติว่าคุณซื้อส่วนประกอบ js และพวกเขาให้ไฟล์ชื่อ some-lib-3.2.1.min.js ในการใช้ไฟล์นี้ในบันเดิลให้ทำดังต่อไปนี้:

  1. คัดลอก some-lib-3.2.1.min.js และเปลี่ยนชื่อไฟล์ที่คัดลอกเป็น some-lib-3.2.1.js รวมทั้งไฟล์ในโครงการของคุณ

  2. อ้างอิงไฟล์ที่ไม่ย่อเล็กสุดในบันเดิลของคุณเช่นนี้:

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

เพียงเพราะไฟล์ที่ไม่มี 'min' ในชื่อจริง ๆ แล้ว minified ไม่ควรทำให้เกิดปัญหาใด ๆ (นอกเหนือจากความจริงแล้วไฟล์นั้นไม่สามารถอ่านได้) มันใช้เฉพาะในโหมดแก้ไขข้อบกพร่องและเขียนออกมาเป็นสคริปต์แยกต่างหาก เมื่อไม่อยู่ในโหมดดีบักไฟล์ min ที่รวบรวมไว้ล่วงหน้าควรรวมอยู่ในชุดข้อมูลของคุณ


4

ฉันได้พบวิธีแก้ปัญหาที่ดีที่ทำงานได้อย่างน้อยใน MVC5 คุณสามารถใช้BundleแทนScriptBundleได้ มันไม่มีพฤติกรรมที่ชาญฉลาดScriptBundleซึ่งเราไม่ชอบ (ไม่สนใจ. min เป็นต้น) ในกรณีนี้ ในโซลูชันของฉันฉันใช้Bundleสำหรับสคริปต์ปาร์ตี้สามมิติที่มีไฟล์. min และ. map และฉันใช้ScriptBundleรหัสของเรา ฉันไม่ได้สังเกตเห็นข้อเสียของการทำมัน เพื่อให้มันทำงานในลักษณะนี้คุณจะต้องเพิ่มไฟล์ต้นฉบับเช่น angular.js และมันจะโหลด angular.js ในการดีบักและมันจะรวม angular.min.js ในโหมดการเปิดตัว


ดูเหมือนจะไม่ทำงานเมื่อปิดการใช้งานการปรับให้เหมาะสม ( ScriptTable.EnableOptimizations = false) เส้นทางสคริปต์ที่มีรูปแบบจะไม่ถูกแสดงผล (เช่น~/Scripts/thirdpartylib/*.js) มันไม่ทำงานเมื่อแต่เพื่อไม่EnableOptimizations = true ScriptBundle
Steven Liekens

ฉันใช้มันด้วย false เช่นกัน (ในระหว่างการพัฒนา) และฉันไม่มีปัญหาที่คุณอธิบายดังนั้นอาจเป็นอย่างอื่นที่มีผลกับคุณคุณต้องทำ IncludeDirectory แทนที่จะรวมไว้เพื่อให้รูปแบบทำงานได้
Ilya Chernomordik

คุณแน่ใจหรือไม่ว่ากำลังแสดงผลรุ่น ".min.js" ของไฟล์ของคุณ? คุณใช้บันเดิลจากเนมสเปซSystem.Web.Optimizationsหรือจากแพ็คเกจ nuget Microsoft.Web.Optimizationsหรือไม่?
Steven Liekens

ฉันใช้ System.Web.Optimization และฉันตรวจสอบว่ามันแสดงผลรุ่น min แต่ฉันคิดว่าฉันไม่ได้ใช้ IncludeDirectory จริง ๆ แต่มันจะแปลกถ้ามันไม่ทำงานกับรุ่น min แม้ว่า ... เนื่องจาก IncludeDirectory ไม่ใช่ เพียงพอสำหรับฉันฉันทำการสแกนแบบกำหนดเองและเพิ่มตัวกรองทั้งหมดโดยใช้รวมดังนั้นอาจเป็นไปได้ว่ารูปแบบและ IncludeDirectory ทำงานไม่ถูกต้องที่นั่นถึงแม้ว่ามันจะค่อนข้างแปลก
Ilya Chernomordik

1
ไม่ปัญหาคือสองเท่า: มีเพียง.min.jsไฟล์เดียวและ*.jsรูปแบบไม่ตรงกับไฟล์ที่ลงท้าย.min.jsด้วย
Steven Liekens

3

ในการแสดง*.min.jsไฟล์คุณต้องปิดใช้งานBundleTable.EnableOptimizationsซึ่งเป็นการตั้งค่าร่วมที่ใช้กับบันเดิลทั้งหมด

หากคุณต้องการเปิดใช้งานการปรับให้เหมาะสมสำหรับบันเดิลที่ระบุเท่านั้นคุณสามารถสร้างScriptBundleประเภทของคุณเองที่เปิดใช้งานการปรับให้เหมาะสมชั่วคราวเมื่อระบุไฟล์ในบันเดิล

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

ใช้OptimizedScriptBundleแทนScriptBundleชุดข้อมูลที่ควรใช้ไฟล์แบบย่อโดยไม่คำนึงว่ามีไฟล์แบบไม่ย่อขนาดอยู่หรือไม่

ตัวอย่างสำหรับ Kendo UI สำหรับ ASP.NET MVC ซึ่งกระจายเป็นชุดของไฟล์ที่ย่อเล็กสุดเท่านั้น

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

ฉันเจอสคริปท์ที่หายไปในการผลิตงานพิมพ์และคิดว่ามันเป็นปัญหา MVC ฉันพบคำตอบนี้ .. แท้จริงแล้ว, เคนโด้มีส่วนเกี่ยวข้อง เมื่อทำงานกับมันนานเกินไปฉันจะทำทุกอย่างเพื่อหนีจากเคนโด้
เฟลิเป้

@ เฟลีเปฉันอยู่ในสถานการณ์เดียวกันซึ่งเป็นสาเหตุที่ฉันเขียนคำตอบนี้ เคนโด้เป็นคนน่ากลัว ฉันหวังว่าตัวอย่างของฉันจะเป็นประโยชน์
Steven Liekens

2

สำหรับกรณีของฉันฉันใช้ไลบรารี่ Knockout.js (ที่ยอดเยี่ยม!) ซึ่งมาในรูปแบบ Debug / Non:

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

เพื่อให้การทำงานนี้ฉันรวม "Knockout- {Version} .js" (ไม่ใช่การดีบัก) ใน Bundle ของฉันและได้รับ. debug ไฟล์ js ในโหมดดีบั๊ก


1

วิธีที่ง่ายเพียงแค่เปลี่ยนชื่อไฟล์. min ตัวอย่างเช่นคุณมี abc.min.css มากกว่าแค่เปลี่ยนชื่อไฟล์นี้เป็น abc_min.css และเพิ่มลงในบันเดิลของคุณ ฉันรู้ว่ามันไม่ใช่วิธีที่ถูกต้องที่จะทำ แต่เป็นวิธีแก้ปัญหาชั่วคราว ขอขอบคุณและขอให้เขียนโค้ดที่มีความสุข


1
ทุกครั้งที่ nuget ดาวน์โหลดไฟล์คุณจะต้องเปลี่ยนชื่อใหม่
Anirudha Gupta

ฉันรู้ว่ามันไม่ใช่วิธีที่ถูกต้องที่จะทำ แต่เป็นวิธีแก้ปัญหาชั่วคราว
RK Sharma

1
ทำให้บรรทัดนี้ใช้งานได้สำหรับฉัน // BundleTable.EnableOptimizations = true
Anirudha Gupta

0

Bundler มีประโยชน์มากมายตรวจสอบหน้านี้ แต่ :

แพลตฟอร์ม Microsoft MVC4 พิจารณาว่าคุณมีรุ่นอย่างน้อยทั้งรุ่นย่อและรุ่นไม่ระบุสำหรับแต่ละชุดสคริปต์หรือสไตล์ (ไฟล์อื่นเช่น Debug และ vsdoc ก็มีให้เช่นกัน) ดังนั้นเราจึงมีปัญหาในสถานการณ์ที่มีไฟล์เหล่านี้เพียงไฟล์เดียวเท่านั้น

คุณสามารถเปลี่ยนสถานะการแก้ปัญหาในไฟล์ web.config อย่างถาวรเพื่อจัดการเอาต์พุต:

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

ดูผลลัพธ์ที่เปลี่ยนแปลง! เปลี่ยนการกรองไฟล์แล้ว เพื่อให้เป็นไปตามวัตถุประสงค์เราจะต้องเปลี่ยนการเพิกเฉยต่อการกรองเคสที่จะเปลี่ยนตรรกะแอปพลิเคชัน!


1
การเพิ่ม debug = "false" ยังไม่สามารถใช้งานได้สำหรับฉัน min.js ไฟล์ที่ยังไม่รวมถึงแม้ว่าฉันล้าง IgnoreList ได้เป็นอย่างดี ...
มอส

-21

คนที่ฉันจะเก็บไว้จนกว่า Microsoft จะได้ทำหน้าที่ร่วมกัน

ลองสิ่งนี้

ใน RegisterBundles สร้างชุดนี้สำหรับ 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"
 ));

ใน _Layout.cshtml ให้ใส่สิ่งนี้:

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

วิธีนี้ทำให้เราได้รับชุดผลิตภัณฑ์ที่ดีที่สุดและมีการอ้างอิงใน Debug

แก้ไขเมื่อ Microsoft แก้ไขรหัส MVC 4


3
ฉันไม่ใช่แฟนของโซลูชันที่เสนอนี้เลย ตอนนี้คุณต้องรักษาชุดของสคริปต์ใน (อย่างน้อย) สองที่
Fatal

นี่เป็นจุดประสงค์ของการรวมกลุ่มคุณไม่คิดอย่างนั้นเหรอ?
Oliver

4
การรวมกลุ่มทำงานด้วยวิธีนี้แล้ว หากคุณรันโปรเจ็กต์ในโหมดดีบักแต่ละไฟล์ CSS จะถูกโหลดแยกกันอย่างไรก็ตามเมื่อคุณรันในรีลีสพวกเขาจะรวมกันและย่อให้เป็นหนึ่งเดียว โค้ดภายในบล็อก if นั้นเหมือนกับสิ่งที่แสดงในหน้าโดยอัตโนมัติในโหมดแก้ไขข้อบกพร่อง
Chad Levy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.