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.
Эрик Дж.

версия RTM или RC? у меня в RC все работало нормально
Fatal

10
Идея заключается в том, что при работе в режиме отладки будет использоваться версия «dev» без минификации, а когда вы находитесь в режиме без отладки, выбирается минимизированная версия. Чтобы увидеть его в действии, измените значение отладки web.config с true на false.
Питер Гермишуйс

28
в некоторых случаях у вас нет неунифицированной версии скрипта. Я мог бы , возможно , понять его , если существуют оба файла.
Роковой

1
Обидно , что по умолчанию это работает так ... конечно, файл, возможно, уже уменьшен , но я думаю, что Microsoft не смогла увидеть преимущества добавления предварительно минимизированных сценариев в пакеты для очистки кеша (хороший маленький vхэш параметра который добавляется в URL и изменяется при изменении содержимого файла)
ничего не нужно

Ответы:


257

Решение, которое я первоначально отправил, сомнительно (грязный взлом). Поведение изменено в пакете Microsoft.AspNet.Web.Optimization, и оно больше не работает, как отмечают многие комментаторы. Прямо сейчас я не могу воспроизвести проблему вообще с версией 1.1.3 пакета.

Пожалуйста, ознакомьтесь с источниками System.Web.Optimization.BundleCollection (вы можете использовать dotPeek, например) для лучшего понимания того, что вы собираетесь делать. Также прочитайте ответ Макса Шмелева .

Оригинальный ответ :

Либо переименуйте .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
Спасибо от меня тоже - так что добавив это в мой список MVC4 гоча :)
Дэн Б

27
это был долгий момент, они могли добавлять эти минимальные файлы, закомментированные с указанием причины или чего-то, что привело к результату, теперь целый час тратился на размышления о том, кто крадет мои файлы сценариев из вывода.
Гиедриус

5
Согласно комментарию Фатала в OP, это решение в конечном итоге будет перерабатывать дубликаты ссылок для минимизированной и обычной версий, если они обе существуют (например, jquery).
Данмизер

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. У вас есть отладочная и свернутая версии скрипта в вашем проекте в одной папке:
    • script.js
    • script.min.js
  2. Вы добавляете только script.js в пакет в своем коде.

В результате вы будете автоматически были в script.js включены в DEBUG режиме и script.min.js в RELEASE режиме.

длинная версия

Вы также можете иметь версию .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
хорошее объяснение, однако, проблема ОП заключалась в том, что некоторые скрипты ( jquery.tmpl) не имели, не поставлялись, не загружались неминовой версии файла. Бандлер полностью игнорирует файлы сценариев, если у него нет
неминовой

Согласитесь, хорошее объяснение, но оно не отвечает на все вопросы ОП.
Диего

2
Короткая версия не работает для меня. «script.js» будет включен в оба этих типа выпуска. Я переключил DEBUG / RELEASE и (когда я посмотрел на источник) был выбран скрипт / script. Js.
user981375

4
user981375, вам также нужно установить <compilation debug = "false" /> в файле web.config
Макс Шмелев,

5
Я предпочитаю этот ответ, потому что это подход "передового опыта" и объясняет, как можно следовать правилам по умолчанию для достижения той же цели.
Джеймс Реатеги

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' в имени на самом деле минимизирован, не должно вызывать каких-либо проблем (кроме того факта, что он по сути не читается). Он используется только в режиме отладки и записывается в виде отдельного скрипта. Когда не в режиме отладки, предварительно скомпилированный файл 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.
Стивен Лиекенс

Я также использую его с false (во время разработки), и у меня нет проблем, которые вы описываете, так что это может быть что-то еще, что влияет на вас. Вам также нужно сделать IncludeDirectory вместо include для работы шаблона.
Илья Черномордик

Вы уверены, что он отображает ".min.js" версию вашего файла? Вы используете пакеты из пространства имен System.Web.Optimizationsили из пакета nuget Microsoft.Web.Optimizations?
Стивен Лиекенс

Я использую System.Web.Optimization и проверил, что он отображает минимальную версию, но я понял, что фактически не использую IncludeDirectory, но было бы странно, если бы это не работало с минимальной версией ... Поскольку IncludeDirectory не работает для меня достаточно, я делаю пользовательское сканирование и добавляю все фильтры, используя Include, поэтому может быть, что pattern и IncludeDirectory там не работают должным образом, хотя это немного странно.
Илья Черномордик

1
Нет, проблема двоякая: существует только .min.jsфайл, и *.jsшаблон не соответствует файлам, оканчивающимся на .min.js.
Стивен Лиекенс

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, я нашел этот ответ ... и вот, кендо участвует. Проработав с этим слишком долго, я делаю все, чтобы убежать от кендо
Фелипе

@ Филип Я был в такой же ситуации, поэтому я написал этот ответ. Кендо ужасен. Я надеюсь, что мой пример полезен.
Стивен Лиекенс

2

В моем случае я использовал (замечательно!) Библиотеку Knockout.js, которая поставляется в виде отладочной / не версии:

"~/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 скачивает файл, вам нужно переименовать его.
Анирудха Гупта

Я знаю, что это не правильный способ сделать это, а просто временное решение
Р.К. Шарма

1
поставить эту строку у меня работают // BundleTable.EnableOptimizations = true;
Анирудха Гупта

0

Bundler имеет много преимуществ, проверьте эту страницу, НО :

Платформа Microsoft MVC4 Предполагается, что у вас есть как минимум минифицированная версия, так и не минимизированная версия для каждого Script или Style Bundle (также доступны другие файлы, такие как Debug и vsdoc). Поэтому у нас возникают проблемы в ситуациях, когда существует только один из этих файлов.

Вы можете изменить состояние отладки в файле web.config навсегда для обработки вывода:

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

Смотрите выходные изменения! Фильтрация файлов изменена. Для достижения цели мы должны изменить игнорирование фильтрации случаев, что изменит логику приложения!


1
Добавление debug = "false" все еще не работает для меня. Файлы min.js по-прежнему не включены, хотя я также очищаю IgnoreList ...
MoSs

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

Таким образом, мы получаем лучшие комплекты в Production и ссылку в Debug.

Исправьте это, когда Microsoft исправляет их код MVC 4


3
Я не фанат этого предложенного решения вообще. Теперь вам нужно поддерживать набор скриптов в (как минимум) двух местах
Fatal

Это в значительной степени побеждает цель объединения, не так ли?
Оливер

4
Комплектация уже работает таким образом. Если вы запускаете проект в режиме отладки, каждый файл CSS загружается индивидуально, однако при запуске в выпуске они объединяются и минимизируются в один. Код в блоке if идентичен тому, что отображается на странице автоматически в режиме отладки.
Чад Леви
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.