Recursive structure of JS code


JavaScript is a very flexible programming language, so every JS developer should have some rules to organize their own code to be successful. In this post, I describe my own very simple rules that I use to structure my code. This is not an action guide, but rather a systematization of my observations.


npm-package

Packages are top-level bricks of any large enough JS project, but package-level code is out of the scope of this post. It is JSON code rather than JS code.


ES6 module

An ES6-module is a building block for npm-packages. JS does not restrict how many code elements (constants, variables, functions, …) can be placed in one ES6-module. I distinguish the following code areas at the module level:

Example:

// IMPORT
import {link} from "node:fs";

// VARS
const PI = 3.14;
let r, l, s;

// FUNCS
function print(msg) {}

// CLASSES
class Printer {}

// MAIN
r = 4;
l = 2 * PI * r;
s = PI * r * r;

// EXPORT
export {r, l, s, print, Printer}

Two areas are specific for ES6-modules only:

Other areas are common areas, and they can be used in any scope (module, function, statement). For example:

// VARS
let a, b;

// MAIN
if (a === b) {
// CLASSES
    class Printer {
        out(data) {
            console.log(data);
        }
    }

// MAIN
    const p = new Printer();
    p.out('Hello World!');
}

Nonetheless, I exclude the CLASSES area from common areas and use it on the module level only — I don’t use classes inside other classes, functions, or statement scopes in my code.


Scope

These 3 areas can be used in any scope (module, function, statement):

I use this order because it is convenient for me. I prefer to know what stuff (vars, const, funcs) can be used in calculations (MAIN). There is a feature called hoisting in JS — all declarations in scope will be available in this scope regardless of declaration’s place, so I just use a natural order here.

Since every scope can contain nested scopes, we have recursion for JS code structure for these 3 areas:

// VARS
let a = 1, b = 2;

// FUNCS
function print(c, d) {
// VARS
    let x, y;

// FUNCS
    const norm = (z) => `${z}`.padStart(2, '0');

// MAIN
    x = norm(c);
    y = norm(d);
    console.log(`first: ${x}; second: ${y}`);
}

// MAIN
print(a, b);

Resume

In my opinion, the same structure for the code in the project helps the developer understand code faster and better. Short comments with names of the areas in large scripts make the developer more efficient (especially in large scripts with nested scopes).

LOGO