Составьте пакет script, включите еще один пакет script
Предположим, что у меня установлены эти два пакета script:
bundles.Add(new ScriptBundle("~/Scripts/Bootstrap").Include(
"~/Content/Scripts/jQuery/jquery-2.1.1.js",
"~/Content/Scripts/Bootstrap/bootstrap.js"));
bundles.Add(new ScriptBundle("~/Scripts/jQuery").Include(
"~/Content/Scripts/jQuery/jquery-2.1.1.js"));
Как вы можете видеть, ~/Scripts/Boostrap
использует jQuery JavaScript файл и Bootstrap. Это связано с тем, что для Bootstrap требуется работа jQuery.
С другой стороны, ~/Scripts/jQuery
состоит только из файла jQuery.
Я хочу иметь два пакета в случае, если для представления нужен только jQuery, а не Bootstrap.
Однако я копирую код здесь, я определяю путь к файлу JavaScript jQuery дважды.
Есть ли способ рассказать пакет ~/Scripts/Boostrap
для использования или "впрыска" другого пакета?
Что-то вроде этого:
bundles.Add(new ScriptBundle("~/Scripts/Bootstrap").UseBundle("~/Scripts/jQuery").Include(
"~/Content/Scripts/Bootstrap/bootstrap.js"));
Ответы
Ответ 1
Составьте пакет script, содержащий еще один пакет script
Нельзя напрямую использовать класс Bundling.
Скажем, в вашем сценарии, что бизнес решает отправить только один пакет клиенту для каждого запроса. Вы решили собрать все сценарии, необходимые для каждого контроллера (в этом волшебном мире). Вы можете начать с чего-то вроде этого:
bundles.Add(new ScriptBundle("~/Scripts/Home")
.Include("~/Content/Scripts/jQuery/jquery-2.1.1.js",
"~/Content/Scripts/Bootstrap/bootstrap.js"
"~/Content/Scripts/Home.js"));
bundles.Add(new ScriptBundle("~/Scripts/Account")
.Include("~/Content/Scripts/jQuery/jquery-2.1.1.js",
"~/Content/Scripts/Bootstrap/bootstrap.js"
"~/Content/Scripts/Account.js"));
Тогда, понимая, что .Include(string []) просто берет массив строки, вы можете DRY ваш код во что-то вроде:
var commonScripts = new List<string>()
{
"~/Content/Scripts/jQuery/jquery-2.1.1.js",
"~/Content/Scripts/Bootstrap/bootstrap.js"
};
var homeScripts = new List<string>()
{
"~/Content/Scripts/Home.js"
};
bundles.Add(new ScriptBundle("~/bundles/home/")
.Include(commonScripts.Concat(homeScripts).ToArray()));
var accountScripts = new List<string>()
{
"~/Content/Scripts/Account.js"
};
bundles.Add(new ScriptBundle("~/bundles/account/")
.Include(commonScripts.Concat(accountScripts).ToArray()));
Я не рекомендую бизнес-причины этого решения, но я думаю, что логика, которая его решает, может быть использована аналогично для решения вашей проблемы.
Если вы думаете, что у вас есть дубликаты, вы также можете:
.Include(commonScripts.Concat(accountScripts)
.Distinct()
.ToArray()));
Лично я бы не включил jQuery или BootStrap в пакеты, поскольку они доступны из многих CDN онлайн бесплатно; A означает, что я использую меньше своей пропускной способности, а B клиент, возможно, уже загрузил нужные мне сценарии (причины CDN существуют для обычных скриптов/стилей).
Ответ 2
Вы также можете подумать о создании класса оболочки ComposableBundle
, который позволяет создавать пакеты с синтаксисом .UseBundle(someBundle)
.
Например, следующие методы класса и расширений:
public class ComposableBundle<T> where T : Bundle
{
private T _bundle;
private List<string> _virtualPaths = new List<string>();
public ComposableBundle(T bundle)
{
_bundle = bundle;
}
public string[] VirtualPaths
{
get { return _virtualPaths.ToArray(); }
}
public T Bundle
{
get { return _bundle; }
}
public ComposableBundle<T> Include(params string[] virtualPaths)
{
_virtualPaths.AddRange(virtualPaths);
_bundle.Include(virtualPaths);
return this;
}
public ComposableBundle<T> UseBundle(ComposableBundle<T> bundle)
{
_bundle.Include(bundle.VirtualPaths.ToArray());
return this;
}
}
public static class BundleExtensions
{
public static ComposableBundle<T> AsComposable<T>(this T bundle) where T : Bundle
{
return new ComposableBundle<T>(bundle);
}
public static ComposableBundle<T> Add<T>(this BundleCollection bundles, ComposableBundle<T> bundle) where T: Bundle
{
bundles.Add(bundle.Bundle);
return bundle;
}
}
Позволит вам сконфигурировать ваши пакеты следующим образом:
var jQueryBundle = bundles.Add(new ScriptBundle("~/bundles/jquery").AsComposable()
.Include("~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryui").AsComposable()
.UseBundle(jQueryBundle)
.Include("~/Scripts/jquery-ui-{version}.js"));