Coding Guidelines
Lean towards kebab case for most file names. If you see an exception such as the ‘gg_native’ folder its because the react native init system doesn’t except kebab case.
Most coding conventions are applied by the Biome linter and formatter. You can find the ‘biome.json’ config file in the root of the repo.
Directory.github/
- …
Directory.vscode/
- …
Directorymono/
- …
Directorynative/
- …
- .gitignore
- biome.json
Functions
Explicit functions should be ‘named’, not arrow functions
Arrow functions are great when needed in-line
Imports
When importing functions from the project (not NPM) use file extensions. This means the monorepo tools don’t need to do extra work trying a range of extensions on hundreds of files. The project is set up so you can rely on autocomplete for imports and it will add the extension for you.
WARNING!!! Don’t use the file extension on an import for files that have platform specific alternatives e.g. ‘myComponent.tsx’ because it will fail to load ‘myComponent.android.tsx’ or ‘myComponent.web.tsx’. Here you should just import ‘myComponent’ and let the bundler work out the correct file.
Imports are grouped with 3rd party npm packages first, then local files.
Props
Props are declared in the following style. As a type called ‘Props’, and then a destructured object with the properties. This means a bit less typing i.e. no ‘props.foo’ and also the linter can detect unused properties in the prop.
Exports
A common problem is the use of ‘barrel files’ which export everything from a folder. This can cause performance issues, especially in a monorepo. You need just one function from a file, but behind the scenes the whole file is being imported and parsed.
Instead, export each function directly from the file and rely on autocomplete to help you find the right file.
The Biome linter enforces this rule.
TypeScript
Strict mode is enabled in the project. The hot reloading system does not care about strict mode so while editing code it’s possible to use ‘any’ while working things out. It’s also the case that many other type errors that show up during refactoring won’t break the hot reloading so long as the code is still valid typescript/javascript.
But the CI will reject any PR that doesn’t pass the strict mode check.
Branded Types
Branded types can be used to narrow down certain types for example characterId, bucketHash, itemHash and itemInstanceId. There is a helper to create them as per https://egghead.io/blog/using-branded-types-in-typescript
As of May 2024 some minor refactoring to tidy the use of branded types might be required. But the main use case is to stop the hard to spot mistakes of using ‘itemHash’ instead of ‘itemInstanceId’ which is easily done and not helped by some questionable end point naming that is outside this apps control.
Semantic Commit Messages
See how a minor change to your commit message style can make you a better programmer.
Format: <type>(<scope>): <subject>
<scope>
is optional
Example
More Examples:
feat
: (new feature for the user, not a new feature for build script)fix
: (bug fix for the user, not a fix to a build script)docs
: (changes to the documentation)style
: (formatting, missing semi colons, etc; no production code change)refactor
: (refactoring production code, eg. renaming a variable)test
: (adding missing tests, refactoring tests; no production code change)chore
: (updating grunt tasks etc; no production code change)ux
: (user experience changes)
References: