I won’t be lying to you that stuff came to be an abomination. It was relatively simple stuff. We needed some dialog with a searchable tree inside it and some extra features I don’t really remember. Well I worked, sweat and delivered. The result was your typical thousand lines long unmaintainable ball of spaghetti covered in mud and crap. But it worked so that was nice.
Since then I spent a lot of time figuring out how to do JS properly. I even gave a presentation about it which pretty much shared the characteristics of my first JS project. I’m not a talker guy and it showed. Anyway I learned a lot by myself and had even better guidance from people vastly more knowledgable than me. So I present some action items to you so you don’t have to learn them the hard way.
Step 1 – Modularize
This is perhaps the most important thing. If you ever attempt to write maintainable JS code you need to split your stuff into smaller files. Don’t write all your code into a single file. Also don’t mix HTML and JS in one file, use references.
You should also keep your files short. One hundred lines should be enough for most use cases. You can even use a JS dependency manager, like RequireJS.
There is also a host of patterns on JS modularisation. I’d point out to the Asynchronous Module Definition or if you wouldn’t want it to formal, just using the Revealing Module Pattern.
Step 2 – Test
There are volumes of literature written about testing – especially unit testing – code. JS given its dynamic nature provides enormous flexibility – and the same breadth of errors. Since there’s no compilation with type checking you can easily invoke function which doesn’t exist causing a runtime error.
This is my favourite kind of error I use to make – writing the function
getParameterByName and then trying to invoke
getParamByKey in other places. Tests are great to catch this. And also a lot of other errors.
And be sure to actually run those tests. There are great unit testing tools in JS like Karma, a test runner, Jasmine or QUnit, unit testing frameworks. There’s also the great browser PhantomJS which is written for JS testing and automation.
Step 3 – Analyse your code
There are numerous best practices and anti patterns in JS accumulated over the years. Some of these can be validated by other code, called a static analyser. Do yourself a favour and use one. I’d recommend JSHint for this purpose. It’s pretty strict by default, but you can obviously fine-tune its behaviour.
Basically all it does is that it goes over your code and checks if you do something in a less than ideal way. Like not declaring variables or using undefined functions by mistake.
Step 4 – Use a package manager
Much has been written in JS and much is being written in this very moment as well. Sure you can write it better but you don’t have to. You should be focusing on providing value for whoever you write that code for.
So use what is already there if it fits. To do that, you can use Bower, a package manager for client-side JS. The usage is easy, you just type
bower install this_awesome_package and Bower takes care of resolving and storing the files.
You just need to push the configuration file to source control, so that others can download the same packages with Bower, without requiring to keep lots of third party code in your repository.
Step 5 – Use a task runner
You don’t want to do all common tasks by hand (unit testing, running JSHint, minifying your code, etc). Everybody hates these recurring and menial tasks, so let your machine do them for you.
Get Grunt, a task runner for JS. You’ll find tons on predefined tasks (like running your Jasmine tests with Karma on a PhantomJS browser outputting coverage data) and you save precious time where you can create value instead of getting frustrated with your toolset.
Step 6 – Use source control
Seriously this shouldn’t even be a step. Setting up a git repo is super simple, so you should have one. And if you don’t like git there are tons of other alternatives, most of them free.
Step 7 – Have a build process
This is obviously more advanced stuff, but a proper build process is a must have when there are other people working on your codebase. I would argue that even if you’re just by yourself you would benefit from running a build every time you commit code.
Your build process should validate your JS code (a la JSHint), run your tests and publish the result to some place where you can check it for yourself.