-
-
Notifications
You must be signed in to change notification settings - Fork 654
Code Style Guide
When contributing new code to the codebase, please follow the following code style guide for consistency and continued ease-of-maintenance! Thank you for your help! 🚀
- Imports
- ToDos
- New libraries
- Code
- Use aliases
- File Structure
- Linting
- Typescript
- Styles
- Naming
- Testing
- Dependencies
- Version Control
Keep to the ordered format for imports as follows:
- External module imports
- Absolute imports (Use the
@
operator to reference things in the/src
directory) - Relative imports
ex:
import React from 'react';
import { Heading } from '@mycrypto/ui';
import { AccountContext, StoreContext } from '@services/Store';
import { actions } from './constants';
import './Dashboard.scss';
Please avoid adding new libraries. If you do add one, please note it in your PR and a short description of what it is used for so that the person reviewing has a simple time understanding what it is/what it is used for.
If you add a ToDo somewhere in the code, please use the format @todo: <explanation>
so it's easily-searchable in the future.
A collection of conventions we follow when coding for core
Prefer pure functions
Isolate side effects
Rule Example Rational
Review Codebase Outline We group .stories and .test with the target component.
To facilitate file switching when working on a component
/components
| Account.tsx
| Account.story.tsx
| Account.test.tsx
We use ESlint, Tslint, Prettier. Activate the rules in your IDE for auto-correction.
We use TS and attempt to stay up to date with the latest version.
Place shared typings in @types
Whenever a type is shared place it in the @types
directory. It will allow us to determine which types to place as globals.
Favour type composition over redefinition
It emphasises the relation between the types. Read utility-types
to discover the helpers.
/* Don't */
interface Asset {
uuid: TUuid;
name: string;
symbol: TSymbol;
decimal: number;
}
interface ISwapAsset {
uuid: TUuid;
name: string;
symbol: TSymbol;
}
/* Do */
interface Asset {
uuid: TUuid;
name: string;
symbol: TSymbol;
decimal: number;
}
type ISwapAsset = Omit<Asset, 'decimal'>
Use Brand<>
types for strings
It allows type safety for strings that we can’t enumerate like uuid, address, symbol etc.
/* Don't */
interface Account {
address: string;
}
/* Do */
import { Brand } from 'utility-types';
type TAddress = Brand<string, 'address'>
interface Account {
address: TAddress;
}
Use React.ComponentProps<>
to access a components props So we can reduce the amount of imports
/* Don't */
// Selector.tsx
export interface SelectorProps {...}
export const Selector = (): SelectorProps => {...}
// AssetSelector.tsx
import { Selector, SelectorProps } from '@components'
const AssetSelector = (props: SelectorProps & OwnProps) => (...)
/* Do */
// Selector.tsx
interface Props {...}
export const Selector = (): Props => {...}
// AssetSelector.tsx
import { Selector } from '@components'
const AssetSelector = (props: Pick<React.ComponentProps<Selector>, 'whatever' | 'you' | 'need'>) => (...)
Currently there is a mix between .css
, .scss
, and style
components.
Use theme over importing constants.
It helps reduce imports and anticipates theme switching.
const Wrapper = styled.div`
color: ${({ theme }) => theme.brand }
`;
Use nested SC To reduce the number of intermediate components in JSX
Use &&
for adding conditional styles
const SContainer = styled('div')`
display: inline-flex;
${(p) => p.fontSize && `font-size: ${p.fontSize}`}
`;
Rule: Prefix exported types
Rationale: Facilitate maintenance by making them searchable.
Example:
// Don't
interface SwapAssets {}
// Do
interface TSwapAssets {}
Rule: Prefix SC components with S
Rationale: When parsing JSX it's useful to know what is an SC
Example:
// Don't
const StyledWrapper = styled.div``
const Price = styled(Currency)``
// Do
const SWrapper = styled.div``
const SPrice = styled(Currency)``
Use Jest
watch mode when you code.
Prefer hooks
Prefer ramda
over lodash
(Import the method rather then the default [to decrease bundle size])
Prefer datefns
over moment
PR reviews
Atomic commits: https://dev.to/cbillowes/why-i-create-atomic-commits-in-git-kfi