BEM and Coding Standards

Watch videos

Style (SCSS) best-practices:

Scripting (React) best-practices:

BEM

This project uses BEM (Block Element Modifier) approach to organize styles.

Following rules are true specifically in ScandiPWA project case:

  • Blocks and elements start with uppercase: Header

  • If block or element has 2 or more words in its name - they both start with uppercase: MenuItem

  • Blocks and elements are divided with minus sign (-): Header-MenuItem

  • Mods are divided with an underscore (_): Header-MenuItem_visible

  • Mods start with lowercase

  • Mods may consist of:

    • a key and a value: MenuItem_type_dropdown or MenuItem_type_defaultLocal if modifier has 2 or more words in its key or value.

    • a key without value included in the name: MenuItem_visible

  • For boolean modifiers, the value is not included in the name: MenuItem_visible

  • If mod has 2 or more words in its name - it is written as follows: backgroundColor_red

  • Block’s element can’t be accessed from outside the block

How to use it in Javascript?

This projects uses rebem-jsx-plugin to implement BEM in this project.

Defining a block

Defining an element of a block

Defining a block which is an element of parent block

Using mods (modificators) prop

  • Boolean modifier

  • Single key-value modifier

  • Multiple key -> value modifier

How to use it in styles (SCSS)?

Let’s consider following JSX snippet:

  • How to access block:

  • How to access block’s element:

  • How to access modified block’s element:

Coding standard: description of ESLint rules

file-structure

File structure must comply to the following guidelines:

  • File structure must be flat, meaning that nesting components inside of other components is prohibited.

  • Extending root directory src with custom folders is prohibited.

  • File structure regulations imply having files with certain postfixes for certain functionality parts. Allowed postfixes for directories are the following

    • Component and route: .component .container .style .config .unstated

    • Store: .action .dispatcher .reducer

    • Query: .query

    • Style, type: none

  • For files which are in their own directories with functionality related only to them (e.g routes, components), names should match the name of the directory these files are in.

derived-class-names

Class name must match name of the file it is inside of. Expected class names for all the files other than components are name + prefix (e.g. class inside of AddToCart.container.js file must be called AddToCartContainer and not otherwise).

Examples of incorrect code for this rule:

Examples of correct code for this rule:

use-extensible-base

All components should be extensible. For class to be extensible it should be derived from extensible base. Replacements of non-extensible bases are the following and should not be imported - these are available in any point of the application.

  • PureComponent -> ExtensiblePureComponent

  • Component -> ExtensibleComponent

  • no base -> ExtensibleClass

The ExtensiblePureComponent, ExtensibleComponent and ExtensibleClass requires no import.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

only-one-class

There should be only one class per file. Multiple classes inside of one file are not allowed.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

no-non-extensible-components

Non-extensible components are not allowed. Use extensible bases instead of regular Component or PureComponent.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

export-level-one

Variables and classes if declared on root level must be exported (and not by default!)

Examples of incorrect code for this rule:

Examples of correct code for this rule:

use-middleware

Wrap default export classes in middleware function in order to make classes extensible and assign namespaces to them.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

Last updated