The GoCardless AngularJS Style Guide
We've used AngularJS since March 2013, and have blogged before about why we chose it and how we use it.
Since then a lot has changed: our team is 2x as large, we have 4x as much AngularJS to maintain, and we recently kicked off a major new project. To help keep our code consistent we've written and open-sourced a style guide.
The document is valuable as a reference and we hope you find it useful. For us, the process of writing it was equally as valuable, so we encourage you to write your own too. While writing ours, developers who have written AngularJS at GoCardless for a long time reconsidered why they do things the way they do, and new developers quickly learnt both how AngularJS works at a low-level and how it’s written at GoCardless.
TL;DR - AngularJS style at GoCardless
This style guide addresses four areas: High-level Goals; Directory and File Structure; Parts of AngularJS; and General Patterns and Anti-patterns.
Our high-level goals guide low-level decisions. As a company one of our values is "Build to Last". As engineers we want our code to add long-term value. But you rarely get it right the first time, so the best you can do is make future change easy.
We would, for example, pick verbose over DRY if that results in code that’s easier to read and change. We have found that inheritance and mixins make change especially hard. The code is neat when first written, but as it changes your classes end up knowing and doing too much, and your code becomes complex through layers of indirection. Composable service objects fit well with AngularJS dependency injection and make logic easier to track down.
We plan to write a lot more AngularJS code going forward. In AngularJS 2.0, the biggest change will be to the module system, moving from a custom one to ES6 modules. In preparation for this we have adopted ES6 modules on top of the current module system. Having two module syntaxes is verbose, but will make the migration to AngularJS 2.0 easier.
Directory and File Structure
Our directory and file structure is designed for non-trivial web applications rather than specifically for AngularJS. This fits well with the plans for AngularJS 2.0, where all core parts are composable, dependency injection sits on ES6 modules, and directives become sugar on top of Web Components.
Each module of functionality, whether component, route, or service, is kept in its own directory. For example, a route module would include the route config, controller, template, and tests. Updating a route usually means updating the controller, template and tests at the same time. This makes refactoring easier as the likelihood of forgetting to update a part of a component is reduced, and those components without tests are revealed.
Parts of AngularJS; General Patterns and Anti-patterns
Instead of rewriting well-documented best practices, the remainder of the style guide focuses on patterns and anti-patterns we found particularly good or bad. First for each part of AngularJS, then application-wide.
The style guide is a living document. We will change it as and when the way we write AngularJS changes. In the meantime, we hope you find it useful and look forward your feedback.