我在我们基于MVC的解决方案中包含了一个大的javascript应用程序。但是,该应用程序包含大量文件,因此我希望在其上启用捆绑和缩小。事实上,我想在所有第三方javascript和CSS文件上启用捆绑,同时保持我们自己开发的文件不受限制和非捆绑。当然,直到发布。
有一种方法可以全局启用优化:
public static void RegisterBundles(BundleCollection bundles)
{
Bundle ckScripts = new ScriptBundle("~/scripts/ckeditor")
.IncludeDirectory("~/Areas/CMS/Editor", "*.js", true);
bundles.Add(ckScripts);
BundleTable.EnableOptimizations = true;
}
但是,这发生在最高BundleTable
级别,可以对捆绑表中的所有捆绑包进行优化。
我需要这样的东西:
public static void RegisterBundles(BundleCollection bundles)
{
Bundle ckScripts = new ScriptBundle("~/scripts/ckeditor")
.IncludeDirectory("~/Areas/CMS/Editor", "*.js", true)
.EnableOptimizations();
bundles.Add(ckScripts);
}
这将有效地仅为该特定捆绑包启用优化。
我知道,目前还没有Bundle.EnableOptimizations()
方法并且创建了这样的事实,即优化发生在BundleTable级别,这本身就是设计的全局性,创建这样的方法,将证明非常困难。
所以,在这里我失去了想法在哪里研究。
问题:
据我所知,BundleTable是一个单身人士。这意味着只能有一个实例。我有一个创建另一个捆绑表的想法,但当我开始弄清楚如何让MVC使用它时迷路了。
另一个起点是编写自定义渲染器。一个模仿System.Web.Optimization.Scripts.Render()
行为的人,但我又迷失了它,试图弄清楚BundleTable在哪个状态下出现。
更新
似乎我可以使用HtmlHelper
创建新的 BundleContext 和 BundleResponse 。
public static IHtmlString RenderBundled<TSource>(this HtmlHelper<TSource> helper, string bundlePath)
{
// Find the bundle in question
var bundle = BundleTable.Bundles.FirstOrDefault(b => b.Path == bundlePath);
// No bundle found, return
if (bundle == null) return MvcHtmlString.Create(String.Empty);
// Add the bundle found into a new collection
BundleCollection coll = new BundleCollection {bundle};
// Create a new BundleContext
BundleContext ctx = new BundleContext(helper.ViewContext.HttpContext, coll, "~/bundles");
// Enable optimizations
ctx.EnableOptimizations = true;
// Create the response (this contains bundled & minified script/styles from bundle)
BundleResponse response = bundle.GenerateBundleResponse(ctx);
// Render the content based on ContentType
if (response.ContentType == "text/css")
return RenderStyle(response.Content);// returns <style>bundled content</style>
if (response.ContentType == "text/javascript")
return RenderScript(response.Content); // returns <script>bundled content</script>
// In any other case return "nothing"
return MvcHtmlString.Create(String.Empty);
}
这可能不是最好的方法。在每个页面请求上创建BundleContext
并将脚本/样式有效负载添加到页面输出而没有缓存功能的开销。但这是一个开始。我注意到的一件事是捆绑的内容实际上将缓存在HttpContext.Cache
中。所以,理论上我可以将bundle path
放入script src
或style href
,然后以某种方式处理来自服务器端的请求。