Не очищайте определенный файл при использовании Microsoft Web Optimization Framework
Я пытаюсь объединить множество .js файлов в один, используя Microsoft Web Optimization framework. Все работает, но внутри этих файлов у меня есть несколько, которые уже были минитизированы и угашены, и нет необходимости обрабатывать их снова.
Например, у меня есть файл recaptcha_ajax.js и он вызывает следующие ошибки при добавлении:
/* Minification failed. Returning unminified contents.
(715,29-36): run-time error JS1019: Can't have 'break' outside of loop: break t
(714,293-300): run-time error JS1019: Can't have 'break' outside of loop: break t
(678,210-217): run-time error JS1019: Can't have 'break' outside of loop: break t
(671,1367-1374): run-time error JS1019: Can't have 'break' outside of loop: break t
(665,280-287): run-time error JS1019: Can't have 'break' outside of loop: break t
*/
Я попытался взять recaptcha_ajax.js из пакета и ссылаться на него напрямую, но затем другие всплывающие окна - так что мне нужен этот файл внутри пакета в определенной позиции.
Мне просто нужно сказать - не уменьшайте и не угадывайте recaptcha_ajax.js - просто добавьте его в комплект.
Есть ли способ сделать это? Вот как я это вижу:
var b = new ScriptBundle("~/bundles/myjsbundle");
b.IncludeDirectory("~/ScriptsMine/", "*.js", true);
// some command like:
// b.DoNotMinifyOrUglify("~/ScriptsMine/recaptcha_ajax.js");
bundles.Add(b);
Ответы
Ответ 1
Связки преобразуют каждый файл с помощью коллекции IItemTransform
и конкатенации результата. Затем он преобразует результат, используя коллекцию IBundleTransform
.
По умолчанию пакет script минимизирует содержимое всего пакета, используя JsMinify
(который реализует IBundleTransform
).
Итак, чтобы предотвратить минимизацию некоторого файла, вы должны создать свой собственный IBundleBuilder
, который минимизирует файл пакета по файлу с помощью IItemTransform
.
public class CustomScriptBundle : Bundle
{
public CustomScriptBundle(string virtualPath)
: this(virtualPath, null)
{
}
public CustomScriptBundle(string virtualPath, string cdnPath)
: base(virtualPath, cdnPath, null)
{
this.ConcatenationToken = ";" + Environment.NewLine;
this.Builder = new CustomBundleBuilder();
}
}
public class CustomBundleBuilder : IBundleBuilder
{
internal static string ConvertToAppRelativePath(string appPath, string fullName)
{
return (string.IsNullOrEmpty(appPath) || !fullName.StartsWith(appPath, StringComparison.OrdinalIgnoreCase) ? fullName : fullName.Replace(appPath, "~/")).Replace('\\', '/');
}
public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
{
if (files == null)
return string.Empty;
if (context == null)
throw new ArgumentNullException("context");
if (bundle == null)
throw new ArgumentNullException("bundle");
StringBuilder stringBuilder = new StringBuilder();
foreach (BundleFile bundleFile in files)
{
bundleFile.Transforms.Add(new CustomJsMinify());
stringBuilder.Append(bundleFile.ApplyTransforms());
stringBuilder.Append(bundle.ConcatenationToken);
}
return stringBuilder.ToString();
}
}
public class CustomJsMinify : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath.EndsWith("min.js", StringComparison.OrdinalIgnoreCase))
{
return input;
}
Minifier minifier = new Minifier();
var codeSettings = new CodeSettings();
codeSettings.EvalTreatment = EvalTreatment.MakeImmediateSafe;
codeSettings.PreserveImportantComments = false;
string str = minifier.MinifyJavaScript(input, codeSettings);
if (minifier.ErrorList.Count > 0)
return "/* " + string.Concat(minifier.Errors) + " */";
return str;
}
}
Затем используйте CustomScriptBundle
вместо ScriptBundle
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new CustomScriptBundle("~/bundles/Sample").Include(
"~/Scripts/a.js",
"~/Scripts/b.js",
"~/Scripts/c.js"));
}
Если вы предоставите файл min.js
, он будет использоваться вместо его извлечения.
Ответ 2
Рамка оптимизации учитывает имена файлов.
Попробуйте переименовать ваш *.js файл в recaptcha_ajax.min.js. Если я прав, то он должен пропустить процесс uglify/minify.
Справочные данные: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
(прокрутите немного вниз, чтобы найти эту цитату:)
Предыдущий код создает новый пакет JavaScript, названный ~/bundles/jquery, который включает все соответствующие (это отладка или, но не .vsdoc) в папке Scripts, которые соответствуют wild card string "~/Scripts/jquery- {version}.js". Для ASP.NET MVC 4, это означает, что при конфигурации отладки файл jquery-1.7.1.js будет быть добавлен в комплект. В конфигурации выпуска, Добавится jquery-1.7.1.min.js. Последовательность объединения несколько общих соглашений, таких как:
- Выбор файла ".min" для выпуска, когда существуют "FileX.min.js" и "FileX.js".
- Выбор версии ".min" для отладки.
- Игнорирование файлов -vsdoc (таких как jquery-1.7.1-vsdoc.js), которые используются только IntelliSense.
Ответ 3
если вы добавляете файлы .js в ScriptManager, вы заметите, что сценарии загружаются в <form>
, а не в <head>
, поэтому вытаскивание из пакета будет загружать этот файл перед другими, что плохо если он зависит от других вещей в пакете
Вот пример библиотеки, которая должна быть добавлена в комплект в определенном порядке.
Это добавлено в App_Start/BundleConfig.vb
'############################################################
' This is a ScriptManager Resource Definition
' for use in a ScriptManager mapping
'############################################################
Dim ResourceDef as ScriptResourceDefinition = New ScriptResourceDefinition()
Dim ResourceName as String = "ColorBox"
'add the Resource Definition details
ResourceDef.Path = "~/Scripts/colorbox/jquery.colorbox-min.js"
ResourceDef.DebugPath = "~/Scripts/colorbox/jquery.colorbox.js"
ScriptManager.ScriptResourceMapping.AddDefinition(ResourceName, ResourceDef)
'############################################################
Обратите внимание на использование ResourceDef.Path
и ResourceDef.DebugPath
.
Какой файл будет включен, будет зависеть от того, что вы делаете публикацию Debug или Release
- Отладка: нет "углификации"
- Релиз: Total "uglification"
Это мой пакет ScriptManager, обратите внимание на размещение ColorBox, позиция означает много:
<asp:ScriptManager runat="server" >
<Scripts>
<asp:ScriptReference Name="jquery" />
<asp:ScriptReference Name="jquery.ui.combined" />
<asp:ScriptReference Name="ColorBox" />
<asp:ScriptReference Name="Infragistics" />
<asp:ScriptReference Name="MsAjaxBundle" />
<asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
<asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
<asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
<asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
<asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
<asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
<asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
<asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
<asp:ScriptReference Name="WebFormsBundle" />
</Scripts>
</asp:ScriptManager>