Categories
JavaScript Best Practices

Maintainable JavaScript — Namespaces and Modules

Spread the love

Creating maintainable JavaScript code is important if want to keep using the code.

In this article, we’ll look at the basics of creating maintainable JavaScript code by looking at namespacing.

Namespaces

It’s possible that we pollute our single global object even if we only created one.

Therefore, if we have one global variable, we organize our code inside it by namespacing the code.

For instance, we can write:

var Books = {};
Books.JavaScript = {};
Books.Ruby = {}

We have the Books global variable and we compartmentalize them with properties.

We have the JavaScript and Ruby properties to organize different things inside the object.

Also, we can add namespaces dynamically by adding properties to our object.

For instance, we can write:

var GlobalObj = {
  namespace(ns) {
    const parts = ns.split(".");
    let object = this;

    for (const part of parts) {
      if (!object[part]) {
        object[part] = {};
      }
      object = object[part];
    }
    return object;
  }
};

We have the namespace function that gets a string that’s separated by dots.

Then we check if the property exists.

If it doesn’t, then we create a property and set it to an empty object.

We do that until all the string parts and added.

And then we return the object .

This way, we can use it by writing:

GlobalObj.namespace('foo.bar.baz');

And we should see the foo property with bar and baz nested in it.

This method gives us freedom to create the namespace and assumes that it exists.

We just run the namespace method beforehand so that we can always use it.

Modules

Since ES6, modules have been part of the JavaScript language.

For instance, we can use them by exporting the members that we want from a module and importing them to use them.

To define a module, we write:

module.js

export const foo = 1;
export const bar = () => {};
export const baz = {};
export default function() {}

to create our JavaScript module with the filename module.js .

Then we can use it by using the import keyword:

import qux, { foo, bar, baz } from "./module";

console.log(qux, foo, bar, baz);

We import the default export as qux .

Default exports are always outside the curly braces and there can only be one of them.

The named exports are in the curly braces and are import with the names that they’re defined as.

We can change the names of default imports to anything.

And we can change the names of named exports with the as keyword.

So we can write:

import qux, { foo, bar, baz as quux } from "./module";

console.log(qux, foo, bar, quux);

The module name can be a relative path or an absolute path.

If it starts with ./ or ../ then it’s a relative path.

./ means relative to the current file.

../ means one directory level up.

Having none of those means it’s an absolute path.

Modules in the node_modules folder can be imported with just the module name.

If something isn’t exported from the module, then they won’t be accessible outside the module.

Conclusion

Namespaces can be added to compartmentalize our code.

Also, we can use modules to export only what we want to expose and keep everything else private.

We can also create smaller files with modules because of that.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *