Tips on managing large amounts of code? - javascript

My project seems to be getting bigger and bigger and some of my classes are thousands of lines long. It's too hard to search through them every time I want to make changes.
I find JavaScript is not as easy to lay out cleanly as some other programming languages. So when the classes get to be a few thousand lines, I have troubles reading it.
I've tried splitting it into multiple files, but then you're breaking classes apart, which doesn't seem right. For example, if every method in a class uses a global variable, you would only be able to find the global variable in one of the files for that class.
Also, if I want to use the JavaScript code from 100 different .js files, I end up with something like this...
<script type="text/javascript" src="Scripts/classes/Node.js"></script>
<script type="text/javascript" src="Scripts/classes/Queue.js"></script>
<script type="text/javascript" src="Scripts/classes/DblyLinkedList.js"></script>
.... 97 more lines like this
Although, I figured there may be something where I can do...
<script type="text/javascript" src="Scripts/.../*.js"></script>
or something similar... is that right?
Anyone have any tips on managing code as it reaches its extremes?
Tips on cleaning up JavaScript code would also be helpful.

Breaking up JS into separate files has some major drawbacks, chiefly that you're forcing web browsers to make a separate request for each file.
Have you taken a look at leaving all of your files separated out, but making a single-file "bundle" for each project containing only the necessary files? This can be automated via a script.
This SitePoint article might help you get started: http://www.sitepoint.com/blogs/2007/04/10/faster-page-loads-bundle-your-css-and-javascript/

