ASP.NET Пакети, як відключити мінімізацію


185

У мене є debug="true"обидва мої web.config (и) , і я просто не хочу, щоб мої пакети були впорядковані, але нічого, що я роблю, здається, це не відключає. Я спробував enableoptimisations=false, ось мій код:

//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 Запит полягає в тому, як увімкнути групування під час вимкнення мінімізації. Використання налагодження web.config = true / false або EnableOptimizations увімкнено або вимкнено або обидва. Відповідь Martin Девіого дозволяє пакетування бути включений в той час як мініфікація відключений
guymid

2
також для мене .... для файлу 'x.js' у пакеті переконайтесь, що у папці НЕ є файл 'x.min.js', інакше, хоча ви видалили трансформацію мінімізації. 'попередньо' мінімізований файл, наприклад, якщо у вас є 'angular.js', то ВИДАЛИТИ 'angular.min.js' ;-)
stooboo

Відповіді:


137

Якщо у вас є debug="true"в web.config і використовується Scripts/Styles.Renderдля посилання на пакети на ваших сторінках, що слід відключити як пакетування і Мінімізація. BundleTable.EnableOptimizations = falseзавжди буде вимикати також поєднання та мінімізацію (незалежно від істинного / хибного прапора налагодження).

Ви, можливо, не використовуєте Scripts/Styles.Renderпомічників? Якщо ви безпосередньо надаєте посилання на пакет, BundleTable.Bundles.ResolveBundleUrl()ви завжди отримаєте мінімізований / пакетний вміст.


12
З цієї відповіді я не впевнений, як вимкнути просто мінімізацію та залишити групування на місці - чи можливо це?
Адам Туліпер - MSFT

33
Для цього найпростіше було б змінити Script / StyleBundles для звичайних пакетів, у яких за замовчуванням не встановлено Transform, це призведе до вимкнення мінімізації, але все-таки розшарування. Зауважте, що для того, щоб відбуватись пакетування, вам все одно доведеться встановити значення "EnableOptimizations" на "true".
Хао Кунг

2
також для мене .... для файлу 'x.js' у пакеті переконайтесь, що у папці НЕ є файл 'x.min.js', інакше, хоча ви видалили трансформацію мінімізації .. Пакет буде обслуговувати 'попередньо' мінімізований файл, наприклад, якщо у вас є 'angular.js', то ВИДАЛИТИ 'angular.min.js' ;-)
stooboo

1
@stooboo Це для мене виправлено, але нічого видаляти не потрібно. Просто включіть нехвилинний файл.
OneHoopyFrood

2
EnableOptimizations = false- куди належить цей код?
alex

158

Умовні директиви компіляції - ваш друг:

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

16
Насправді я думаю, що він його прибив - для того, щоб просто вимкнути мініфікацію, використовуйте Bundle за Хао, інакше використовуйте ScriptBundle, який зв'язує та мінімізує, ні?
Адам Туліпер - MSFT

1
Це чудове рішення, коли ви хочете посилатися на пакет за його посиланням URI для таких речей, як завантаження через RequireJS, не використовуючи власну систему зв'язування / мінімізації RequireJS.
Норман Н

1
Я бачу такі речі, як Адам, я розумію ScriptBundle як розширений пакет, тому оскільки ви хочете додати базову посилання (ніяких конкретних післяопераційних операцій), Bundle мені здається гарним способом відключити мінімізацію певного пакету.
Чарльз ХЕТЬЄР

6
@ RickAnd-MSFT Я думаю, що ви неправильно розумієте мету цього коду, який дозволяє поєднувати + не мінімізувати в режимі налагодження, а також зв'язувати + мінімізувати у режимі випуску. Використання налагодження web.config = true / false або EnableOptimizations увімкнено або вимкнено або обидва. Я прочитав ваш коментар і відхилив це рішення Мартіна, лише щоб дізнатися, що це насправді дуже хороший спосіб
згрупування

-1 це "рішення" є кращим проміжком. Насправді, навіть якщо це працює, це призводить до дуже некерованого коду. Але це не найгірше в цьому. Використання "Bundle" призводить до передачі активів сервером з mime-типу, встановленим на "text / html" замість "text / javascript". Якщо ви застосовуєте цей підхід для з’єднання файлів css, ви граєте з вогнем у режимі налагодження. Не варто. Просто ні. Дивіться мою відповідь щодо більш здорового підходу, який працює на виробництві.
XDS

89

Щоб вимкнути пакет та мінімізацію, просто покладіть цей файл .aspx (це вимкне оптимізацію, навіть якщо debug=trueв web.config )

vb.net:

System.Web.Optimization.BundleTable.EnableOptimizations = false

c # .net

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

Якщо ви поставите EnableOptimizations = trueце, він буде вбудовуватися та зменшуватись, навіть якщо debug=trueв web.config


2
Це єдине, що вирішило проблему для мене. Я мав debug="true"і право, Script.Renderале все ще не працювало. Також зауважте, що це не буде сервером жодних .min.js файлів, тому обов'язково додайте копії коду залежності.
OneHoopyFrood

2
@TCC: я помиляюся, думаючи, що синтаксис vb.net має мати велику літери False?
jeremysawesome

@jeremysawesome о так, я думаю, що це правильно, хороший момент :-) Я не часто програміст VB, тому я навіть не помічав ...
TCC

1
Перший рядок повинен бути "... навіть якщо debug = false" ні?
UnionP

2
vb.Net не дбає про те разі, Помилкові = False, як .ToString () = .ToString ()
Мануел

67

Ви можете вимкнути мінімізацію в своїх пакетах, просто очистивши перетворення.

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

Я особисто вважав це корисним, коли хотів з'єднати всі мої сценарії в один файл, але потребував читабельності під час фаз налагодження.


1
-1 Ось дракони: зірвавши JsMinifier / CssMinifier також зірве внутрішній механізм, який встановлює mime-тип на "text / css" або "text / javascript". Це не спричиняє проблем у режимі налагодження / випуску, але це спричиняє загрозу в css-розшаруваннях у контексті опублікованих збірок (він же живих розгортань): Chrome і firefox відмовляються завантажувати згадані пакети css, вказуючи, що їхні типи mime встановлені на "text / html" замість "text / css". З js-пачками речі тренуються якось, але в його кращих випадках найкраще мати js-пакет, переданий як "текст / html" (<- серйозно?). Дивіться мою відповідь щодо правильного підходу.
XDS

28

Я перепробував багато цих пропозицій, але, здавалося, спрацював. Я витратив досить багато годин, тільки щоб дізнатися, що це моя помилка:

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

У мене завжди є мінімізований і пакетний javascript, незалежно від того, що я намагався. Натомість я повинен був використовувати це:

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

Додатковий '~' це зробив. Я навіть знову його видалив лише в одному екземплярі, щоб побачити, чи це було насправді. Було ... сподіваюся, я можу врятувати хоча б одну людину годин, які я витрачав на це.


Ух, я божеволіла останні 3 години за цим ...
Бодох

24

Поєднайте кілька відповідей, це працює для мене в 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

Існує також простий спосіб керувати мінімізацією (та іншими функціями) вручну. Це новий трансформатор CssMinify (), використовуючи, як це:

// 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();

Це зручно, коли ви хочете, щоб деякі спеціальні деталі в'язки були лише мінімізовані. Скажімо, ви використовуєте деякі стандартні стилі (jQuery), які стають вам під ноги (беручи до них багато надмірних запитів браузера), але ви хочете не змінити свій власний таблицю стилів. (Те саме - з javascript).


13

Я поєднав декілька відповідей, даних іншими у цьому питанні, щоб створити інше альтернативне рішення.

Мета: Завжди поєднувати файли, відключати мінімізацію JS та CSS у випадку, коли <compilation debug="true" ... />та завжди застосовувати спеціальне перетворення до пакету CSS.

Моє рішення :

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

2) У методі 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

Якщо встановити вказане властивість як false, воно вимкне і поєднання, і мінімізацію.

У файл Global.asax.cs додайте рядок, як зазначено нижче

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

Я просто не розумію, чому мої менші файли перетворюються в css, коли ця функція вимкнена? Коли я вмикаю оптимізацію, поєднання менших файлів більше не працює.
FrenkyB

5

Ось як відключити мінімізацію на основі групи:

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

Сторінка: Шляхи, використовувані для ваших наборів, не повинні збігатися з жодним фактичним шляхом у опублікованих складах, інакше нічого не буде працювати. Також не забудьте уникнути використання .js, .css та / або '.' та "_" в будь-якій точці назви пакета. Зберігайте ім’я максимально просто та максимально просто, як у прикладі вище.

