Search code examples
javascriptnode.jsecmascript-6project-organization

Is class/namespace-based code organization relevant in JavaScript/Node.js?


Disclaimer: I’m a Node.js newbie.

There’s a number of class-based languages in which you can/must use namespaces to organize your code, for example: Java, PHP, ActionScript 3… For a number of those languages, if you choose/have to use namespaces, there’s generally a set of common practices and conventions that govern project organization then:

  • Classes form the basic code units, and responsibilities are spread across multiple classes.
  • The class file hierarchy reside in a single top-level directory (most of the time: src/ or lib/).
  • Each source file contains a single class definition and nothing else.
  • Each class resides at a specific level of a namespace (or package) hierarchy, which mirrors the filesystem; for example:
    • in Java: class com.badlogic.gdx.Application would be found in the src/com/badlogic/gdx/Application.java file
    • in PHP (with PSR-0): class Symfony\Component\HttpKernel\Kernel would be found in the src/Symfony/Component/HttpKernel/Kernel.php file
  • Foreign class symbols can be imported into the current scope via a specific statement:
    • in Java: import com.badlogic.gdx.Application;
    • in PHP: use Symfony\Component\HttpKernel\Kernel;

I’m used to this type of project organization, but I do realize that it’s specific to class/namespace-based languages and that it might not match JavaScript/Node.js’ usual idioms. If I understand the concept of Node.js modules correctly, it’s 1 source file = 1 module, but from what I’ve seen in a lot of NPM packages, a module usually export more than one symbol, and more often than not those exports are functions and not classes/constructors, so it’s pretty different from the conventions described above.

So, I have the following questions:

  • In JavaScript/Node.js, is it relevant at all to think about distribution of responsibilities in terms of «classes only» (using either the traditional constructor + prototype composition method or the new class shorthand)?
  • Is the type of project organization described above possible at all in the context of a Node.js project?

Solution

  • In JavaScript/Node.js, is it relevant at all to think about distribution of responsibilities in terms of «classes only» (or «prototypes only» for that matter)?

    In Javascript it's a choice rather than a mandate. You can go full OOP even file structure wise. Or just write modules as pure functions. I'd advise you to stick to the structure that's easier for others, who may want to understand your code, to follow. For example, the OOP style:

    Let namespace be the path under src

    /src/org/xml/XMLDocument.js
    

    and have a class very similar to the popular OOP languages:

     // imports
     const fs = require('fs');
     const XMLNode = require('./XMLNode');
    
     // class def
     class XMLDocument extends XMLNode {
    
       // constructor
       constructor(filePath){
         ...
       }
    
       // property getter
       get filePath(){
         ...
       }
    
       // method
       function getElementsByName(name){
         ...
       }
    
     }
    
     // export class to outer world
     module.exports = XMLDocument;
    

    Use the class

    // import
    const XMLDocument = require('./org/xml/XMLDocument');
    
    // create an instance     
    const doc = new XMLDocument('./mydoc.xml');
    

    So yes, following an OOP structure is relevant when you tackle the problem the OOP way. And there are alternate ways as well.

    Another "creator" oriented custom style:

     function createXMLDocument(filePath){
         const doc = {};
         doc._type = "XMLDocument";
         ... // make the object have XMLDocument features
         return doc;
      }
    
      function createDXMLDocument(filePath){
         const doc = cerateXMLDocument(filePath);
         doc._type = "DXMLDocument";
         ... // modify parent object with DXML features
         return doc;
      }
    

    You see, there are some patterns the developer adheres to and write all project code in that style.

    Is the type of project organization described above possible at all in the context of a Node.js project?

    A Node.js project can have any kind of code organisation because of certain features:

    1. Javascript module system is nothing but referencing a js file present somewhere in file system. So there are no special restrictions on file placement. There are modules that are built in, or can be installed via npm.

    2. Module exports can export one or multiple "things" to external world. So a lot of flexibility here as well.

    3. Javascript itself can be easily written in many styles, functional, OOP, procedural etc. It allows developer to modify a lot of Javascript's own nature. Hence possibly "mimic" many programming styles.