I am using a ASP.NET route (to intercept the call to the .js) and controller to generate some JS I want to use on my client. The reason I'm doing this is so as to not have to duplicate id's or constants on the client. Here's the output of my JS:
app.serviceRootURL = 'http://localhost:65211/'; // set in my web.config
app.ajaxResponseStatuses = [
{ "status":"Success", "id":0 }, // set in my C# DTO
{ "status":"Failure", "id":1 },
];
First of all, I am not sure if this is the best approach, so other suggestions to doing this would be beneficial.
More importantly though, I'm wondering how I can bundle and minify this. As I understand it, even if I could minify the JS at compile or run-time, minification will change the names of my variables. So in the above JS, app.ajaxResponseStatuses
could get changed to a.bc
, and then in the actual JS files where I'm trying to access that variable, they could be looking for x.yz
.
If you are generating the js at runtime, bundling isn't possible (at least not efficiently). You would have to create a new bundle for every request which isn't terribly quick. Plus, you wouldn't be able to cache the regular, constant script bundle.
EDIT: While bundling server-generated js isn't practical, rendering the values into a script tag in the page can achieve the same benefit of bundling, fewer HTTP calls. See the edit in Part 3 for more.
Minifying the server generated js however, is totally possible. This question should have the answer you're looking for. However, I'd recommend you cache this on the server if possible, as the minification process itself could take longer than simply sending down the extra bits.
In most minifiers, global variables (those accessible on the window
object) are skipped during the name mangling. With the same respect, variables that are accessed in other files that are not defined within that file are not renamed.
For example, if you have the following file...
// outside of a closure, so globally accessible
var foo = 1;
function bar() {
// within a closure, and defined with `var`, not globally accessible
var bar;
// reference to variable declared in another file
baz = null;
}
it would be minified as follows (with whitespace included for readability
var foo = 1;
function bar() {
var b;
baz = null;
}
This is one reason it is important to always declare your variables using the var
keyword, otherwise they are assumed to be references to global variables and will not be minified.
Also, JSON (not Javascript object literals!!!) will never be distorted by minifiers, because it consists of string literals for all keys, and all values that aren't of another literal type.
Not a bad way, and at my job we do use this approach. For small files though, or simple config values, we have transitioned to rendering server values in a script tag using ASP.NET in the actual view. i.e.
Default.aspx
<script> window.globals = <%= JsonConvert.SerializeObject(new AppGlobals(currentUser)) %>; </script>
We rip this out into a code behind, but the premise is the same.
EDIT:
Pros
Cons
Use when:
Your generated files are large, but rarely change or are the same for multiple users. These scripts can be treated the same as other static assets. To give an example, we serve a js file containing all the text in our app for localization purposes. We can serve a different js file based on the language set in the user's settings, but these values only change once at most with every release, so we can set aggressive cache headers and use a hash in the uri, along with a query string for the locale, to leverage browser caching and download each language file only once per client. Plus, if this file is going to be the same for every user accessing the same uri, you can cache it at the web server (IIS, Apache, etc.).
Ex: /api/language.v1-0-0.js?locale=en
Your js is independent from the rest of your app and not having it won't delay rendering. In this case, you can add the async
attribute to your script tag, and this file will be downloaded asynchronously and executed when it is received without preventing the execution of other javascript.
script
tag)Pros
Cons
Use when:
Don't waste too much time worrying about it. The differences in these two approaches is almost always negligible. If it becomes a problem, try both and use the better option for your case.