ASP.NET Bundel cara menonaktifkan minifikasi


185

saya sudah debug="true" di kedua web.config (s) saya , dan saya hanya tidak ingin bundel saya diperkecil, tetapi sepertinya tidak ada yang saya lakukan untuk menonaktifkannya. Saya sudah mencoba enableoptimisations=false, ini kode saya:

//Javascript
bundles.Add(new ScriptBundle("~/bundles/MainJS")
            .Include("~/Scripts/regular/lib/mvc/jquery.validate.unobtrusive.js*")
            .Include("~/Scripts/regular/lib/mvc/jquery.validate*")
            .Include("~/Scripts/regular/lib/bootstrap.js")
            .IncludeDirectory("~/Scripts/regular/modules", "*.js", true)
            .IncludeDirectory("~/Scripts/regular/pages", "*.js", true)
            .IncludeDirectory("~/Scripts/regular/misc", "*.js", true));

//CSS
bundles.Add(new StyleBundle("~/bundles/MainCSS")
            .Include("~/Content/css/regular/lib/bootstrap.css*")
            .IncludeDirectory("~/Content/css/regular/modules", "*.css", true)
            .IncludeDirectory("~/Content/css/regular/pages", "*.css", true))

2
@ RickAnd-MSFT Permintaannya adalah bagaimana mengaktifkan bundling sementara minifikasi dinonaktifkan. Menggunakan web.config debug = true / false atau EnableOptimizations hanya mengaktifkan keduanya atau keduanya mati. Jawaban Martin Devillers memungkinkan bundling diaktifkan saat
minifikasi

2
juga untuk saya .... untuk file 'x.js' di dalam bundel memastikan bahwa TIDAK ada file 'x.min.js' di folder sebaliknya jika Anda telah menghapus transformasi minifikasi .. bundling akan melayani keluar 'file pra' yang dimodifikasi misalnya, jika Anda memiliki 'angular.js' lalu DELETE 'angular.min.js' ;-)
stooboo

Jawaban:


137

Jika Anda memiliki debug="true"di web.config dan menggunakan Scripts/Styles.Renderuntuk referensi bundel di halaman Anda, itu harus mematikan bundling dan minifikasi. BundleTable.EnableOptimizations = falseakan selalu mematikan bundling dan minifikasi juga (terlepas dari flag true / false debug).

Apakah Anda mungkin tidak menggunakan Scripts/Styles.Renderpembantu? Jika Anda secara langsung memberikan referensi ke bundel melalui BundleTable.Bundles.ResolveBundleUrl()Anda akan selalu mendapatkan konten yang diperkecil / dibundel.


12
Dari jawaban ini, saya tidak yakin cara mematikan hanya minification dan meninggalkan bundling di tempat - apakah ini mungkin?
Adam Tuliper - MSFT

33
Untuk melakukan ini, yang paling mudah adalah dengan mengubah Script / StyleBundles keluar untuk Bundel biasa yang tidak memiliki Transform yang ditetapkan secara default, ini akan mematikan minifikasi tetapi masih bundel. Catatan Anda masih harus memiliki EnableOptimizations set true untuk bundling terjadi.
Hao Kung

2
juga untuk saya .... untuk file 'x.js' di dalam bundel memastikan bahwa TIDAK ada file 'x.min.js' di folder sebaliknya jika Anda telah menghapus transformasi minifikasi .. bundling akan melayani keluar 'pre' file minified misalnya jika Anda memiliki 'angular.js' maka DELETE 'angular.min.js' ;-)
stooboo

1
@stooboo Inilah yang memperbaikinya bagi saya, tetapi Anda tidak perlu menghapus apa pun. Cukup sertakan file non-min.
OneHoopyFrood

2
EnableOptimizations = false- di mana kode ini berada?
alex

158

Arahan kompilasi bersyarat adalah teman Anda:

#if DEBUG
            var jsBundle = new Bundle("~/Scripts/js");
