# JavaScript, TypeScript

  • Use TypeScript, Prettier, ESLint and Jest. Add prettier and eslint plugins to your IDE.
  • ESLint must include rules: 'airbnb', 'prettier/react', 'prettier', 'plugin:react-hooks/recommended'.

# React.js

# Naming

Folder structure example

SmartTable/
  SmartTable.tsx
  SmartTable.spec.tsx
  styles.sass
  constants.ts
  reducer.ts
  reducer.spec.ts
  thunks.ts
  thunks.spec.ts
  models/
  schemas/
  Thead/
     Thead.tsx
     styles.sass
     TH/
       TH.tsx
       styles.sass
  • Directory structure corresponds to the DOM structure.
  • Folders that contains collections wrote in lowercase. Example, models.
  • Write component file in camel case starting with caital symbol. Example, SmartTable.tsx.
  • Component name must be a noun. Example, InvoiceTable.
  • Use camel case for variables, i.e. userName.
  • User pascal case for classes, types, interfaces, components. Examples UserPage, Campaign.
  • Use upper case for constants. Examples CACHE_TTL, COUNT_LIMIT. Prefer to them in constants.ts file.

# Variables

  • Booleans
    • There is a convention to prefix boolean variables and function names with "is" or "has", i.e. isLoggedIn, hasAccess or things like that.
    • Sometimes you have to name variable to make it grammarly correct. Wrong isResourcesLoaded, correct is isEachResourceLoaded.
    • Do not use use negative affirmations, i.e. isNotLoggedIn.

# Components

  • Use React.FC (React.FunctionalComponent) and hooks instead of classes.

  • Avoid HOC (High Order Component) and render props patterns. Use React.Context and decomposition instead.

  • Make Component's API clear and simple. Pass only minimal necessary props.

  • Use proper props order:

    • Required props
    • Optional props
    • Required callbacks
    • Optional callbacks
  • Store all business login on single layer. You may create a context for that:


import { Context, CampaignServiceContext } from './CampaignServiceContext';


export const CampaignServiceProvider: FC = () => {
  const dispatch = useDispatcher<AppDispatch>();

  const contextValues: Context = {
      add: (campaign: Campaign) => dispatch(thunkAction());
      remove: (campaign: Campaign) => dispatch({type: Action.REMOVE_CAMPAIGN, campaign});
  }
  
  return <CampaignServiceContext.Provider value={contextValues}>{children}</CampaignServiceContext.Provider>;
}

# CSS

  • Prefer measures in em or rem:

    • If you need to strictly observe the dimensions, then use rem.
    • If the dimensions are adapted, then use em.
    • The pixel unit px is used in extreme cases. For example, when we use inline styles (although we try to avoid them completely and use selector classes).
  • Avoid CSS-IN-JS.

  • Store styles beside the component, in file styles.{css,sass}. Sub-components can have their own style files.

  • Keep classes lowercase and use dashes (not underscores or camelCase). Dashes serve as natural breaks in related class (e.g., .btn and .btn-danger).

  • Avoid excessive and arbitrary shorthand notation. .btn is useful for button, but .s doesn't mean anything.

  • Keep classes as short and succinct as possible.

  • Use meaningful names; use structural or purposeful names over presentational.

  • Prefix classes based on the closest parent or base class.

# Contexts

  • Do not store state in Contexts that constantly changes.

# Memoization

  • Avoid using memoization if there's no performance issues.
  • Use Highlight updates when components render to check how ofter components rerenders.
  • Use React.memo if props don't change often, but component has some heavy calculations.
  • Use React.useMemo to memoize some calculations.
  • Use React.useCalback if you want to avoid rerendering of heavy child components.

# Typescript

  • Prefer type over interface.
  • Avoid using inheritance. Functions like Omit, Exclude, and others are using to inherit types. It's hard to maintan code with inheritance.
  • Extract types only if want to use them in multple places. Remember to avoid inheritance.
  • Reusable types store in models folder. Place models folder in the component folder.
  • Do not add typing when TS interpolates automatically.
  • Avoid using prefixes in type names like T, I, Type, etc.
  • Use singular type for enum types. Example, UserType, Language.

# Tests

  • Use Jest. Prefer aliases describe() and it().
  • Name a test suite file according to what it tests, i.e. ComponentName.spec.tsx or reducer.spec.ts.
  • Cover with tests business or complicated logic.
  • Function describe for what it tests. Function it what we expected.
describe("withdraw()", () => {
  it('fetches API', () => {...})
  it('dispatches specific actions', () => {...})
});

# Redux

  • When to store state in global Redux store:
    • Dictionaries and collections which changes rarely.
  • When not to store state on global Redux store:
    • If the state of the component is isolated. Like state of modal windows.
  • Store Action types and reducer in file reducer.ts beside the component.
  • Use thunks then:
    • Action contains async logic.
    • Action depends on current global state.
    • Action contains some conditions and dipatches many actions.
  • Store Redux Thunks in file thunks.ts beside the component.
  • Prefer to use more generic actions. For example, send specific Payload object instead of dispatch many actions.
  • Avoid side-effects in reducers.
  • Avoid storing form data in redux. Do it only if you have very a complex form with many states.
  • Do not mutate state in reducers, make a copy return {...state, payload}.
  • Global Redux store must duplicate component structure.
    • If component contains sub-components with their own chunk of state, split reducer as well.

# Vue.js

Official Style Guide (opens new window)

  • Все проекты развернуты с использованием Vue CLI. Для небольших проектов используем file-base структуру, которую предоставляет CLI по умолчанию после установки проекта.
  • Если вы понимаете, что ваш проект будет большой, вы можете использовать фрактальную структуру (Module-based).
  • Файлы компонентов создаем в Camel Case стиле, в соответсвие с официальным style guide (opens new window).
  • В проектах предпочтительно использовать Vue Class Component (opens new window) и TypeScript. Vue CLI позволяет включить данный функционал при установке проекта.
  • Use standard ESLint rules from Vue CLI.