# What this PR does
Add frontend guidelines as md file
## Checklist
- [ ] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
show up in the autogenerated release notes.
---------
Co-authored-by: Rares Mardare <rares.mardare@grafana.com>
5 KiB
5 KiB
OnCall Frontend Guidelines
The base guidelines we decided to follow are:
- https://github.com/ryanmcdermott/clean-code-javascript
- https://github.com/grafana/grafana/tree/main/contribute/style-guides
Anything that is either not covered by the materials above or we decided to do differently is stated in this document.
Ways of working
Code reviews
- PR can be merged when the following conditions are met:
- CI pipeline succeeded without bypassing checks
- There is at least 1 approval from the frontend team and no opened remarks from reviewers other than the approver
- All comments are replied, answered, addressed or discussed separately
- We make use of builtin GH PR reviews
- Minor comments that don’t need to be addressed right away and are not a blocker for a merge are marked with “Minor: “ prefix
- Unless there is some important hotfix to make and no frontend mates are available
Technical conventions
Type-safety
- Don’t use implicit / explicit
anyor @ts-ignore
Use auto generated types for new features
- For new features and endpoints that are covered by OpenApi schemas, we should use auto generated types and typed http client
Naming conventions on most used variables such as handlers, booleans etc
- Use descriptive naming (such as the use of is) that follows natural convention such as
isFormVerifiedorisAuthenticatedinstead of verified, authenticated etc - Use descriptive naming for event handlers such as
onIconClickoronInputChangerather than handleChange - Include the verb part in the functions’ names
- For 3 or more function arguments use object destructuring https://github.com/ryanmcdermott/clean-code-javascript?tab=readme-ov-file#function-arguments-2-or-fewer-ideally
- For functions that return other functions getBlaBlaHandler (in case of handlers) or getBlaBlaFn (if it’s not handler that is returned)
- Don’t use higher-ordered functions without clear need
State management
Don’t use returned values from MobX actions
- MobX actions should not return value that is later used within components. Instead MobX actions should update observables and then components should consume observables to reflect data updates.
Leverage small global stores over local state passed as props over multiple levels
- Create small specialized store in MobX even for small feature instead of relying on local state that is passed down the React tree over multiple levels e.g.: alert_receive_channel_connected_channels.ts alert_receive_channel_webhooks.ts
Use global decorators / custom hooks / utilities consistently
- For example:
@WithGlobalNotificationto set successful / failing notification based on MobX action’s result@AutoLoadingStateto manage loading statuses of async actionsuseIsLoadingto consume loading stateuseDrawerto manage drawersuseConfirmModalto manage confirm modal- Global helpers
Code organization
Store files in appropriate places
- Store files in appropriate places (components, containers, models etc)
- Helpers and configs should be stored in the same folder with the appropriate name e.g. [container].helper.ts, [container].config.ts
- Project-wide utilities should be placed in the utils folder`
- Use named exports for all code you want to export from a file.
- Export only the code that is meant to be used outside the module.
Don’t opt-out from eslint / TS rules
- Avoid opting out from eslint or TS rules unless there is a strong reason / lack of possibility to follow the rule
Styling
Use Emotion.js with agreed code style
- Use emotion.js for styling
- Make use of
useStyles2hook - Use css `` syntax
- Place
getStylesfunction at the end of the same file or in the separate file withX.styles.tssuffix (if it’s reused by multiple components or it’s too large for placing in the same component’s file)
React
Keep components functional and small
- Use functional components for new features
- Leverage components composition, use many small components, render list items in dedicated component and dereference values late https://mobx.js.org/react-optimizations.html
- Keep components small and flat
- Use dedicated components over render functions in case a there's a risk that a single component grows too much
- Static values (especially non-primitive) that don’t depend on local state, props or store should be extracted out of component
- Don’t create unnecessary local state that duplicates parts of global store
- Leverage custom hooks to extract repetitive logic
- Don’t use useMemo / useCallback by default
Architecture
Use layered architecture
- Don’t interact with backend directly from components
- Don’t interact with 3rd party (faro, web storage etc) directly but rather through service
Frontend-backend communication
Use typed HTTP request and response payloads
- HTTP request payload and response payload should always be typed
- Use typed http client whenever we have auto-generated types available