Класи помічників показані нижче. Зауважте, що для того, щоб зробити ці класи захищеними від майбутнього, ми хірургічно видаляємо екземпляри, що мінімізують js / css, замість цього. мова йде про належну передачу пакетів css (firefox та chrome відхиляти пакети css з типом mime, встановленим на "text / html", що є типовим):

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

Щоб зробити цю роботу всім вам потрібно встановити (через nuget):

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

І ваш web.config має бути збагачений так:

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

Зауважте, що вам, можливо, доведеться вжити додаткових кроків, щоб змусити свої пакети css працювати з точки зору шрифтів тощо. Але це вже інша історія.


4

Просто для доповнення вже наданих відповідей, якщо ви також хочете НЕ пом'якшувати / придушувати / об'єднувати деякі файли, одночасно дозволяючи повне поєднання та мінімізацію інших файлів, найкращим варіантом є використання спеціального рендерінга, який буде читати вміст певного пакету. (і) та візуалізувати файли на сторінці, а не віртуальний шлях пакета. Я особисто вимагав цього, тому що IE 9 становив $ *% @ ing ліжко, коли мої файли CSS постачалися в комплекті навіть із мінімізацією, вимкненою .

Велике спасибі цій статті , яка дала мені вихідну точку для коду, який я використовував для створення CSS-рендеріра, який би візуалізував файли для CSS, але все ж дозволяв системі надавати мої файли javascript в комплекті / мінімізовані / непримітні.

Створено статичний клас помічників:

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

}

Потім у файлі компонування бритви:

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

замість стандартних:

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

Я впевнений, що для створення необов'язкового рендеріра для файлів javascript також не потрібно буде оновити цей помічник.


1
Добре працює. Якщо ви хочете, щоб URL-адреси змінювалися під час оновлення файлів, ви можете змінити CssTemplateщось на зразок "<link href=\"{0}?f={1}\" rel=\"stylesheet\" type=\"text/css\" />"і змінити sb.AppendFormatрядок на щось на кшталтsb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(file.VirtualFile.VirtualPath), System.IO.File.GetLastWriteTimeUtc(HttpContext.Current.Server.MapPath(file.IncludedVirtualPath)).Ticks);
franzo

Правда, ми робили щось подібне на роботі. У нас була загальнодоступна статична рядок під назвою JSVersion, яку ми помістили в клас Global.asax, який витягнув maj / min / build / rev виконуючої збірки. Потім ми посилаємось на нього так: <script type = "text / javascript" src = "Scripts / jsfile_name.js <% = Global.JSVersion%>"> </script>
Джеймс Ебі

3

Шукайте EnableOptimizationsключове слово у вашому проекті

Тож якщо знайдеш

BundleTable.EnableOptimizations = true;

переверніть його false.


2
Це вимикає мінімізацію, але також вимикає групування, що, принаймні, слід зазначити.
Джон Павек

1

Якщо ви використовуєте LESS / SASS CSS перетворення, є параметр, useNativeMinificationякий може бути встановлено на false, щоб вимкнути мінімізацію (у web.config). Для своїх цілей я просто змінюю його тут, коли мені потрібно, але ви можете використовувати перетворення web.config, щоб завжди включати його під час створення релізу або, можливо, знаходити спосіб змінити його в коді.

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

Порада: Вся справа в тому, щоб переглянути свій CSS, що ви можете зробити в інструментах огляду браузера або просто відкривши файл. Якщо ввімкнено групування, ім'я файлу змінюється для кожної компіляції, тому я ставлю наступне у верхній частині сторінки, щоб я міг легко переглядати скомпільований CSS у новому вікні браузера кожного разу, коли він змінюється.

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

це буде динамічна URL-адреса щось на кшталт https://example.com/Content/css/bundlename?v=UGd0FjvFJz3ETxlNN9NVqNOeYMRrOkQAkYtB04KisCQ1


Оновлення: я створив перетворення web.config, щоб встановити його як істинне для мене під час збирання / випуску

  <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
Ім'я файлу НЕ змінюється для кожної компіляції. Він заснований на вмісті файлу, тому він змінюється щоразу, коли файл змінюється.
Джим Раден

1

Це може виявитися корисним для кого - то в майбутньому , так як нові рамки, коли установка через VS, отримує значення по замовчуванням web.config, web.Debug.configі web.Release.config. У розділі web.release.configви знайдете цей рядок:

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

це, здавалося, відміняло будь-які внесені зміни. Я прокоментував цей рядок, і ми виявили підтягування (з точки зору бачення нескороченого коду у складі "реліз")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.