使脚本包包含另一个脚本包

Mat*_*ero 21 c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

假设我配置了这两个脚本包:

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"));
Run Code Online (Sandbox Code Playgroud)

如您所见,~/Scripts/Boostrap使用jQuery JavaScript文件和Bootstrap文件.这是因为Bootstrap需要jQuery才能工作.

另一方面,~/Scripts/jQuery仅由jQuery文件组成.

我希望有两个捆绑包,以防视图只需要jQuery而不是Bootstrap.

但是,我在这里复制代码,我定义了两次 jQuery JavaScript文件路径.

有没有办法告诉~/Scripts/Boostrap捆绑使用或"注入"另一个捆绑?

像这样的东西:

bundles.Add(new ScriptBundle("~/Scripts/Bootstrap").UseBundle("~/Scripts/jQuery").Include(
        "~/Content/Scripts/Bootstrap/bootstrap.js"));
Run Code Online (Sandbox Code Playgroud)

Eri*_*ips 11

使脚本包包含另一个脚本包

不直接使用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"));
Run Code Online (Sandbox Code Playgroud)

然后意识到.INCLUDE(字符串[]),只是需要一个字符串数组,你可以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()));
Run Code Online (Sandbox Code Playgroud)

我不推荐这个解决方案背后的商业原因,但我认为解决它的逻辑可以类似地用于解决您的问题.

如果您认为您可能有重复项,您还可以:

                .Include(commonScripts.Concat(accountScripts)
                                      .Distinct()
                                      .ToArray()));
Run Code Online (Sandbox Code Playgroud)

就个人而言,我不会在捆绑包中包含jQuery或BootStrap,因为它们可以免费在线获得许多CDN; 一种方法我使用的带宽较少,而客户端可能已经下载了我需要的脚本(无论如何,CDN存在于常见脚本/样式的原因).


Dan*_*.G. 10

您还可以考虑创建一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

允许您像这样配置您的包:

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"));
Run Code Online (Sandbox Code Playgroud)