Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Hoist a config read out of a hot path with lazy memoization, not a module-level constant
Reading config inside a per-row transform re-runs file reads and validation on the response path and can throw mid-serialization. Hoisting it to a module-level constant fixes the cost but moves the side effect to import time, where it can throw during test collection before a single test runs.
Bad example
| 1 | // per row, on the response path: readFileSync, existsSync, 16-entry env validation |
| 2 | const url = `${envConfig().s3.baseUrl}/placeholder.png`; |
| 3 |
|
| 4 | // or, moving the side effect to import time: |
| 5 | const S3_BASE_URL = envConfig().s3.baseUrl; // throws during test collection |
Explanation (EN)
The first form pays the cost per row and can take down a whole response; the second makes any file that imports this module fail before any test body runs.
Objašnjenje (HR)
Prvi oblik placa trosak po retku i moze srusiti cijeli odgovor; drugi cini da svaka datoteka koja uvozi ovaj modul padne prije nego se ijedan test izvrsi.
Good example
| 1 | let s3BaseUrl: string | undefined; |
| 2 |
|
| 3 | const getS3BaseUrl = (): string => { |
| 4 | s3BaseUrl ??= envConfig().s3.baseUrl; |
| 5 | return s3BaseUrl; |
| 6 | }; |
| 7 |
|
| 8 | const url = `${getS3BaseUrl()}/placeholder.png`; |
Explanation (EN)
One read per process, and nothing happens until something actually needs the value.
Objašnjenje (HR)
Jedno citanje po procesu, a nista se ne dogada dok vrijednost stvarno ne zatreba.
Notes (EN)
The rule of thumb: hoisting is about how often the work runs, laziness is about when it first runs. Anything that can throw or touch the filesystem needs both.
Bilješke (HR)
Pravilo: podizanje se tice toga koliko se cesto posao izvodi, lijenost toga kada se prvi put izvede. Sve sto moze baciti gresku ili dirati datotecni sustav treba oboje.