mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-01-09 01:21:01 +00:00
Add codestyle docs (#1356)
This commit is contained in:
parent
519665a8bf
commit
910d8b9423
1 changed files with 130 additions and 0 deletions
130
CONTRIBUTING.md
130
CONTRIBUTING.md
|
@ -56,6 +56,136 @@ If you set your `user.name` and `user.email` git configs, you can sign your comm
|
||||||
You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases) like `git config --global alias.ci 'commit -s'`.
|
You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases) like `git config --global alias.ci 'commit -s'`.
|
||||||
Now you can commit with `git ci` and the commit will be signed.
|
Now you can commit with `git ci` and the commit will be signed.
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
Most of the code style is enforced by [prettier](https://prettier.io/) and our [eslint](https://eslint.org) configuration.
|
||||||
|
If your IDE doesn't support integration of prettier and/or eslint you can use the npm tasks `lint` and `format` to check your code style.
|
||||||
|
|
||||||
|
For both npm tasks, there is also an additional `:fix` task. This will try to fix the code to the best of either tools ability.
|
||||||
|
|
||||||
|
### Number of lines
|
||||||
|
|
||||||
|
Try to keep the files as short as possible while keeping the context between the code parts by
|
||||||
|
- splitting your code into multiple files. Especially react components can and should be separated into atomic components and custom hooks.
|
||||||
|
- avoiding repetition.
|
||||||
|
- extracting types and interfaces into `.d.ts` files.
|
||||||
|
|
||||||
|
### Function Style
|
||||||
|
|
||||||
|
We prefer lambda functions over the `function` keyword. Simple functions, that return a value can be shortened to one-liners.
|
||||||
|
|
||||||
|
:+1: Good:
|
||||||
|
```typescript=
|
||||||
|
const addTwo = (x: number): number => x + 2
|
||||||
|
```
|
||||||
|
|
||||||
|
:-1: Bad:
|
||||||
|
```typescript=
|
||||||
|
function addTwo (x: number): number {
|
||||||
|
return x + 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Function naming
|
||||||
|
|
||||||
|
Names of functions should
|
||||||
|
- be as short as possible while clearly communicating their purpose.
|
||||||
|
- not include technical details, if not necessary.
|
||||||
|
- avoid abbreviations.
|
||||||
|
|
||||||
|
:+1: Good:
|
||||||
|
```typescript=
|
||||||
|
const addTwo = (x: number): number => x + 2
|
||||||
|
```
|
||||||
|
|
||||||
|
:-1: Bad:
|
||||||
|
```typescript=
|
||||||
|
const doStuffWithX = (x: number): number => x + 2
|
||||||
|
```
|
||||||
|
|
||||||
|
:-1: Bad:
|
||||||
|
```typescript=
|
||||||
|
const incrementXTwoTimesButNotRecursive = (x: number): number => x + 2
|
||||||
|
```
|
||||||
|
|
||||||
|
:-1: Bad:
|
||||||
|
```typescript=
|
||||||
|
const clcX = (x: number): number => x + 2
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Documentation of functions
|
||||||
|
|
||||||
|
To make the code as clear as possible to everyone, who will try to understand it, every function must have an [ESDoc](https://esdoc.org/).
|
||||||
|
|
||||||
|
Please make sure that your documenation can be read in a standard text editor (hard line breaks at ~120 characters, etc.).
|
||||||
|
|
||||||
|
The documentation must
|
||||||
|
- explain what the function does. If the explanation is longer than one line, then write a short introdoctory first line, followed by a break and then the longer explanation.
|
||||||
|
- contain every parameter with the `@param name explaination` annotation, that explains the purpose of the parameter.
|
||||||
|
- contain a `@return description` annotation if the return type isn't `void`, that explains the meaning of the value.
|
||||||
|
- contain `@throws ErrorClass description` annotations if the function throws runtime errors or doesn't catch errors from other method calls.
|
||||||
|
- contain a blank line between the description and the annotation block.
|
||||||
|
|
||||||
|
The described annotations must appear in this order: `@param`, `@return`, `@throws`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```typescript=
|
||||||
|
/**
|
||||||
|
* Calculates the divison of the given divisor and divident.
|
||||||
|
*
|
||||||
|
* @param divisor The divisor for the calculation
|
||||||
|
* @param divident The divident for the calculation
|
||||||
|
* @return The calculated division.
|
||||||
|
* @throws Error if the divident is zero.
|
||||||
|
*/
|
||||||
|
const divide = (divisor: number, divident: number): number => {
|
||||||
|
if (divident === 0) {
|
||||||
|
throw new Error("Can not divide by zero")
|
||||||
|
}
|
||||||
|
return divisor / divident
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Documentation of types and interfaces
|
||||||
|
|
||||||
|
Every exported type and interface must have an [ESDoc](https://esdoc.org/). No special annotations are needed.
|
||||||
|
|
||||||
|
### React components
|
||||||
|
|
||||||
|
React components
|
||||||
|
- must be functional. Use the `React.FC` type.
|
||||||
|
- can omit the `@return` annotation in the ESDoc if it returns always the same React DOM.
|
||||||
|
- should use the [`useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback) hook where possible. Don't use inline functions.
|
||||||
|
- should use [custom hooks](https://reactjs.org/docs/hooks-custom.html) to extract long functions to reduce the number of lines in the component file.
|
||||||
|
- must be placed in files that have the same name as the component, but in [kebab-case](https://stackoverflow.com/a/17820138). This file can also contain the interface for the properties.
|
||||||
|
- should be named in [PascalCase](https://en.wikipedia.org/wiki/Pascal_case).
|
||||||
|
|
||||||
|
|
||||||
|
#### Example File: `increment-number-button.tsx`:
|
||||||
|
```typescript=
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties for the {@link IncrementNumberButton}
|
||||||
|
*/
|
||||||
|
export interface IncrementNumberButtonProps {
|
||||||
|
prefix: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a button that contains a text and a number that gets incremented each time you click it.
|
||||||
|
*
|
||||||
|
* @param prefix A text that should be added before the number.
|
||||||
|
*/
|
||||||
|
export const IncrementNumberButton: React.FC<IncrementNumberButtonProps> = ({ prefix }) => {
|
||||||
|
const [counter, setCounter] = useState(0)
|
||||||
|
|
||||||
|
const incrementCounter = useCallback(() => setCounter((lastCounter) => lastCounter + 1), [])
|
||||||
|
|
||||||
|
return <button onClick={incrementCounter}>{prefix}: {counter}</button>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
[issues]: https://github.com/hedgedoc/react-client/issues
|
[issues]: https://github.com/hedgedoc/react-client/issues
|
||||||
[new_issue]: https://github.com/hedgedoc/react-client/issues/new/choose
|
[new_issue]: https://github.com/hedgedoc/react-client/issues/new/choose
|
||||||
[matrix-support]: https://matrix.to/#/#hedgedoc:matrix.org
|
[matrix-support]: https://matrix.to/#/#hedgedoc:matrix.org
|
||||||
|
|
Loading…
Reference in a new issue