Today I'd like to share a simple but very useful practice for managing Ruby and JS code under version control.
In our team, we always use trailing commas when defining multi-line literals for arrays and hash (object in JS) literals.
It's great that both Ruby and JS allow this in their syntax, because as a result we are able to get cleaner diffs:
Notice how the same code change results in a drastically simpler diff: adding or removing an item changes a single line, nothing more.
Other Benefits 👩💻👨💻
Reordering lines, or sorting them alphabetically with the help of an editor (like Sublime Text), will always result in valid code, without the need to manually add the missing comma to avoid a syntax error.
Also, conflicts in source control are less likely to happen, since each line change becomes independent, unlike the usual approach where we are actually removing the last line without a comma to add two lines.
Finally, tools like git blame
are more likely to display relevant commit
information, rather than the commit that added the comma.
Automation 🤖
To make this practice effortless, we have modified the configuration of the static analysis tools (Rubocop and ESLint), to require trailing commas in multi-line literals.
We have also set up Guard
to listen for file changes and automatically run
the tools with --autofix
, so that commas are automatically added when we
forget; we don't really need to think about it.
In ESLint for JS:
"comma-dangle": ["error", "always-multiline"],
In Rubocop for Ruby:
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: comma
An example Guardfile
configuration:
# Run Rubocop every time we change a file, and autofix it if possible.
guard :rubocop, all_on_start: false, cli: ['-a'] do
...
Summary
Using trailing commas in multi-line literals results in code that is syntactically more stable to changes, and keeps a cleaner history in source control.
Developers make less syntax errors, since they can add and remove items, sort or reorder them, without having to manage missing (or extra) trailing commas.
We've been using this approach for years now, and haven't run into any issues in practice. It's been great so far 😃