Bundler tidak termasuk file .min


261

Saya memiliki masalah aneh dengan bundel mvc4 tidak termasuk file dengan ekstensi .min.js

Di kelas BundleConfig saya, saya menyatakan

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

Dalam pandangan saya, saya menyatakan

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

Dan ketika itu membuat, itu hanya membuat

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

Jika saya mengganti nama jquery.tmpl.min.js menjadi jquery.tmpl.js (dan memperbarui jalur dalam bundel yang sesuai), kedua skrip di-render dengan benar.

Apakah ada beberapa pengaturan konfigurasi yang menyebabkannya mengabaikan file '.min.js'?


Saya menggunakan bundler MVC 4 dan itu termasuk file .min.js.
Eric J.

versi RTM atau RC? itu bekerja ok di RC untuk saya juga
Fatal

10
Idenya adalah bahwa bekerja dalam mode debug, bahwa versi "dev" tanpa minification akan digunakan dan ketika Anda berada dalam mode non-debug, bahwa versi minified diambil. Untuk melihatnya beraksi, ubah nilai debug web.config Anda dari true ke false.
Pieter Germishuys

28
dalam beberapa kasus Anda tidak memiliki versi skrip non-minified. Saya mungkin bisa memahaminya jika kedua file itu ada.
Fatal

1
Sayang sekali bahwa ini berfungsi seperti ini secara default ... tentu saja, file mungkin sudah diperkecil , tapi saya pikir Microsoft gagal melihat manfaat dari menambahkan skrip pra-minified ke bundel untuk tujuan penghilang cache ( vparameter kecil yang bagus hash yang akan ditambahkan ke url, dan perubahan ketika isi file perubahan)
nothingisnecessary

Jawaban:


257

Solusi yang saya posting awalnya dipertanyakan (adalah hack kotor). Perilaku tweak telah berubah dalam Microsoft.AspNet.Web.Optimasi paket dan tweak tidak berfungsi lagi, seperti yang ditunjukkan oleh banyak komentator. Saat ini saya tidak dapat mereproduksi masalah sama sekali dengan versi 1.1.3 dari paket.

Silakan lihat sumber System.Web.Optimization.BundleCollection (Anda dapat menggunakan dotPeek misalnya) untuk pemahaman yang lebih baik tentang apa yang akan Anda lakukan. Baca juga jawaban Max Shmelev .

Jawaban asli :

Ubah nama .min.js menjadi .js atau lakukan sesuatu seperti

    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
Terima kasih dari saya juga - jadi menambahkan ini ke daftar gotcha MVC4 saya :)
Dan B

27
ini waktu yang lama, mereka bisa saja menambahkan file-file min yang dikomentari dengan alasan atau sesuatu untuk hasil, sekarang seluruh jam terbuang bertanya-tanya siapa yang mencuri file skrip saya dari output.
Giedrius

5
Per komentar Fatal dalam OP, solusi ini akan berakhir dengan mendefinisi ulang duplikat referensi untuk versi minified dan reguler jika keduanya ada (misalnya jquery).
danmiser

11
M $, ketika somefile.min.js ditentukan secara eksplisit, atau ketika hanya ada file .min.js, maka hanya sertakan file .min.js! Kalau tidak, terapkan saja perilaku saat ini!
Adaptabi

3
Luar biasa bahwa kelas yang sebenarnya disebut "IgnoreList", namun berasal langsung dari Object. Tidak ada LINQ, tidak ada iterasi. - msdn.microsoft.com/en-us/library/…
JP ten Berge

176

Microsoft menyiratkan perilaku berikut (dan saya lebih suka mengikutinya dalam proyek saya):

versi pendek

  1. Anda memiliki versi skrip debug dan yang diperkecil di proyek Anda di bawah folder yang sama:
    • script.js
    • script.min.js
  2. Anda hanya menambahkan script.js ke bundel dalam kode Anda.

Akibatnya, Anda secara otomatis akan memiliki script.js termasuk dalam mode DEBUG dan script.min.js dalam mode RELEASE .

versi panjang

Anda juga dapat memiliki versi .debug.js . Dalam hal ini file tersebut dimasukkan dalam prioritas berikut di DEBUG:

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

dalam PERS:

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

catatan

Dan omong-omong, satu-satunya alasan untuk memiliki .min versi skrip Anda di MVC4 adalah kasus ketika versi minified tidak dapat diproses secara otomatis. Misalnya kode berikut tidak dapat dikaburkan secara otomatis:

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

Dalam semua kasus lain, Anda bisa menggunakan hanya versi debug naskah Anda.


6
penjelasan yang bagus, masalah OP adalah bahwa beberapa skrip ( jquery.tmpl) tidak memiliki, tidak datang bersama, tidak bisa mengunduh versi file non-min. Bundler mengabaikan file skrip sama sekali jika tidak memiliki versi non-min dalam mode debug
Eonasdan

Setuju, penjelasan yang bagus tapi sama sekali tidak menjawab pertanyaan OP.
Diego

2
Versi pendek tidak berfungsi untuk saya. "script.js" akan dimasukkan dalam kedua jenis rilis ini. Saya beralih DEBUG / RELEASE dan (ketika saya melihat sumbernya) 'script.js' adalah yang dipilih / dirender.
user981375

4
user981375, Anda juga perlu mengatur <kompilasi debug = "false" /> di file web.config
Max Shmelev

5
Saya lebih suka jawaban ini karena ini adalah pendekatan "praktik terbaik" dan menjelaskan bagaimana aturan default bundler dapat diikuti untuk mencapai tujuan yang sama.
James Reategui

5

Jika semua yang Anda miliki adalah versi file yang diperkecil, solusi paling sederhana yang saya temukan adalah menyalin file yang diperkecil, menghapus .min dari nama file yang disalin, kemudian merujuk nama file yang tidak diperkecil dalam bundel Anda.

Sebagai contoh, katakanlah Anda membeli komponen js dan mereka memberi Anda file bernama some-lib-3.2.1.min.js. Untuk menggunakan file ini dalam bundel, lakukan hal berikut:

  1. Salin some-lib-3.2.1.min.js dan ganti nama file yang disalin ke some-lib-3.2.1.js. Sertakan kedua file dalam proyek Anda.

  2. Referensi file non-minify di bundel Anda, seperti ini:

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

Hanya karena file tanpa 'min' dalam nama sebenarnya diperkecil seharusnya tidak menyebabkan masalah (selain fakta bahwa itu pada dasarnya tidak dapat dibaca). Ini hanya digunakan dalam mode debug dan ditulis sebagai skrip terpisah. Ketika tidak dalam mode debug, file min yang dikompilasi sebelumnya harus disertakan dalam bundel Anda.


4

Saya telah menemukan solusi bagus yang berfungsi setidaknya di MVC5, Anda bisa menggunakan Bundlesaja ScriptBundle. Tidak memiliki perilaku cerdas ScriptBundleyang tidak kita sukai (mengabaikan .min, dll.) Dalam kasus ini. Dalam solusi saya, saya gunakan Bundleuntuk skrip pihak 3d dengan file .min dan .map dan saya gunakan ScriptBundleuntuk kode kita. Saya belum melihat adanya kelemahan dalam melakukannya. Untuk membuatnya bekerja dengan cara ini, Anda perlu menambahkan file asli misalnya angular.js, dan itu akan memuat angular.js dalam debug dan itu akan membundel angular.min.js dalam mode rilis.


