One of the most important things I have found is writing your module outside of your application, this ensures a couple of things:
- Your tests are completely isolated
- Adding a dependency to your module is a pain!
- Your module can be easily re-used, just drag and drop it into another app
One of the most important things to take from this is coupling to a dependency is hard, it really forces you to think if that dependency is necessary and you will end up with code that has very loose coupling, which is always a good thing!
To demonstrate how easy it is to move your code to another application, this source code I put together for this app was already in an app I was developing last week. It took all of about 5 minutes to piece together the sample code.
The sample code is available on GitHub. If you are running this code you will need to set up a server in the root directory to make sure all of the assets are loaded in. I was lazy and just useds PHP 5.4's built in server:
$ php -S localhost:8000
Inside the root
js folder we have a modules directory and one extremely small module
action-dialog. Keeping all of your modules files: Views, Models, Collections and assets separate really makes things reusable. It will also help in a large team and help avoid people changing the same code at the same time.
With this modular approach, each module should have their own tests, take a look at the
For running the tests I have been using one
tests.html file in the root of the application. For me this approach just minimises the code taken to get a test runner up and going. With mocha it is really easy to still drill down and just view the tests for one particular module during development, just click on the Action Dialog View heading and mocha will only run that spec.
I agree with TJ in his components article that each module should have it's own CSS and images, he adds that the CSS should only be structural CSS for layout, and not delve into typography or colour at all. Your applications independent CSS in
css/layout.css should be like a theme that covers all of those reusable style attributes.
Also images and html should all be self contained in the module, currently I load in the HTML with the requirejs text plugin and compile it into a template using Handlebars. Images can easily be placed into the modules CSS and then loaded into the core application that way, or referenced via the modules HTML templates.
So for my applications I have several core libraries that I always make use of:
In this example and in the applications I am building currently, these core libraries sit in
/js/libs and are shared between all of the modules. This does go a little against the modules being completely standalone, but it would be simple enough for a module to have its own libs folder and manage its own library dependencies. If a new team member comes on board and doesn't like using mochas BDD style specs they could certainly write their own Qunit tests for their module and have it run those independently of the rest of the app.
To simplify loading the modules into the app, each module has its own
main.js file in the root of that module. This is just a convention for that module to export whatever public API is needed to run.
Each module should have its own readme file that explains how it can be used and go into detail on its public API and events.
A build script using grunt or similar could solve this problem and over the next month or two I'm sure I will either find an excellent tool for this job, or try to write one.
I am going to continue with this approach of building micro applications and glueing them together to form a large application. I have been very impressed so far by this approach, and for me it has made my code extremely lean.