Skip to main content

Code Styleguide

Introduction​


Each guideline describes either a good or bad practice, and all have a consistent presentation.

The wording of each guideline indicates how strong the recommendation is.

Do is one that should always be followed. Always might be a bit too strong of a word. Guidelines that literally should always be followed are extremely rare. On the other hand, you need a really unusual case for breaking a Do guideline.

Consider guidelines should generally be followed. If you fully understand the meaning behind the guideline and have a good reason to deviate, then do so. Please strive to be consistent.

Avoid indicates something you should almost never do. Code examples to avoid have an unmistakable red header.

Why? gives reasons for following the previous recommendations.

General​


1. Rule of One​


Do define one component | service | symbol per file.

Consider limiting files to 400 lines of code.

Why? One component | service | symbol per file makes it far easier to read, maintain, and avoid collisions with teams in source control.

Why? One component | service | symbol per file avoids hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or unwanted coupling with dependencies.

As the app grows, this rule becomes even more important.

2. Common ES6 Export​


Do use common export over default export.

Consider avoiding default export everywhere.

Why? it allows to keep the same name used for the export when importing the module.

Why? export default allows to set any name when importing the module, making it more complicated to later track the module.

Example

We use the name of the const to export the component.

export const PokemonRandomizer = () => {};

We keep the same name of the exported component

import { PokemonRandomizer } from "./PokemonRandomizer.component";

3. Small functions​


Do define small functions

Consider limiting to no more than 15 lines.

Why? Small functions are easier to test, especially when they do one thing and serve one purpose.

Why? Small functions promote reuse.

Why? Small functions are easier to read.

Why? Small functions are easier to maintain.

Why? Small functions help avoid hidden bugs that come with large functions that share variables with external scope, create unwanted closures, or unwanted coupling with dependencies.

Naming​


1. General Naming Guidelines​


Do use consistent names for all symbols.

Do follow a pattern that describes the symbol's feature then its type. The recommended pattern is feature.type.ts.

Why? Naming conventions help provide a consistent way to find content at a glance. Consistency within the project is vital. Consistency with a team is important. Consistency across a company provides tremendous efficiency.

Why? The naming conventions should simply help find desired code faster and make it easier to understand.

Why? Names of folders and files should clearly convey their intent. For example, src/modules/pokemon-randomizer/PokemonRandomizer.component.ts may contain a component that displays a random pokemon.

2. Separate file names with dots and dashes​


Do use "kebab-case" to separate words in the descriptive name.

Do use dots to separate the descriptive name from the type.

Do use consistent type names for all modules following a pattern that describes the module's feature then its type. A recommended pattern is feature.type.ts.

Do use conventional type names including .component, .container, .hoc, .hook, .service, .controller, .model, .router, .helper, .middleware, .constant and .test. Invent additional type names if you must but take care not to create too many.

Why? Type names provide a consistent way to quickly identify what is in the file.

Why? Type names make it easy to find a specific file type using an editor or IDE's fuzzy search techniques.

Why? Unabbreviated type names such as .service are descriptive and unambiguous. Abbreviations such as .cmp, .cm, .h, .srv, .svc, and .serv can be confusing.

Why? Type names provide pattern matching for any automated tasks.

3. Symbols and file names​


Do use consistent names for all assets named after what they represent.

Do use upper camel case for class names and component names.

Do match the name of the symbol to the name of the file.

Why? Consistent conventions make it easy to quickly identify and reference assets of a different type

Coding conventions​


Have a consistent set of coding, naming, and whitespace conventions.

1. Components and Classes​


Do use upper camel case, also known as PascalCase, when naming components and classes.

Why? Follows conventional thinking for component/class names.

Why? Classes can be instantiated and construct an instance. By convention, the upper camel case indicates a constructive asset or a component to render.

2. Constants​


Do declare variables with const if their values should not change during the application lifetime.

Why? Conveys to readers that the value is invariant.

Do create a constants file in module/constants in case you need to use constants in other files.

Do use descriptive name.type convention.

Do group the constants that are related to each other as β€œenums”

Do spell const variables in UPPER_SNAKE_CASE.

Why? The tradition of UPPER_SNAKE_CASE remains popular and pervasive.

Example

export const MAX_POKEMONS = 100;

3. Properties and methods​


Do use lower camel case to name properties and methods.

Why? Follows conventional thinking for properties and methods.

4. Import line spacing​


Consider leaving one empty line between third party imports and application imports.

Consider listing import lines alphabetized by the module.

Consider listing destructured imported symbols alphabetically.

Why? The empty line separates your stuff from their stuff.

Why? Alphabetizing makes it easier to read and locate symbols.

5. Readable Code​


Do Follow these best practices Readable Code John Papa

Do Remember we are a team and we need to understand what you want to do.

4. Application structure​


Have a near-term view of implementation and a long-term vision. Start small but keep in mind where the app is heading down the road. First, define modules. Each module has its own folder, with its own subfolders. (components, constants, helpers, store, etc.) All content is one asset per file. Each component, container, and store elements should be in its own file. Use the naming conventions for files in this guide.

1. LIFT​


Do structure the app such that you can Locate code quickly, Identify the code at a glance, keep the Flattest structure you can, and Try to be DRY.

Do define the structure to follow these four basic guidelines, listed in order of importance.

Why? LIFT provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly. To confirm your intuition about a particular structure, ask: can I quickly open and start work in all of the related files for this feature?

2. Locate​


Do make locating code intuitive, simple and fast.

Why? To work efficiently you must be able to find files quickly, especially when you do not know (or do not remember) the file names. Keeping related files near each other in an intuitive location saves time. A descriptive folder structure makes a world of difference to you and the people who come after you.

3. Identify​


Do name the file such that you instantly know what it contains and represents.

Do be descriptive with file names and keep the contents of the file to exactly one component.

Avoid files with multiple components, multiple elements, or a mixture.

Why? Spend less time hunting and pecking for code, and become more efficient. Longer file names are far better than short-but-obscure abbreviated names.

Consider deviating from the one-thing-per-file rule when you have a set of small, closely-related features that are better discovered and understood in a single file than as multiple files. Be wary of this loophole.

4. Flat​


Do keep a flat folder structure as long as possible.

Consider creating sub-folders when a folder reaches seven or more files.

Consider configuring the IDE to hide distracting, irrelevant files such as generated .js and .js.map files.

Why? No one wants to search for a file through seven levels of folders. A flat structure is easy to scan.

On the other hand, psychologists believe that humans start to struggle when the number of adjacent interesting things exceeds nine. So when a folder has ten or more files, it may be time to create subfolders.

Base your decision on your comfort level. Use a flatter structure until there is an obvious value to creating a new folder.

5. T-DRY (Try to be DRY)​


Do be DRY (Don't Repeat Yourself).

Avoid being so DRY that you sacrifice readability.

Why? Being DRY is important, but not crucial if it sacrifices the other elements of LIFT. That's why it's called T-DRY. For example, it's redundant to name a component review-component.component.js because, with the .component type, it is obviously a component. But if something is not obvious or departs from a convention, then spell it out.

6. Overall structural guidelineslifetime​


Do start small but keep in mind where the app is heading down the road.

Do have a near term view of implementation and a long term vision.

Do put all of the app's code within the projects folder or in the global folders.

Why? It helps to keep the app structure easy to maintain in the early stages while being easy to evolve as the app grows.

Why? It helps when you need to import any type of module, you will know where really is.