Reputation: 1789
Ok so I have been using the C# bundling to minify and combine scripts and css.
But I'm not sure how to append a script to a bundle which has already been created.
I'm trying to append to the bundle because not all scripts are found in the same file, as I'm working with a nopcommerce solution in visual studio. So the scripts are added all over the solution.
Here is the bundle code:
bundles.Add(new ScriptBundle("~/Content/themes/base/js/scripts/footeroptimized").Include(
"~/Themes/MyTheme/Content/js/bootstrap.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.validate.unobtrusive.min.js",
"~/Scripts/public.common.min.js",
"~/Themes/MyTheme/Content/js/readmore.min.js"));
I thought maybe I could use the bundles .Add()
function but I get an error:
bundles.Add("~/Themes/MyTheme/Content/js/global.min.js"));
The error is: "Cannot convert from string to system.web.optimization.bundle"
I couldn't find anything explaining why im getting that error.
Also I have added the using statement for optimizations @using System.Web.Optimization;
Anyone know how to add to a bundle which has already been created.
UPDATE:
I have also tried the following but it doesn't work:
var footerScriptBundle = new ScriptBundle("~/Content/themes/base/js/scripts/footeroptimized");
footerScriptBundle.Include(
"~/Themes/MyTheme/Content/js/bootstrap.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.validate.unobtrusive.min.js",
"~/Scripts/public.common.min.js",
"~/Themes/MyTheme/Content/js/readmore.min.js");
footerScriptBundle.Include("~/Themes/MyTheme/Content/js/global.min.js");
Cheers
Upvotes: 0
Views: 728
Reputation: 167
Because I had lost the URL of this Question between my R&Ds thus I left a reply on the MSDN blog (so the txt below is not a copyright violation).
https://blogs.msdn.microsoft.com/rickandy/2012/08/14/adding-bundling-and-minification-to-web-forms/#comment-47175
The reason of including files in the MasterPage is rational to have common files in one place related to them but this may provide a solution for other purposes:
By the way, It doesn't have to be registered in the global.asax essentially. I love to have the url list of bundled files in the MasterPage (having related stuffs in one place) so I misused :) a static bool in the BundleConfig named "IsRegistered"? initialized as false then in the RegisterBundles chk it (if true return) else make it true and do the register. Now have 2 other methods in your BundleConfig as RenderJS and RenderCSS (they call the main Styles.Render and Scripts.Render) but before the render these methods call the RegisterBundles method (like a PreRender event) thus now derive 2 Controls in a namespace registered as TagPrefix the controls are JSBundle and CSSBundle accepting Src and Href and their setter add the paths to 2 other arrays in the BundleConfig (uniquely). Finally the RegisterBundles uses the arrays to include in the bundle. Hurray now I can add files from Master.cs or even in the master itself but only before the render time instead of Application_Start
Call this in the master :
private static bool IsRegistered = false;
//...
public static System.Web.IHtmlString RenderJS(params string[] paths) {
if (!IsRegistered)
RegisterBundles();
return Scripts.Render(paths);
}
and check the registration state in the RegisterBundles:
public static void RegisterBundles() {
if (IsRegistered)
return;
IsRegistered = true;
//...;
}
adding files uniquely :
private static string[] CSSPths
, JSPths;
public static void AddJS(params string[] pths) {
if (JSPths == null)
JSPths = new string[0];
JSPths = MyNameSpace.Arrays.Merge(JSPths, pths
.Select(elm => "~/" + elm.TrimStart('~', '/'))
.Except(JSPths).ToArray());
}
Edit :
Hah we can add files to the bundle from OnInit event of the UserControls (such as NavBar or menus)
Upvotes: 0
Reputation: 50211
The use case you've described is not appropriate for bundles. You cannot modify a bundle at run-time, and even if you could, it doesn't make sense to do so.
Think about it. You visit one page, and request and receive bundle abc.js
, which the browser caches. Then, you visit a different page which also asks for abc.js
, only you want the contents to be different. Except, the browser will not ask for the file and will reuse the old one because it has been cached. Bundles are for avoiding sending files that are always needed together across many pages.
If you truly need to bundle additional files, then you need to either put the different files into their own bundles and request two bundles on each page, or create one bundle for each different scenario, a bundle that contains all the base files plus the site-area-specific files.
However, if there is only one additional file needed and the file you're trying to add to the bundle is used on only a single page, then you're doing it wrong. That file doesn't belong in a bundle at all! Just serve it up like usual, with the normal <script>
or <link>
tag. Even if you have multiple files, if they're used on only one page, perhaps you could combine them into a single (unbundled) file. Or as suggested above, make a special bundle that is for just those few files, and include or don't include it as a second, separate bundle.
The extra overhead of the browser having to request two objects, a bundle and also a page-specific javascript or a second bundle, is not that big. You won't get very much value out of trying to build bundles this way, and doing so will be a headache of nightmare proportions. Don't do that.
Some day with HTTP 2.0, we might be able to forget about bundling, since it may be possible the browser can ask for many files with a single request, and then receive all the answers in a single response. At that point, minification would still be important, but we would completely abandon bundles since their benefit would be completely realized through the protocol itself. There still may be multiple requests, split along lines of where the request can be serviced from, so for example one request for all static content (images, videos, stylesheets, javascript, etc) that can be served from a CDN, and one request for all dynamic content.
Upvotes: 1