Commits
Use the Angular convention of
type(scope): messagefor commit messages. In general, the scope should be the module filename (without extension). For example, adding tests for thesso.tsfile would betest(sso): short message here.You can use commitizen for an easy command-line prompt.
Why? A convention for commit messages makes it easier to generate changelogs and see at a glance the purpose of any given commit. The Angular convention is a popular and well-established style.
Git commits and GitHub PRs should be as small and independent as possible. Grouping unrelated changes into a single PR or commit should generally be avoided.
Why? Grouping makes it harder to revert a problem; other, desired changes have to also be rolled back or manually applied.
Why? Grouping muddles concerns, adding unnecessary complexity and weight. A large PR containing multiple unrelated features takes much longer to review and approve than many small PRs. Creating commits and PRs is effortless.
Files
Files should be saved as UTF-8 with Unix line endings.
Why? UTF-8 is the most compatible encoding across editors, browsers, and other clients.
Spaces should be used for indentation, usually at 2 spaces per indent.
Why? A convention needs to be set, and this is preferred by the majority of developers (both in the JavaScript team, and the Banno organization and community at large). Spaces also work/look better across a variety of environments.
File names should be in all lowercase, using hyphens to separate words. Periods are used for nested extensions (e.g.,
app.spec.js).Why? All-lowercase prevents issues when using them on filesystems that don’t strictly distinguish case (Windows, OSX). Hyphens are the preferred separator in URL paths, so use them in the filesystem too.
Javascript
Write Javascript using the Standard style.
Why? It’s easier to manage than a custom ESLint configuration, and provides a good set of rules.
Tips / Policies
Break code into as many small, reusable individual
lib/,util/,helper/functions as possible.Prefer immutability. Avoid
let / mutable variablesand preferconst. Also preferpure functionsthat only ever take input and return an object. Avoid object property mutation unless needed.Try to always use long, verbose,
WETcode that is not “cute” or “clever”. Try to prefer chains of.map(),.filter(),.find()wherever possible for readability purposes.Try to lean on TypeScript type checking as much as possible. Avoid
any. Consider run-time checking (TBD) for really tricky/nested/flexible interfaces like expansive API responses from 3rd party vendors or other team APIs.Try to put functions that are used throughout multiple repositories in
node-templateso that we can re-use them and keep one source of easily updatable truth.Try to make unit tests as un-brittle as possible, even at the expense of lots of “copy + pasting”/duplication. It will pay dividends down the road making sure tests aren’t super tightly coupled to the code in case it needs to change/expanded on.
Try to stick to existing conventions per-repo. We are not perfect across every repo being 100% cohesive and identical to one another. Some don’t have TypeScript, some don’t have
binci. Some useproxyquirefor unit tests. If you enter a repo that doesn’t have the latest and greatest pattern, try not to wildly refactor it to match the flavor of the month and instead stick to writing code that “blends in” given the style of the repo (within reason).Stick to consistent
import/exportpatterns. Sometimes we export verbosely (named interfaces + types + enums + functions per line). Sometimes we export glob style*.Avoid Promises and prefer async/await everywhere.
Prefer
importoverrequirewherever possible in TypeScript-enabled repos. Prefer ordered imports in the following order: external dependencies, Banno scoped external dependencies, then src/lib, src/helpers, etc. (local to the repo) dependencies.Try to avoid skipping whitespace to designate breaking up sections. The vision in your mind at the time of writing is not always clear to the next reader. One preferred pattern is to avoid whitespace where at all possible (except between imports + functions). Instead place an inline comment on why the next block is present and its relation to the previous block.
Try to define functions from top-to-bottom. Meaning, if you have a function A that calls function B, make sure they are defined in a readable + linear fashion. It is very confusing to be reading a function for the first time, see a reference to another function, and have to scroll down to figure out where that function is defined. This is actually a compiler error in some older languages like C I believe.
Try to lean on strong small, bitesize functions + variables that express intent with their naming instead of relying on comments. Try to avoid
results,object,stuff-like variable names.Prefix
v0controller names withv0-instead of putting them at the end to make A-Z sorting + visual distinction of unversioned (typically deprecated / legacy) controllers easier versus their newerv0counterparts.