Tampaknya tidak berfungsi saat optimisasi dinonaktifkan ( ScriptTable.EnableOptimizations = false). Jalur skrip yang berisi pola tidak dirender (mis ~/Scripts/thirdpartylib/*.js.). Ini tidak bekerja ketika EnableOptimizations = true, tetapi begitu ScriptBundle.
Steven Liekens

Saya menggunakannya dengan false juga (selama pengembangan) dan saya tidak memiliki masalah yang Anda uraikan, jadi mungkin ada hal lain yang memengaruhinya untuk Anda. Anda juga perlu melakukan IncludeDirectory alih-alih menyertakan agar pola berfungsi.
Ilya Chernomordik

Apakah Anda yakin itu merender versi ".min.js" dari file Anda? Apakah Anda menggunakan bundel dari namespace System.Web.Optimizationsatau dari paket nuget Microsoft.Web.Optimizations?
Steven Liekens

Saya menggunakan System.Web.Optimization dan saya memeriksa bahwa itu membuat versi min, tapi saya sudah tahu saya tidak menggunakan IncludeDirectory pada kenyataannya, tetapi akan aneh jika itu tidak bekerja dengan versi min meskipun ... Karena IncludeDirectory tidak cukup bagi saya, saya melakukan pemindaian khusus dan menambahkan semua filter menggunakan Include, jadi mungkin bahwa pola dan IncludeDirectory tidak berfungsi dengan baik di sana, meskipun agak aneh.
Ilya Chernomordik

1
Tidak, masalahnya ada dua kali lipat: hanya .min.jsada file, dan *.jspolanya tidak cocok dengan file yang diakhiri .min.js.
Steven Liekens

3

Untuk membuat *.min.jsfile, Anda harus menonaktifkan BundleTable.EnableOptimizations, yang merupakan pengaturan global yang berlaku untuk semua bundel.

Jika Anda ingin mengaktifkan pengoptimalan hanya untuk bundel tertentu, Anda dapat membuat ScriptBundletipe Anda sendiri yang memungkinkan pengoptimalan sementara saat menghitung file dalam bundel.

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

Gunakan OptimizedScriptBundlesebagai ganti ScriptBundleuntuk bundel yang file mininya harus selalu digunakan, terlepas dari apakah ada file yang tidak diperkecil.

Contoh untuk Kendo UI untuk ASP.NET MVC, yang didistribusikan sebagai kumpulan hanya file yang diperkecil.

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

Saya menemukan beberapa skrip yang hilang dalam aksi publikasi produksi, dan berpikir itu adalah masalah MVC, saya menemukan jawaban ini .. lihatlah, kendo terlibat. Setelah bekerja terlalu lama, saya melakukan apa saja untuk menjauh dari kendo
Felipe

@Felipe Saya berada dalam situasi yang sama itulah sebabnya saya menulis jawaban ini. Kendo itu mengerikan. Saya harap teladan saya bermanfaat.
Steven Liekens

2

Untuk kasus saya, saya menggunakan perpustakaan Knockout.js (luar biasa!) Yang muncul sebagai versi Debug / Non:

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

Untuk membuat ini bekerja, saya memasukkan "Knockout- {Version} .js" (non-debug) di Bundle saya dan mendapatkan .debug. File js dalam mode Debug.


1

Cara mudah cukup Ubah nama file .min misalnya, Anda memiliki abc.min.css daripada hanya mengubah nama file ini menjadi abc_min.css dan menambahkan ini ke bundel Anda. Saya tahu ini bukan cara yang tepat untuk melakukannya, tetapi hanya solusi sementara. terima kasih dan selamat coding.


1
Setiap kali nuget mengunduh file, Anda perlu mengganti nama.
Anirudha Gupta

Saya tahu ini bukan cara yang tepat untuk melakukannya, tetapi hanya solusi sementara
RK Sharma

1
taruh baris ini berfungsi untuk saya // BundleTable.EnableOptimizations = true;
Anirudha Gupta

0

Bundler memiliki banyak manfaat, periksa halaman ini TETAPI :

Microsoft MVC4 Platform Mempertimbangkan bahwa Anda memiliki setidaknya versi minify & versi unminified untuk setiap Script atau Style Bundle (file lain seperti Debug dan vsdoc juga tersedia). Jadi Kami memiliki masalah dalam situasi yang hanya ada satu dari file-file ini.

Anda dapat mengubah status debug dalam file web.config secara permanen untuk menangani output:

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

Lihat perubahan output! Pemfilteran file berubah. Untuk memenuhi tujuan tersebut, kita harus mengubah abaikan penyaringan kasus yang akan mengubah logika aplikasi!


1
Menambahkan debug = "false" masih tidak berfungsi untuk saya. file min.js masih belum termasuk meskipun saya menghapus IgnoreList juga ...
MoSs

-21

Teman-teman saya hanya akan menyimpannya sampai Microsoft membuatnya bertindak bersama

Coba ini

Di RegisterBundles buat bundel ini untuk 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"
 ));

Di _Layout.cshtml cantumkan:

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

Dengan cara ini kami mendapatkan bundel terbaik dalam Produksi dan referensi di Debug

Perbaiki ketika Microsoft memperbaiki Kode MVC 4 mereka


3
Saya bukan penggemar solusi yang diusulkan ini sama sekali. Anda sekarang harus mempertahankan kumpulan skrip di (setidaknya) dua tempat
Fatal

Ini cukup banyak mengalahkan tujuan bundling, bukan begitu?
Oliver

4
Bundling sudah berfungsi seperti ini. Jika Anda menjalankan proyek dalam mode debug setiap file CSS dimuat secara individual, namun ketika Anda menjalankan dalam rilis mereka digabungkan dan diperkecil menjadi satu. Kode dalam blok if identik dengan apa yang diberikan pada halaman secara otomatis dalam mode debug.
Chad Levy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.