#else
            var jsBundle = new ScriptBundle("~/Scripts/js");
#endif

16
Sebenarnya saya pikir dia telah memakukannya - untuk mematikan minifikasi, gunakan Bundle sesuai Hao, jika tidak gunakan ScriptBundle yang bundel dan minify, bukan?
Adam Tuliper - MSFT

1
Ini adalah solusi yang bagus ketika Anda ingin mereferensikan bundel dengan URI referensi bundelnya untuk hal-hal seperti memuat melalui RequireJS tanpa menggunakan sistem bundling / minifikasi sendiri yang disyaratkan.
Norman H

1
Saya melihat hal-hal seperti Adam, saya memahami ScriptBundle sebagai Bundel yang disempurnakan, jadi karena Anda ingin menambahkan referensi dasar (tidak ada pasca operasi tertentu), Bundle menurut saya cara yang baik untuk menonaktifkan minifikasi pada bundel tertentu.
Charles HETIER

6
@ RickAnd-MSFT Saya pikir Anda salah memahami tujuan dari kode ini yang memungkinkan bundling + tidak ada minifikasi dalam mode debug dan bundling + minification dalam mode rilis. Menggunakan web.config debug = true / false atau EnableOptimizations hanya mengaktifkan keduanya atau keduanya mati. Saya membaca komentar Anda dan menolak solusi Martin ini, hanya untuk mengetahui bahwa itu sebenarnya cara yang sangat baik untuk memiliki bundling tanpa
minifikasi

-1 "solusi" ini adalah celah-berhenti di terbaik. Pada kenyataannya, meskipun berfungsi, ini mengarah pada kode yang sangat tidak dapat diubah. Tapi itu bukan hal terburuk tentang itu. Menggunakan "Bundel" mengarah ke aset yang diserahkan oleh server dengan tipe mime diatur ke "teks / html" alih-alih "teks / javascript". Jika Anda menerapkan pendekatan ini untuk bundling file css yang Anda mainkan dengan api saat dalam mode debug. Jangan. Hanya saja, jangan. Lihat jawaban saya untuk pendekatan yang lebih sehat yang bekerja di bagian produksi.
XDS

89

Untuk menonaktifkan bundling dan minifikasi, cukup letakkan ini file .aspx Anda (ini akan menonaktifkan optimasi meskipun debug=truedi web.config )

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c # .net

System.Web.Optimization.BundleTable.EnableOptimizations = false;

Jika Anda meletakkan EnableOptimizations = trueini akan bundel dan diperkecil bahkan jika debug=truedi web.config


2
Ini adalah satu-satunya hal yang memperbaiki masalah bagi saya. Saya punya debug="true"dan benar Script.Rendertetapi itu masih tidak berhasil. Perhatikan juga bahwa ini tidak akan mem-server file .min.js apa pun, jadi pastikan untuk menyertakan salinan kode dependensi yang tidak ditentukan.
OneHoopyFrood

2
@ TC: Apakah saya salah dalam berpikir bahwa sintaks vb.net harus memiliki modal False?
jeremysawesome

@ jeremysawesome oh yeah saya pikir itu benar, poin bagus :-) Saya bukan programmer VB sangat sering jadi saya bahkan tidak memperhatikan ...
TCC

1
Baris pertama harus "... walaupun debug = false" tidak?
UnionP

2
vb.Net tidak peduli dengan kasus, False = false, seperti .tostring () = .toString ()
manuel

68

Anda dapat mematikan minifikasi dalam bundel Anda hanya dengan Menghapus transformasi Anda.

var scriptBundle = new ScriptBundle("~/bundles/scriptBundle");
...
scriptBundle.Transforms.Clear();

Saya pribadi menemukan ini berguna ketika ingin menggabungkan semua skrip saya dalam satu file tetapi membutuhkan keterbacaan selama fase debugging.


