BEM and Coding Standards
Last updated
Last updated
Style (SCSS) best-practices:
Scripting (React) best-practices:
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
This projects uses rebem-jsx-plugin to implement BEM in this project.
Note:
usage of className
prop is prohibited
Note:
string props are declared with double quotes ("
), while the object keys are declared with single quotes ('
).
Boolean modifier
Note:
the prop name should start with is
to immediately represent boolean
Single key-value modifier
Multiple key -> value modifier
Let’s consider following JSX snippet:
How to access block:
How to access block’s element:
Note:
&
stands for parent selector, it is very useful in order to not repeat yourself.
How to access modified block’s element:
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: