-
Notifications
You must be signed in to change notification settings - Fork 16
Coding Guidelines
-
These are not to be blindly followed; strive to understand these and ask
when in doubt. Sometimes standards are a bad idea. -
Don't duplicate the functionality of a built-in library.
-
Not kidding, really try hard not to duplicate the functionality of any existing library or function. If this means making a new repo to share across projects... please do that... even if it's a simple function.
-
Don't swallow exceptions or "fail silently."
-
Don't write code that guesses at future functionality. (Don't be an architecture astronaut)
-
Use callbacks, passed objects and/or split the repo up into multiple repos to prevent tight coupling across directory boundaries. Especially avoid cross-importing.
-
Never use IPC where importing a class or useHook will work. If that class/hook comes with too much baggage, break it up and import the stuff you need.
-
Strive to adhere to the Unix Philosophy. There are some nice articles that discuss this philosophy as applied to object oriented code and react:
-
Master branch must require code reviews and passing tests
-
All new projects must have a full CI pipeline, including linters, tests
-
Coverage enforcement is required (even a ui should be "load checked", etc.)
-
If a project has dependencies, it must use and commit a lockfile of some sort
-
Avoid global variables & long parameter lists
-
Limit dependencies of an object (entities an object depends on).
-
Limit an object's dependents (entities that depend on an object).
-
Prefer composition over inheritance.
-
Prefer inheritance over callbacks and branches.
-
Prefer small methods. Between one and five lines when it makes sense
-
Prefer small classes with a single, well-defined responsibility. When a
class exceeds 100 lines, it may be doing too many things.
-
No system should ever hit the internet/connect to network, open a file that might be on a network drive, etc. ... as a precondition for startup. Missing network/internet needs to be gracefully handled at any time and for any reason.
-
When opening a file or reading data from the internet in any way, assume it contains deliberately constructed malicious data. Write a test to prove that appropriate exceptions are thrown, and are gracefully handled.
-
When doing IPC, assume the other service can be down. Ensure timeouts & failures are handled.
- Start new projects with Typescript
- Use maps, not objects
- Minimize state rerendering using mobx (or whatever tool, redux, etc)
- No default exports
- No require cycles
- No relative imports unless necessary to avoid require cycles or if in same folder
- Filenames for React components should be the name of the primary export (e.g. RootNavigator.tsx)
- Imports should be sorted via TypeScript Import Sorter (VSCode extension) from 'Michael' [TODO: Extract config for use with other editors]
-
Avoid testing private methods.
-
Use intermediate assertions about state during test progression.
-
When at all possible, put your debug logs in the test, not in the code.
-
Use both integration tests and unit tests not one or the other.
-
Don't evade coverage checks.
-
It's always better not to use mocks and use fixtures instead where posible
-
Feel free to test with a "temp server" or "fast/inline nostr relay"
-
Feel free to "hot test" or "integration test", but please mark/tag the test so they can be run separately.
-
Ideally, integration tests should not contribute to coverage minimums.
-
[Index foreign keys].
-
Constrain most columns as [NOT NULL].
-
In a SQL view, only select columns you need (i.e., no SELECT table.*).
-
Use an ORDER BY clause on queries where the results will be displayed to a
user, as queries without one may return results in a changing, arbitrary
order. -
Never put meaningful or computed data in the "id" or "primary key" field of a table.
-
Sqlite need not be considered a "relational database", depending on what you're doing with it.
-
Use as key-value store is OK
-
Use as indexed "blob storage" instead of filesystem is OK
-
-
No complex bash scripts. Scripts that are complex enough to need stuff like functions and loops should be moved into a language suitable for complexity and testing, like python or node.
-
No one-off complex scripts. Scripts that manage deployments, requirements, etc should, ideally be abstracted and run in many projects.... rather than each project having its own requirements, versioning and deployments systems. This is especially true for libraries.
-
Avoid rendering delays caused by synchronous javascript hits.
-
Use UTF-8 only
To add new standards:
-
First make sure your proposal doesn't suck. Coding standards that suck have the following attributes:
-
Full of author's own opinions and personal coding style.
-
Huge focus on style and formatting issues
-
Recommendations disguised as standards.
-
See: https://codeahoy.com/2016/05/22/effective-coding-standards/
-
-
Open up a slack discussion with at least 3 other devs and propose one or more additions or changes. Include the CTO and the Engineering Manager.
-
Edit this page with the verbiage everyone agrees on.