1
-1 Inilah naga: Merobek JsMinifier / CssMinifier juga merobek mekanisme internal yang menetapkan tipe mime menjadi "text / css" atau "text / javascript". Ini tidak menyebabkan masalah dalam mode debug / rilis tetapi itu mendatangkan malapetaka pada css-bundle dalam konteks build yang diterbitkan (alias penyebaran langsung): Chrome dan firefox menolak untuk memuat kata css-bundel yang menyatakan bahwa tipe mime mereka disetel untuk "text / html" bukan "text / css". Dengan js-bundles, latihan entah bagaimana tapi mencurigakan yang terbaik untuk memiliki js-bundle diserahkan sebagai "teks / html" (<- serius?). Lihat jawaban saya untuk pendekatan yang benar.
XDS

28

Saya mencoba banyak saran ini tetapi sepertinya berhasil. Saya telah membuang beberapa jam hanya untuk mengetahui bahwa ini adalah kesalahan saya:

@Scripts.Render("/bundles/foundation")

Itu selalu membuat saya memperkecil dan membundel javascript, tidak peduli apa yang saya coba. Sebaliknya, saya seharusnya menggunakan ini:

@Scripts.Render("~/bundles/foundation")

Ekstra '~' berhasil. Saya bahkan telah menghapusnya lagi hanya dalam satu contoh untuk melihat apakah itu benar-benar itu. Itu ... semoga aku bisa menyelamatkan setidaknya satu orang dari jam yang aku habiskan untuk ini.


Wow, aku sudah gila selama 3 jam terakhir ini ...
Bodokh

24

Kombinasikan beberapa jawaban, ini berfungsi untuk saya di ASP.NET MVC 4.

        bundles.Add(new ScriptBundle("~/Scripts/Common/js")
            .Include("~/Scripts/jquery-1.8.3.js")
            .Include("~/Scripts/zizhujy.com.js")
            .Include("~/Scripts/Globalize.js")
            .Include("~/Scripts/common.js")
            .Include("~/Scripts/requireLite/requireLite.js"));

        bundles.Add(new StyleBundle("~/Content/appLayoutStyles")
            .Include("~/Content/AppLayout.css"));

        bundles.Add(new StyleBundle("~/Content/css/App/FunGrapherStyles")
            .Include("~/Content/css/Apps/FunGrapher.css")
            .Include("~/Content/css/tables.css"));

#if DEBUG
        foreach (var bundle in BundleTable.Bundles)
        {
            bundle.Transforms.Clear();
        }
#endif

21

Ada juga beberapa cara sederhana untuk mengontrol minifikasi (dan fitur lainnya) secara manual. Ini menggunakan transformator CssMinify () baru , seperti ini:

// this is in case when BundleTable.EnableOptimizations = false;
var myBundle = new StyleBundle("~/Content/themes/base/css")
    .Include("~/Content/themes/base/jquery.ui.core.css" /* , ... and so on */);
myBundle.Transforms.Add(new CssMinify());
bundles.Add(myBundle);

// or you can remove that transformer in opposite situation
myBundle.Transforms.Clear();

Itu nyaman ketika Anda ingin memiliki beberapa bagian bundel khusus hanya untuk diperkecil. Katakanlah, Anda menggunakan beberapa gaya standar (jQuery), yang semakin membantu (mengambil banyak permintaan peramban berlebihan), tetapi Anda ingin tetap tidak menggunakan stylesheet Anda sendiri. (Sama - dengan javascript).


13

Saya menggabungkan beberapa jawaban yang diberikan oleh orang lain dalam pertanyaan ini untuk menghasilkan solusi alternatif lain.

Tujuan: Untuk selalu bundel file, untuk menonaktifkan JS dan minifikasi dalam hal itu<compilation debug="true" ... /> dan untuk selalu menerapkan transformasi kustom ke bundel CSS.

Solusi saya :

1) Dalam web.config : <compilation debug="true" ... />

