Node.js Development Guide
This document is structured by topic; under each, we include “Standards”, “Defaults”, and “Suggestions”.
Standards are practices that have a strong consensus across 18F; they should generally be followed to ease the ATO process and make on-boarding simpler.
Defaults are safe selections that tend to be used by a large number of our projects; you may find yourself with a better or more tailored solution, however.
Suggestions contain examples that have worked well on a project or two; they’re not widely used enough to be defaults, but are worth considering.
Node.js supports certain versions as Long-term Support (LTS) versions. We have standardized to using the current active LTS version, currently v8.x.
ECMAScript. Modern browsers
support ES5, but when writing code on the server, you don’t have to write
browser-compatible code. With
--harmony, Node.js supports many ES6 and ES7
features. Similarly, on both the front end and back end,
you can use webpack, browserify, babel, etc. to transpile your code. This
allows you to fill in the feature gaps that are not yet supported by Node.js.
This also means your browser code and server code use the same ECMAScript
features. Given these capabilities, we recommend defaulting to using a
transpiler and targeting the same ES version for back end and front end code.
Be sure to always polyfill missing features in the browser. We suggest
using ES6 as your source language.
For libraries, our standard practice is to use the latest release when first installing. Security updates (as indicated by GitHub or Snyk) should be applied ASAP, but all libs should be updated at some routine interval (e.g. quarterly).
Finally, in an effort to ensure our deployments are repeatable, our code standards require all dependencies (including dependencies’ dependencies) be pinned to specific versions. This should also apply to the development environment (e.g. linters, testing tools, etc.) Suggestions for implementing that include
- npm’s package-lock.json (npm >= 5)
- npm’s npm-shrinkwrap.json (npm < 5)
- yarn’s yarn.lock
- vendoring dependencies (though this is only a partial solution)
Frameworks provide a common baseline for your application. ATO requires configurations that most frameworks provide out of the box, or make it very easy to enable. Here, we document a few common use cases and the libraries we recommend when trying to solve them.
|Test Spies, Stubs, etc.||Sinon||Default|
Scaffolding your application
Scaffolding tools can help take care of some of boilerplate of initializing a project. Some scaffolds are generator tools, others are kits intended to be forked. There are many available on GitHub. You might also choose one based on the front end frameworks you want to use and then add the server-side pieces yourself. You also don’t have to use one at all. That said, don’t spend too much time finding the perfect generator. Once your application has been scaffolded, you’re not going to scaffold it again.
We suggest using one of the following scaffolds:
Static typing can both make code authors’ intent clearer and reduce the number of bugs through static analysis. It’s also notorious for slowing down the pace of prototyping and requiring a great deal of boiler-plate. A significant number of 18F projects are using TypeScript to add static typing, while a handful are testing out Flow.
At this time, we suggest considering a static type-checker, and using TypeScript if it’d aid your project’s workflow.