-
Notifications
You must be signed in to change notification settings - Fork 0
Coding guideline
- Introduction
- No magic Numbers
- No hoisting
- Null and undefined
- Semicolon
- Indentation
- Newlines
- Braces
- Quotes
- Commas
- Equality operators
- Naming Convention
- Naming Class and Object property
- Naming Class
- Naming Property
- Naming Function
- Naming Interface
- Typing
- Typing Function parameter
- Typing Function return
- Logging The first line of defense
- Loops
- What to Log
- Error levels
- Comment
- Formatting and style
- Testing
- Code abstraction
The purpose of this code guideline is to insure code is easy to read and maintain. That code looks consistent such that the style is the same throughout, as if written by one author. The principle being, "No one owns the code and everyone owns the code".
Written code must be self documenting. It must be clear from the name, what the purpose is for a:
- Variable
- Function
- Object
- Class
- Interface
Do not fall into the trap that the "code is the document". It is a poor choice for a document. If someone writes an incorrect rule, flawed logic, implements a broken algorithm or data structure how will anyone else know what the true purpose of the code is. One will only learn (incorrectly) from the flawed implementation, and without proper documentation there will be no other way to know it is true nature.
A document serves to define:
- Functional logic (business rules)
- Usage contract (Interface, API)
- Valid input
- Expect output
- Error codes
Do not assume code is obvious to others because it is obvious to you.
As soon as code is written, it instantly becomes an Ancient artifact. You must communicate to the future civilization it purpose effectively.
Make use of const
values or enums
, do not hard-code numbers or string literals.
Avoid hoisting, always declare before use. Never use clever tricks to hoist functions inside function or code blocks.
Never use null
in the code, always use undefined
to declare something has no value.
As a result you can always make use of ===
over ==
for checking an undefined
value. Using ===
is much faster and also avoids type coercion.
Always terminate a line of code with a semicolon.
Use two spaces for indenting code, do not use tabs.
UNIX newline \n
must be used to terminate end of line, and no trailing spaces.
Always use braces, even for single line statement.
if(condition) { a = -a; }
or
if(condition) {
a = -a;
}
When using quotes, use double quotes before single quotes. The only time it is valid to use single quotes is when there is a string that must have a quoted word(s). This avoids the need to use a backslash "" to escape a quote.
let msg: string = "It is 'important' to use quotes correctly";
No trailing commas.
const DAYS: string[] = [
"Monday",
"Tuesday",
"Wednesday"
];
Always use ===
or !==
before ==
or !=
.
Use long descriptive names. Reserve short or single letter names for loops or utility functions such as a swap function.
Variable name must be all uppercase.
A Filename must be lowercase and use Kebab-case. Each word is separated with a hyphen "-". A filename must use the proper extension or mime-type.
A filename may add classification. All names used to classify must by prefixed with a dot "." character.
user-validation.service.ts
A variable name must be lowercase and use snake_casing. Words are separated with an underscore "_".
let read_buffer: string[];
Never prefix a variable name with special characters like "$" (example, $event).
A variable must be declared using one of the following keywords:
- let
- const
A variables must be declared with explicit types.
Variable must be assigned a (default) value when declared.
Do not use commas to declare multiple variables. Each variable must be declared separately on its own line.
let msg: string = "";
let name: string = "Shivaji";
let obj: {type: string, action: string} = {};
let status_code: number = -1;
Variable declared using const
must be in uppercase;
const API_VERSIONS: string = "v0.1.0";
Object variable name follow the same naming convention defined earlier.
A class property must be prefixed with an underscore "_".
A class property must have one of the following access modifiers:
- protected
- private
The only time the public
access modified should be used is when the class acts more like a regular "data" object used to pass a group of related properties together.
For class variable access, use a method to control or restrict access. If you insist on having a property style access over method access, then make use of getter and setter.
A Class name must use PascalCase. Each word in the name is capitalized.
class HelloWorld {
}
See section.
A Function name must be camelCase, name starts lowercase and each word thereafter is capitalized.
function loadData() {
}
A type Interface name
- Must use Pascal-case.
- Must not be prefixed with an "I"
interface Database {
}
A function type interface must also have a postfix of "Func" in the name.
interface CallbackFunc {
}
In TypeScript code, all types must explicitly declare their type.
Each function parameter must have an explicit type.
function copyBuffer(src: number[],
dest: number[],
index: number): number
Argument that is an objects type, is better defined as an Interface to keep the code concise.
function insertUser( data: {name: string,
surname: string,
uid: string,
password: string} ): boolean
Below we added and optional "index" property.
Interface UserModel {
index?: any,
name: string,
surname: string,
uid: string,
password: string
}
function insertUser( data: UserModel )
A function must declare and explicit return type. For a function not returning a value, use the type "void".
function negate(val: number): void
Avoid making use of the the type "any", when possible use the correct type.
Put considerable thought into logging, allow support to identify cause of issue and correct it without having to call you at 3AM! Also you want to be able to get up and running ASAP after an error, specially critical ones.
Three domain of logging
- Development
- Production
- Monitoring
- Journaling (Audit trail)
Follow these rules when logging to avoid performance penalties.
- Always log to a file, never to console.
- Never log inside a loop.
- Avoid logging inside a heavily used function.
- Use separate logging for production and development.
- In production release, comment out development logging.
All console logging should be commented out in production release.
Write log on a separate line so they can easily be found and commented out using a script.
Do not use the for
loop. Instead, use of one of the following:
forEach
for of
for in
map
filter
reduce
Never log sensitive data like: User name, account, passwords.
A log should have the following format:
DD-MM-YY HH:MM:SS:MS PID LEVEL EID TEST
- Date & Time stamp UTC.
- PID
- Error code, well defined.
- Error Level
- Location of error (file, function) to find point of error in code.
- Description that is clear, concise and understandable by admin.
Each log statement must end with a period.
For all major errors, dump the stack to file!
Debug - For development, never should see in production logs. l
Info - An action was performed, useful for auditing.
Warn - A alert such as memory low, request timing out, etc.
Error - A error that is recoverable without crashing, need to be looked at.
Critical - Unrecoverable error. Stops the world, requires a reboot.
The comment style followed is JSDoc. Make sure to comment:
- File
- Function
- Class or Object
- Interface
- Enums
- Blocks of code
For ALL blocks of code, comment what the code block does, not have it does something.
You can ignore formatting for the most part and just type the code, it will be run through a code formatter to make the source code uniform. Fix any error that is generated by the code linter.
if ( condition ) {
} else if ( condition ) {
} else {
}
try {
} catch( ex ) {
}
// Parameter alignment
function Fn( arg1: type,
arg2: type,
arg3: type ): type {
}
For single argument, do not use parenthesis.
const size = buf => buf.size;
const max(x, y) => x > y ? x : y;
All code must have a set of unit tests.
- For Node based code, use Tape to testing.
- Do not use BBD for writing test, must be assert based methods.
Keep the code as simple and easy to read from a single place. Do not abstract design, this overloads the mind and causes context-switching. Abstract code only when it is absolutely necessary, re-think of an alternative simpler design first. Do not over engineer code for the future, extra code, API, functions that do not get used as dead-code.
The best thing a programmer can do is delete code!