2) Dalam metode Global.asax Application_Start () :

 protected void Application_Start() {
     ...
     BundleTable.EnableOptimizations = true; // Force bundling to occur

     // If the compilation node in web.config indicates debugging mode is enabled
     // then clear all transforms. I.e. disable Js and CSS minification.
     if (HttpContext.Current.IsDebuggingEnabled) {
         BundleTable.Bundles.ToList().ForEach(b => b.Transforms.Clear());
     }

      // Add a custom CSS bundle transformer. In my case the transformer replaces a
      // token in the CSS file with an AppConfig value representing the website URL
      // in the current environment. E.g. www.mydevwebsite in Dev and
      // www.myprodwebsite.com in Production.
      BundleTable.Bundles.ToList()
          .FindAll(x => x.GetType() == typeof(StyleBundle))
          .ForEach(b => b.Transforms.Add(new MyStyleBundleTransformer()));
     ...
}

7

Jika Anda menyetel properti berikut ke false maka itu akan menonaktifkan bundling dan minifikasi.

Dalam file Global.asax.cs , tambahkan baris seperti yang disebutkan di bawah ini

protected void Application_Start()
{
    System.Web.Optimization.BundleTable.EnableOptimizations = false;
}

Saya hanya tidak mengerti mengapa lebih sedikit file saya diubah menjadi css ketika fitur ini dimatikan? Saat saya mengaktifkan pengoptimalan, bundling lebih sedikit file tidak berfungsi lagi.
FrenkyB

5

Berikut cara menonaktifkan minifikasi berdasarkan per-bundel:

bundles.Add(new StyleBundleRaw("~/Content/foobarcss").Include("/some/path/foobar.css"));
bundles.Add(new ScriptBundleRaw("~/Bundles/foobarjs").Include("/some/path/foobar.js"));

Sidenote: Path yang digunakan untuk bundel Anda tidak boleh bertepatan dengan path aktual di build yang Anda terbitkan jika tidak tidak akan ada yang berhasil. Pastikan juga untuk tidak menggunakan .js, .css, dan / atau '.' dan '_' di mana saja atas nama bundel. Pertahankan nama sesederhana dan semudah mungkin, seperti pada contoh di atas.

Kelas pembantu ditampilkan di bawah ini. Perhatikan bahwa untuk membuat kelas-kelas ini menjadi bukti di masa depan, kami dengan pembedahan menghapus contoh minisikan js / css alih-alih menggunakan .clear () dan kami juga memasukkan transformasi tipe-setter mime yang tanpanya pembuatan produksi pasti akan mengalami masalah terutama ketika ia datang untuk menyerahkan css-bundle dengan benar (firefox dan chrome menolak bundel css dengan tipe mime di set ke "text / html" yang merupakan default):

internal sealed class StyleBundleRaw : StyleBundle
{
        private static readonly BundleMimeType CssContentMimeType = new BundleMimeType("text/css");

        public StyleBundleRaw(string virtualPath) : this(virtualPath, cdnPath: null)
        {
        }

        public StyleBundleRaw(string virtualPath, string cdnPath) : base(virtualPath, cdnPath)
        {
                 Transforms.Add(CssContentMimeType); //0 vital
                 Transforms.Remove(Transforms.FirstOrDefault(x => x is CssMinify)); //0
        }
        //0 the guys at redmond in their infinite wisdom plugged the mimetype "text/css" right into cssminify    upon unwiring the minifier we
        //  need to somehow reenable the cssbundle to specify its mimetype otherwise it will advertise itself as html and wont load
}

internal sealed class ScriptBundleRaw : ScriptBundle
{
        private static readonly BundleMimeType JsContentMimeType = new BundleMimeType("text/javascript");

        public ScriptBundleRaw(string virtualPath) : this(virtualPath, cdnPath: null)
        {
        }

