# JavaScript Guidelines **In this document** - [General Guidelines](#general-guidlines) - [Style Guide](#style-guid) ## General Guidelines In order to improve the clarity, quality, and development time it is worth considering the following principles whenever possible: - [DRY (Don't Repeat Yourself)](https://en.wikipedia.org/wiki/Don't_repeat_yourself) - [KISS (Keep It Simple, Stupid)](https://en.wikipedia.org/wiki/KISS_principle) - [SoC (Separation of Concerns)](https://en.wikipedia.org/wiki/Separation_of_concerns) - [Single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle) - [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter) --- ## Style Guide - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript/blob/master/README.md) is partially being followed in our code base. - Most styling issues will be caught by ESLint, so before pushing your changes remember to run `grunt eslint` to catch and fix any issues that it finds. - Check below for the rules that are not caught by ESLint but should be followed. ### Naming Conventions **[Variables:](#naming-conventions-variables)** Variables should be lowercase words separated by `_`. ```js const field_name = '...'; ``` **[Functions:](#naming-conventions-functions)** Functions should be camelCase. This is to easily distinguish between variables and functions. ```js const myFunction = () => { ... }; ``` **[Modules:](#naming-conventions-modules)** Module names and classes should be PascalCase. ```js const MyModule = (() => { ... })(); ``` **[jQuery variables:](#naming-conventions-jquery-variables)** jQuery variables should have a `$` in the beginning to mark them. ```js const $test = $('#test'); ``` **[JavaScript elements:](#naming-conventions-javascript-elements)** JavaScript elements start with `el_` for a similar effect. ```js const el_test = document.getElementById('test'); ``` **[Boolean:](#naming-conventions-boolean)** Those variables which store a boolean value, should start with `is_`, `has_`, ... ```js const is_updated = true; const has_crypto = false; ``` **[Form elements:](#naming-conventions-form-elements)** Consider prefixes for form elements to make it more obvious what type of field they are, such as: ```js const fields = { txt_name: { id: '#txt_name' }, chk_tnc: { id: '#chk_tnc' }, ddl_agents: { id: '#ddl_agents' }, }; ``` --- ### Commenting **[Explanations:](#commenting-explanations)** Feel free to add comments to explain any code that is confusing. **[To do:](#commenting-todo)** Use `TODO: ...` comments anywhere that needs consideration or attention in the future. **[API requests:](#commenting-api-requests)** Comments should be added to highlight logic that is hardcoded in the front-end and should move to API: - For changes that can be done in API V3, use the comment ```js // API_V3: [description of what needs to be moved to API] ``` - For changes that should be done in API V4, use the comment ```js // API_V4: [description of what needs to be moved to API] ``` --- ### Import Rules **[Require:](#import-rules-require)** Use `require` instead of `import` to stay consistent with the current codebase. We could change it to `import` when switching to React. **[Align by equal:](#import-rules-align-by-equal)** Assignments are generally aligned by `=` for readability purposes. ```js const moment = require('moment'); // moment is an npm package const CookieStorage = require('./storage').CookieStorage; // our own function const applyToAllElements = require('./utility').applyToAllElements; // our own function const createElement = require('./utility').createElement; // our own function require('../../_common/lib/polyfills/array.includes'); // polyfill from lib folder require('../../_common/lib/polyfills/string.includes'); // polyfill from lib folder ``` **[Alphabetical ordering:](#import-rules-alphabetical-ordering)** The order is important; it should be sorted alphabetically according to the path: - `moment` comes first as it's not a relative path. - `s` is before `u` so `./storage` comes before `./utility`. - Both `applyToAllElements` and `createElement` are from the same file, but `a` is before `c` - Unassigned `require` goes to the end **[Combining require:](#import-rules-combining-require)** When there are many functions being imported from the same file, consider combining it into one import line. ```js const Utility = require('./utility'); ... Utility.handleHash(); Utility.createElement('div'); ... ```