As a community, Reaction follows guidelines for code style and naming conventions for variables, methods and filenames. The guide also includes tips on working with libraries in Reaction, like React, MongoDB, lodash and more.
- Syntax and style conventions
- Naming conventions
- Working with packages
- JavaScript style recommendations
- Copy conventions
Our rules are similar to Airbnb JavaScript Style Guide and Meteor Code Style, standard template of ESLint rules, with a few custom Reaction-specific rules:
- Always double-quote strings
- Give methods space
- Add spaces around brackets
- 120 character line-length
imports should be listed in this order:- React npm packages (
React,prop-types) - Other npm packages
- Meteor core packages
- Meteor (Atmosphere) packages
- Local app files
- React npm packages (
Other Reaction-specific rules are checked using various linting libraries. Find all the rules in the code:
.eslintrc- ESLint checks JavaScript style, including ES2015, React and Babel..jsbeautifyrc- JS Beautifier automates code formatting.editorconfig- Editor Config standardizes file formatting
To see the rules in action, run eslint . from the command line or use ESLint code editor tools.
💡 ProTip! If you're using Atom, like the Core team, you can install all the necessary tools in one line: apm install editorconfig atom-beautify linter linter-eslint linter-markdown linter-jsonlint linter-docker
File and directory names should be hyphenated. Not all operating systems are case sensitive, so avoid having two files named the same with differing case.
Names of folders and files should be:
- Lowercased
- Alphanumeric characters
- Hyphenated to join more words
- Avoid
camelCase,undescore_casing - Files may use multiple
.as needed
Do
/ui-grid/
/example-payment-method/
/social/
/bootstrap.rtl.js
/index.jsDon't
/reactionpackagename/
/address_book/
/addressBook/
/settingsContainer.js
/addressBook.js
/address_book.jsNamespace package folders in this format: <functionality>-<package-name> or <organization-name>-<package-name>
/imports/plugins/custom/payments-authnet
/imports/plugins/included/connectors-shopify
/imports/plugins/custom/connectors-magento
/reaction-paypal/
/yourorg-your-package/If there are multiple files that provide functionality that is broken down across multiple files, these files should be grouped within a folder.
If the files are stand-alone and the name needs to represent functionality, you can use a hyphen for the separator.
Do
/container/settings.js
/container/settings.html
/container/ <more files>
// or
/settings-container.js
/settings-container.htmlDon't
/container/settings-containers.js
/container/settingsContainer.html
settingsContainer.jsVariable names should be:
- Meaningful. Avoid single-letter variables.
- Use
error, instead ofeorerr - Variables that contain a boolean value should use a
isThisTruestyle. - Variables that return arrays should be plural.
Publication names should:
- Use TitleCase
Working with variables:
- Use
constexcept when a variable is being reassigned. - Use string template notation,
${thisVariable} is trueover string concatenation
Naming methods:
- Methods names should use a verb/noun style when possible, e.g.
checkConfigurationoraddToCart. - When naming multiple methods acting on the same resource should follow this style, e.g.
cart/items/add,cart/items/remove - Methods that return a single value should be singular.
- Methods whose main purpose is to return a value should use the
getprefix, e.g.getShop.
Working with methods:
- Avoid ternary operators and one-line
ifstatements (except in React componenets) - Use parenthesis around all method arguments:
// do - use () around the method arguments
cartItems.find((item) => item.status === picked)
// don't
cartItems.find(item => item.status === picked)- When specifying a callback, always use the parenthesis to indicate the argument being accepted over the bare arrow-function form. This way, it's clear it's not another argument to the original function:
// do - explicitly use a () in the callback function
thisMethodTakesACallback(arg1, arg2, (result) => {
dostuff();
});
// don't
thisMethodTakesACallback(arg1, arg2, result => {
doStuff
});- When breaking arrow functions into multiple lines, use curly brackets and a
return:
// do - explicitly use a return
cartItems.find((item) => {
return item.status === status;
})
// don't
cartItems.find(
(item) => item.status === status
)- Be explicit in querying:
// do - explicitly state the key being queried
Products.findOne({ _id: "abc123" })
// don't
Products.findOne("abc123")Use native JavaScript over libraries like lodash and Underscore whenever there is a suitable replacement.
- Replace
_.map, withArray.prototype.map - Replace
_.reduce, withArray.prototype.reduce - Replace
_.filter, withArray.prototype.filter - Replace
_.isArray, withArray.isArray - Replace
_.extendwithObject.assign - Replace
_.findwithArray.prototype.find - Replace
_.keysand_.values, withObject.keysandObject.values - Replace
_.first,_.restand_.restParam, with destructuring syntax - Replace
_.uniq, with using aSet:[...new Set(cartItems.map((item) => item.product._id))] - Replace
pluckfrom Underscore with.map:
const people = [{name: "George"}, {name: "Katherine"}, {name: "Kip"}]
_.pluck(people, name) => people.map((person) => person.name)- Replace
_.each,_.forEach, withArray.prototype.forEachor loop over an object with:
sum = 0;
lastKey = undefined;
for (const [key, value] of Object.entries(foo)) {
sum += value;
lastKey = key;
}- Use
isRequiredfor validating PropTypes - Use the return shorthand with arrow functions in React components:
// do
const MyComponent = ({ title, content }) => (
<div>
<h1>{title}</h1>
<div>{content}/</div>
</div>
);
// don't
const MyComponent = ({ title, content }) => {
return (
<div>
<h1>{title}</h1>
<div>{content}/</div>
</div>
);
}- Use the return shorthand with arrow function when iterating over arrays in a component:
const MyThings = ({ things }) => (
<ul>
{things.map((thing) => <li>{thing}</li>)}
</ul>
);
// or
const MyThings = ({ things }) => (
<ul>
{things.map((thing) => (
<li>{thing}</li>
))}
</ul>
);When writing user interface copy for Reaction, use sentence casing. This includes copy for titles, buttons, alerts, form inputs, form placeholders and copy elsewhere used throughout the application.
Copy should be:
- Have the first letter capitalized.
- No other words should be capitalized.
- Example:
Your ordersinstead ofYour Orders
// do
<h3 class="panel-title">Your orders</h3>
<Components.Translation defaultValue="Payment method" i18nKey={"cartCompleted.paymentMethod"} />
// don't
<h3 class="panel-title">Your Orders</h3>
<Components.Translation defaultValue="Payment Method" i18nKey={"cartCompleted.paymentMethod"} />