        public ScriptBundleRaw(string virtualPath, string cdnPath) : base(virtualPath, cdnPath)
        {
                 Transforms.Add(JsContentMimeType); //0 vital
                 Transforms.Remove(Transforms.FirstOrDefault(x => x is JsMinify)); //0
        }
        //0 the guys at redmond in their infinite wisdom plugged the mimetype "text/javascript" right into jsminify   upon unwiring the minifier we need
        //  to somehow reenable the jsbundle to specify its mimetype otherwise it will advertise itself as html causing it to be become unloadable by the browsers in published production builds
}

internal sealed class BundleMimeType : IBundleTransform
{
        private readonly string _mimeType;

        public BundleMimeType(string mimeType) { _mimeType = mimeType; }

        public void Process(BundleContext context, BundleResponse response)
        {
                 if (context == null)
                          throw new ArgumentNullException(nameof(context));
                 if (response == null)
                          throw new ArgumentNullException(nameof(response));

         response.ContentType = _mimeType;
        }
}

Agar semua ini berfungsi, Anda harus menginstal (via nuget):

WebGrease 1.6.0+ Microsoft.AspNet.Web.Optimization 1.1.3+

Dan web.config Anda harus diperkaya seperti:

<runtime>
       [...]
       <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-x.y.z.t" newVersion="x.y.z.t" />
       </dependentAssembly>
       <dependentAssembly>
              <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-x.y.z.t" newVersion="x.y.z.t" />
       </dependentAssembly>
        [...]
</runtime>

<!-- setting mimetypes like we do right below is absolutely vital for published builds because for some reason the -->
<!-- iis servers in production environments somehow dont know how to handle otf eot and other font related files   -->
</system.webServer>
        [...]
        <staticContent>
      <!-- in case iis already has these mime types -->
      <remove fileExtension=".otf" />
      <remove fileExtension=".eot" />
      <remove fileExtension=".ttf" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />

      <mimeMap fileExtension=".otf" mimeType="font/otf" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
      </staticContent>

      <!-- also vital otherwise published builds wont work  https://stackoverflow.com/a/13597128/863651  -->
      <modules runAllManagedModulesForAllRequests="true">
         <remove name="BundleModule" />
         <add name="BundleModule" type="System.Web.Optimization.BundleModule" />
      </modules>
      [...]
</system.webServer>

Perhatikan bahwa Anda mungkin harus mengambil langkah-langkah tambahan untuk membuat css-bundel Anda berfungsi dalam hal font dll. Tapi itu cerita yang berbeda.


4

Hanya untuk melengkapi jawaban yang telah diberikan, jika Anda juga TIDAK ingin mengecilkan / mengaburkan / menggabungkan beberapa file sambil tetap memungkinkan bundling penuh dan minifikasi untuk file lain , pilihan terbaik adalah pergi dengan renderer kustom yang akan membaca isi dari bundel tertentu (s) dan render file di halaman daripada membuat jalur virtual bundel. Saya pribadi memerlukan ini karena IE 9 adalah $ *% @ ing tempat tidur ketika file CSS saya dibundel bahkan dengan minifikasi dimatikan .

Terima kasih banyak untuk artikel ini , yang memberi saya titik awal untuk kode yang saya gunakan untuk membuat CSS Renderer yang akan membuat file untuk CSS tetapi masih memungkinkan sistem untuk membuat file javascript saya dibundel / diperkecil / dikaburkan.

Menciptakan kelas pembantu statis:

using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;

namespace Helpers
{
  public static class OptionalCssBundler
  {
    const string CssTemplate = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";

    public static MvcHtmlString ResolveBundleUrl(string bundleUrl, bool bundle)
    {
      return bundle ? BundledFiles(BundleTable.Bundles.ResolveBundleUrl(bundleUrl)) : UnbundledFiles(bundleUrl);
    }

    private static MvcHtmlString BundledFiles(string bundleVirtualPath)
    {
      return new MvcHtmlString(string.Format(CssTemplate, bundleVirtualPath));
    }

    private static MvcHtmlString UnbundledFiles(string bundleUrl)
    {
      var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);

