Составьте пакет 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"));