(a) keep your classes shorter [even
though that will mean yet more
files],
(b) keep them "full-text
indexed" for speed of search and
operation (not aware of any IDE
specifically supporting Javascript
this way, but strong editors like
Emacs, Vim, Eclipse, or TextMate sure
do),
(c) group them up hierarchically
so your pages can have just a few
<script> tags for "upper layer"
scripts each of which just pulls in
several of the "lower layer" ones.
Oh, and, of course, religiously keep everything under a good change control system (SVN, Mercurial, or the like), otherwise your life will be surely very very miserable:-(.

You might want to group related classes together into packages, where each package is a single file. Check out YSlow for best practices on performance.

Well, a good editor is always usefull, as it will give you shortcuts to all your functions defined in the files.
Second, make sure you're not looking at a wall of code. Indentation, spaces and newlines are a good help.
Be extremely strict in your indentation. 2 spaces is 2 spaces, always(or whatever amount you use)
if you put your { under a declaration, then always put it there, without exception)
Clear rules about how you want your text aligned will help a lot.
And I don't know about that last thing... I'm not sure browsers can work with that kind of wildcard.

<script type="text/javascript" src="Scripts/.../*.js"></script>
will not work, and besides, you end up with an interesting problem when splitting up dependent files, as you can't guarantee they will all be downloaded in the order you expected.
Unfortunately, your best bet is really a good IDE that can produce an outline for easy navigation. I use Eclipse with Spket and/or Aptana, but whatever makes it easier to manage is what you're looking for.
edit: one more quick note about splitting js into multiple files. Avoid it where possible. Each separate file means a separate http request. Reducing the number of requests required can make a massive difference in site performance.

AvatarKava's advice is sound. Work in separate files and concatenate them at build time. However, I would also recommend you take a look at your class structure. A class "thousands of lines long" doesn't sound too healthy. Are you sure you classes aren't taking on too much responsibility? Are there not tasks that can be shipped out to other single responsibility classes? This would help improve the clarity in your code far more than cunning ways of splitting files.

Same advice applies to most languages...
Avoid globals wherever possible. You can often get the desired behavior by wrapping a static variable, or using objects.
if (foo == undefined)
var foo
Use naming conventions where possible so you can track things down just by reading the variable or function names. Either that or get good with grep, or get an IDE with intellisense.
Split things into directories. Having 100 files in a directory called "classes" is not helpful. As an example, you may have a collections directory for queues, lists, trees, etc. If you've got a lot you may even have a tree subdir, or a list subdir, etc.
You can then also create a global include for that directory... simply a file called collections.js that includes all of the files in that directory. Of course you have to be careful about splitting things up well, since you don't want to be including files you'll never use.

Related

What are the arguments against the inclusion of server side scripting in JavaScript code blocks?

I've been arguing for some time against embedding server-side tags in JavaScript code, but was put on the spot today by a developer who seemed unconvinced
The code in question was a legacy ASP application, although this is largely unimportant as it could equally apply to ASP.NET or PHP (for example).
The example in question revolved around the use of a constant that they had defined in ServerSide code.
'VB
Const MY_CONST: MY_CONST = 1
If sMyVbVar = MY_CONST Then
'Do Something
End If
//JavaScript
if (sMyJsVar === "<%= MY_CONST%>"){
//DoSomething
}
My standard arguments against this are:
Script injection: The server-side tag could include code that can break the JavaScript code
Unit testing. Harder to isolate units of code for testing
Code Separation : We should keep web page technologies apart as much as possible.
The reason for doing this was so that the developer did not have to define the constant in two places. They reasoned that as it was a value that they controlled, that it wasn't subject to script injection. This reduced my justification for (1) to "We're trying to keep the standards simple, and defining exception cases would confuse people"
The unit testing and code separation arguments did not hold water either, as the page itself was a horrible amalgam of HTML, JavaScript, ASP.NET, CSS, XML....you name it, it was there. No code that was every going to be included in this page could possibly be unit tested.
So I found myself feeling like a bit of a pedant insisting that the code was changed, given the circumstances.
Are there any further arguments that might support my reasoning, or am I, in fact being a bit pedantic in this insistence?
Script injection: The server-side tag could include code that can break the JavaScript code
So write the code properly and make sure that values are correctly escaped when introduced into the JavaScript context. If your framework doesn't include a JavaScript "quoter" tool (hint: the JSON support is probably all you need), write one.
Unit testing. Harder to isolate units of code for testing
This is a good point, but if it's necessary for the server to drop things into the page for code to use, then it's necessary. I mean, there are times when this simply has to be done. A good way to do it is for the page to contain some sort of minimal block of data. Thus the server-munged JavaScript on the page really isn't "code" to be tested, it's just data. The real client code included from .js files can find the data and use it.
Thus, the page may contain:
<script>
(function(window) {
window['pageData'] = {
companyName: '<%= company.name %>',
// etc
};
})(this);
</script>
Now your nicely-encapsulated pure JavaScript code in ".js" files just has to check for window.pageData, and it's good to go.
Code Separation : We should keep web page technologies apart as much as possible.
Agreed, but it's simply a fact that sometimes server-side data needs to drive client-side behavior. To create hidden DOM nodes solely for the purpose of storing data and satisfying your rules is itself a pretty ugly practice.
Coding rules and aesthetics are Good Things. However, one should be pragmatic and take everything in perspective. It's important to remember that the context of such rules is not always a Perfect Divine Creation, and in the case of HTML, CSS, and JavaScript I think that fact is glaringly clear. In such an imperfect environment, hard-line rules can force you into unnecessary work and code that's actually harder to maintain.
edit — oh here's something else I just thought of; sort-of a compromise. A "trick" popularized (in part) by the jQuery gang with their "micro template" facility (apologies to the web genius who actually hit upon this first) is to use <script> tags that are sort-of "neutered":
<script id='pageData' type='text/plain'>
{
'companyName': '<%= company.name %>',
'accountType': '<%= user.primaryAccount.type %>',
// etc
}
</script>
Now the browser itself will not even execute that script - the "type" attribute isn't something it understands as being code, so it just ignores it. However, browsers do make the content of such scripts available, so your code can find the script by "id" value and then, via some safe JSON library or a native browser API if available, parse the notation and extract what it needs. The values still have to be properly quoted etc, but you're somewhat safer from XSS holes because it's being parsed as JSON and not as "live" full-blown JavaScript.
The reason for doing this was so that the developer did not have to define the constant in two places.
To me, this is a better argument than any argument you can make against it. It is the DRY principle. And it greatly enhances code maintainability.
Every style guide/rule taken to extreme leads to an anti-pattern. In this case your insistence of separation of technology breaks the DRY principle and can potentially make code harder to maintain. Even DRY itself if taken to extreme can lead to an anti-pattern: softcoding.
Code maintainability is a fine balance. Style guides are there to help maintain that balance. But you have to know when those very guides help and when they themselves become a problem.
Note that in the example you have given the code would not break syntax hilighting or parsing (even stackoverflow hilights it correctly) so the IDE argument would not work since the IDE can still parse that code correctly.
it simply gets unreadable. You have to take a closer look to divide the different languages. If JavaScript and the mixed-in language use the same variable names, things are getting even worse. This is especially hard for people that have to look at others people code.
Many IDEs have problems with syntax highlighting of heavily mixed documents, which can lead to the loss of Auto-Completion, proper Syntax Highlighting and so on.
It makes the code less re-usable. Think of a JavaScript function that does a common task, like echoing an array of things. If you separate the JavaScript-logic from the data it's iterating over, you can use the same function all over your application, and changes to this function have to be done only once. If the data it's iterating over is mixed with the JavaScript output loop you probably end up repeating the JavaScript code just because the mixed in language has an additional if-statement before each loop.

What software/webapp can I use to edit HTML pages?

Ok, my question's not as broad as it seems, to summarize 8 months effort on my part:
I create chunks of re-usable, extensible XHTML which degrades gracefully and is all kinds of awesome. Most of my code chunks are provided a Javascript interaction layer, and are styled with CSS. I set to work pulling my code chunks into Dreamweaver as 'Snippets' but they're unintelligent chunks of text. Also, once inserted, my beautiful code chunks get mangled by the non-techies who are the ones actually using Dreamweaver.
Also, because they're unintelligent snippets, I have a line of Javascript which configures the code chunks when initialised - see this post for further detail on my approach. But currently I have to replicate a single code chunk as many times as there are configuration options (so each 'snippet' may only differ from another of the same type by ONE config value). This is incredibly lame, it works, but its lame and time-consuming for me to re-deploy a bunch of snippets and hard for my team to remember all the variations.
So I have a series of requirements, to my mind, as the most likely things to solve in any system I put my chunks into:
The inserted code is not modified at insertion time, by the system
The code to be inserted needs to allow config options
I'd be overjoyed if, once inserted, the only editable parts are text nodes
Copy and pasting these whole objects
A clean interface from which to choose from my range of code chunks
It's a serious list of requirements I presume, much searching led me to Kompoze and its 'Smart widgets' which, according to a random post from 2004, suggests XUL files can be created and extensions can be made which sounds vaguely like what I want. The text editor itself was less prone to destruction, when compared to Dreamweaver.
So yeah, I've chased too many rabbits on this one, keen as for a solution whether Software+extension, or Webapp.
EDIT:
Btw, it did occur to me to investigate a highly customised TinyMCE instance, but I don't know feasible that is, and unless there's some sweet backend available, I'm stuck with local editing of files for now - not even on a web server...
To my mind the best answer to this question will solve most of the above, and provide some general workflow advice alongside the suggestion(s).
I would go with a solution based around the excellent markItUp! editor. It's very simple to extend it to cope with the requirements you have. You can add sophisticated logic, and it's nice and shiny.
I'd probably combine it with Jeditable for the inline node editing, and build the whole thing on top of Django, for ease and convenience. Completely customisable, surprisingly easy to work with, portable and cross-platform, and easy to set-up for off-line use. Oh, and all free and open-source.
What do you think of this approach:
<div class="thing">
<elements... />
<script type="text/javascript">
document.write('<span id="thing' + thingNo + '"></span>')
new Thing().init({ id:'thing'+thingNo; });
thingNo += 1;
</script>
</div>
Of course, you'll have to change Thing().init so that it would initialize the parent (instead of current) node.
Have you considered server-side includes where the directive is either a generated page or a shell command? E.g.:
<!--#include virtual="./activePage.aspx?withParam1=something&param2=somethingelse" -->
or
<!--#exec cmd="shellCommand -withParams" -->
You can reuse the same page or command, and provide parameters specific to each usage in each XHTML page.

Is it right to write multiple and separate <script > on a page?

While writing JavaScript code, I Separate each code block with <script> tags
<script type="text/javascript">
//---- code block 1---------
</script>
<script type="text/javascript">
----code block 2-----
</script>
<script type="text/javascript">
$(document).ready.(function(){
// code block3
});
</script>
I want to know that is it good practice to write separate <script type="text/javascript"></script> on the same page
--or--
We have to write all JavaScript code under one <script>
What are the technical differences in each way?
Well, you may want to ask yourself why your code organization scheme leads to that setup, and whether it causes maintenance or understandability problems, but I don't think it's strictly "bad". Now if your <script> tags are actually fetching separate files from the server, then it's a good idea to cut back on them.
The browser parses and interprets script tags in such a way that other work stops, so blocks of Javascript up at the top of your page can slow things down if they do a lot of work. That's true whether you've got a big block of code or several smaller blocks, however.
An advantage of moving to separate script files is that you can re-use code on multiple pages. When you do that, it may be easier at build time to compress your scripts with YUICompressor or some other similar tool.
The best reason to do this is if each script represents a discrete chunk of functionality which may not be used on (and therefore not vended to) every page. In that case, it becomes a smart strategy.
Having multiple <script> tags makes no real difference in performance but is less readable.
There is one edge case where multiple script blocks can make a difference (and I just learned about it). If one line of code references a value before it has been declared, this will work if the code belongs to the same script block, but not if they are separate. But this doesn't change the answer everybody gave you: it probably won't matter in everyday coding.
You don't have to, but its obviously cleaner that way, unless you want to clearly seperate the blocks of code.
Put all your javascript coding in separate and then call the file name. Because it is good thing. Coding execution is step by step, so it will take time if js present in between the coding.
Not nice, but not a problem.
Hunter is right, it makes absolutely no difference as far as performance is concerned.
When your javascript however becomes more complex, you may want to start building your own API of sorts and splitting out all of those tags into separate files. Then when you're deploying your app, find some sort of packaging solution that will combine all of those files to a single one, compress it using YUI compressor or Google Closure and have one single tag that references this file of all your code.
While it is a 'slight' disadvantage to force a separate http request for this file, if it's packaged properly, the file size will be smaller than the uncompressed code you've included in that file.
It is also normal to have script tags further down in your page that provide extra functionality (ie look at google analytics)
Whenever you are violating the DRY principle (Don't Repeat Yourself), you need to ask why. If you don't have a good reason, then you probably shouldn't be doing it that way.

How do you organize your Javascript code?

When I first started with Javascript, I usually just put whatever I needed into functions and called them when I needed them. That was then.
Now, as I am building more and more complex web applications with Javascript; taking advantage of its more responsive user interaction, I am realizing that I need to make my code more readable - not only by me, but anyone who replaces me. Besides that, I would like the reduce the moments of 'what the heck, why did I do this' when I read my own code months later (yes, I am being honest here, I do have what the heck was I thinking moments myself, although I try to avoid such cases)
A couple weeks ago, I got into Joose, and so far, it has been good, but I am wondering what the rest do to make their chunk their codes into meaningful segments and readable by the next programmer.
Besides making it readable, what are your steps in making your HTML separated from your code logic? Say you need to create dynamic table rows with data. Do you include that in your Javascript code, appending the td element to the string or do you do anything else. I am looking for real world solutions and ideas, not some theoretical ideas posed by some expert.
So, in case you didnt't understand the above, do you use OOP practices. If you don't what do you use?
For really JS-heavy applications, you should try to mimic Java.
Have as little JS in your HTML as possible (preferably - just the call to the bootstrap function)
Break the code into logical units, keep them all in separate files
Use a script to concatenate/minify the files into a single bundle which you will serve as part of your app
Use JS namespaces to avoid cluttering up the global namespace:
var myapp = {};
myapp.FirstClass = function() { ... };
myapp.FirstClass.prototype.method = function() { ... };
myapp.SecondClass = function() { ... };
Using all these techniques together will yield a very manageable project, even if you are not using any frameworks.
I use unobtrusive javascript, so, outside of the script tags I don't keep any javascript in the html.
The two are completely separated.
A javascript function will start when the DOM tree is completed, which will go through the html and add the javascript events, and whatever else needs to be changed.
In order to organize, I tend to have some javascript files that are named similar to the html pages that they use, and then for common functions I tend to group them by what they do, and pick a name that explains that.
So, for example, if I have UI functions then I may call them: myapp_ui_functions.js
I try to put the name of the application in the filename, unless there is some javascript that is common to several projects, such as strings.js.
I have (usually) one file that contains a bunch of functions and that's it. That is included in every page that uses Javascript. In the pages themselves, I'll make the calls to the functions like:
$(function() {
$("#delete").click(delete_user);
$("#new").click(new_user);
});
where delete_user() and new_user() are defined in the external file.
I too use unobtrusive Javascript, which for me means jQuery (there are other libraries that are unobtrusive).
You don't want a separate file for each page. That just means more unnecessary external HTTP requests. With one file—assuming you've cached it effectively—it'll be downloaded once and that's it (until it changes).
If I have a large amount of Javascript or the site is effectively split into multiple areas then I may split the Javascript but that's not often the case.
Also, in terms of my source code, I may have multiple JS files but I'll often end up combining them into one download for the client (to reduce HTTP requests).
More at Multiple javascript/css files: best practices? and Supercharging Javascript in PHP.
I've been rewriting a lot of my reusable code as jQuery plugins. I moved to jQuery from Prototype when I started doing ASP.NET MVC. Overtime I've migrated a lot my reusable code, or at least the ideas, from Prototype-based OO to jQuery-style plugins. Most of these are stored in their own JS files (mainly intranet apps so page load speed is pretty high anyway despite the extra requests). I suppose I could add a build step that coalesces these if I needed to.
I've also settled on a MasterPage approach that uses a ContentPlaceHolder for scripts that is right before the closing body tag. The standard jQuery/jQuery UI loads, and any other common JS goes right before the script placeholder in the MasterPage. I have tiny bit of JS at the top of the MasterPage that defines an array that holds any functions that partial views need to run on page load. These functions are run from the base document.ready() function in the MasterPage.
All of my JS is completely separate from my mark up. Some JS may exist in partial views -- these are encapsulated when the partial may be included more than once to make it specific to that instance of the view -- but generally not. Typically only included in the placeholders so that it's loaded at the bottom of the page.
Also, if you want to go OO heavy, check out mochikit: http://www.mochikit.com/
I find that developing your javascript using OO methodology is the way to go if you want it to be clean, readable and even somewhat secure. I posted the following question
Cleanest format for writing javascript objects
And got some fantastic responses on how to write my javascript code well. If you follow these basic principles you can use almost any library, such as yui, jquery and prototype, with ease.

Splitting code in to multiple files for easier management

I am currently using jQuery to write an online application, that started off with a couple of lines of code, and have quickly now become over a 1000 lines.
My code's structure is simple. I have a window.load which wraps my javascript, and inside it I start adding my click event handlers, and the various functions that makeup my application.
$(window).load(function(){
// Code goes here...
});
My code functions can definitely be grouped into categories; e.g. 5 functions perform animation, 12 are event handlers, etc.
I would like to group the functions in their own js files, and import them individually. I can later use my CMS engine to concatenate and compress the files on the fly.
What is the best way in doing so. I am thinking that maybe I can give some of my functions their own namespace for further clarity; e.g. all animation functions are prefixed with ANIMATION - ANIMATION.moveDiv1(), ANIMATION.moveDiv2, MYEVENT.div1Clicked, etc.
I generally stick all related items into their own file, with a namespace that matches the file for readability sake.
An example file could look like:
Example.js
var Animation = {}; // create the namespace-like object
Animation.moveDiv1 = function() {...};
Animation.moveDiv2 = function() {...};
There's really a lot of ways to do this. Speaking of compression, there are some nice tools that you can use to compress things. Check out YUI Compressor
Modularity is a good goal with Javascript, but I would say the next level would be to actually use some Javascript OO techniques. If your app is simple enough, you can probably do without it though.
Your code files should mirror your classes.
Your classes should follow principles of good OO design.
In terms of load-time within the browser, kekoav and knut have the right idea - just use YUI or another script compressor/minifier (and optionally an obfuscator), combine them into a single file and load them all from a single script include directive.
I'd also have a look at JS the prototype property of your classes - if they're getting large and you're creating multiple instances of them, you'll start to see significant performance gains by putting your public (and optionally, private/privileged) methods into the class prototype.
You should definitely be using fully-qualified namespaces for your classes, either using Microsoft's Type.registerNamespace if you're using their AJAX solution, by declaring your own namespace functions as per kekoav's post, or using a squillion other similar approaches that Google will offer.
Good idea from a standpoint of application management, bad idea from the standpoint of loading time. The browser has to load all those little scripts synchronously, therefore taking more time for each additional script you want to load. That's not including the main jQuery library script, the jQuery UI and whatever else you plan on having in your document. Test both premises: abstracting functions out into their own individual scripts and load them vs. one big script that only requires one call to load. Take it a step further and minify the "one big script", one more step and make sure it's served as a compressed file.
You may split the JavaScript files into classes when you are developing, but you should combine your scripts, and minimize them in a production environment. Please take a look at YUI Compressor for more information.

Categories

Resources