      StringBuilder sb = new StringBuilder();
      var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

      foreach (BundleFile file in bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl)))
      {
        sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath));
      }

      return new MvcHtmlString(sb.ToString());
    }

    public static MvcHtmlString Render(string bundleUrl, bool bundle)
    {
      return ResolveBundleUrl(bundleUrl, bundle);
    }
  }

}

Kemudian di file tata letak pisau cukur:

@OptionalCssBundler.Render("~/Content/css", false)

bukannya standar:

@Styles.Render("~/Content/css")

Saya yakin membuat renderer opsional untuk file javascript juga membutuhkan sedikit pembaruan untuk bantuan ini.


1
Bekerja dengan baik. Jika Anda ingin url berubah ketika file diperbarui, Anda dapat mengubah CssTemplateke sesuatu seperti "<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />"dan mengubah sb.AppendFormatbaris ke sesuatu sepertisb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo

Benar, kami melakukan banyak hal seperti itu di tempat kerja. Kami memiliki string statis publik yang disebut JSVersion yang kami masukkan ke dalam kelas Global.asax yang menarik maj / min / build / rev majelis pelaksana. Kami kemudian mereferensikannya seperti ini: <script type = "text / javascript" src = "Scripts / jsfile_name.js <% = Global.JSVersion%>"> </script>
James Eby

3

Pencarian untuk EnableOptimizations kata kunci di proyek Anda

Jadi jika Anda menemukannya

BundleTable.EnableOptimizations = true;

putar itu false.


2
Ini menonaktifkan minifikasi, tetapi juga menonaktifkan bundling sepenuhnya, yang saya pikir setidaknya harus dicatat.
John Pavek

1

Jika Anda menggunakan transformasi KURANG / SASS CSS ada opsi useNativeMinificationyang dapat disetel ke false untuk menonaktifkan minifikasi (di web.config). Untuk tujuan saya, saya hanya mengubahnya di sini ketika saya perlu, tetapi Anda bisa menggunakan transformasi web.config untuk selalu mengaktifkannya pada rilis rilis atau mungkin menemukan cara memodifikasinya dalam kode.

<less useNativeMinification="false" ieCompat="true" strictMath="false"
      strictUnits="false" dumpLineNumbers="None">

Kiat: Inti dari semua ini adalah untuk melihat CSS Anda, yang dapat Anda lakukan di browser memeriksa alat atau hanya dengan membuka file. Ketika bundling diaktifkan, nama file berubah pada setiap kompilasi jadi saya menempatkan yang berikut di bagian atas halaman saya sehingga saya dapat melihat CSS kompilasi saya setiap hari di jendela browser baru setiap kali itu berubah.

@if (Debugger.IsAttached) 
{
    <a href="@Styles.Url(ViewBag.CSS)" target="css">View CSS</a>
}

ini akan menjadi semacam URL dinamis https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


Pembaruan: Saya membuat transformasi web.config untuk menjadikannya benar bagi saya selama pembuatan penyebaran / rilis

  <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
    <less xdt:Transform="Replace" useNativeMinification="true" ieCompat="true" strictMath="false" strictUnits="false" dumpLineNumbers="None">
      <jsEngine name="MsieJsEngine" />
    </less>
  </bundleTransformer>

1
Nama file TIDAK berubah pada setiap kompilasi. Itu didasarkan pada konten file, sehingga itu berubah setiap kali file berubah.
Jim Raden

1

Ini mungkin berguna bagi seseorang di masa depan karena kerangka kerja baru, ketika pengaturan melalui VS, mendapat default web.config, web.Debug.configdan web.Release.config. Di dalam web.release.configAnda akan menemukan baris ini:

<compilation xdt:Transform="RemoveAttributes(debug)" />

ini sepertinya menimpa setiap perubahan sebaris yang saya buat. Saya mengomentari baris ini dan kami sangat senang (dalam hal melihat kode non-minify di build "release")

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.