Patterns for ES6 JavaScript modules - Part 1

ES6 Module Patterns

Since I started working on the altseven JavaScript framework several years ago, I have adopted a lot of ES6 conventions, including the use of ES6 modules as the standard means of packaging JavaScript files. I thought I would share some of my favorite module patterns. If you need some background in how ES6 modules work, just look at the Mozilla Developer Network - Modules page.

Simple Export

With this pattern, you export a single const structure that contains global defaults and settings for an application, or for a section of an application. This gives you an easy way to organize and make available globals.

export const globals = {
    maxRows : 50,
    sort: 'dateCreated desc',
    getId: function(){ 
        let baseid = Math.random().toString();
        let id = baseid.substring(2,baseid.length );
        return id;
    }
};

As you can see, this structure can contain simple values and functions. You can then import the const globals from the JavaScript file and use the data in it as member properties and functions, as demonstrated in the HTML code below.

<script type="module">
    import {globals} from "/assets/js/globals.js";
    let id = globals.getId();
    let templ = `global import:
                <p>maxRows: ${globals.maxRows}</p>
                <p>sort: ${globals.sort}</p>
                <p>randomID: ${id}</p>
    `;

    document.getElementById( "app" ).innerHTML = templ;
</script>

<div id="app"></div>

Run this code and you will get something like this output:

globals

One of the reasons to use JavaScript modules is to keep the global scope int he web browser clean. In Single Page Apps (SPAs), you can just import the JS application in your HTML homepage and then everything runs inside the app. However, in traditional Web apps, you will likely need to refer to this module code outside of the script block itself, such as calling values or functions from the module from elements in the page. In this case, you can simply assign the imported module to the global scope and make it available everywhere.

<script type="module">
    import {globals} from "/assets/js/globals.js";
    let id = globals.getId();
    let templ = `global import:
                <p>maxRows: ${globals.maxRows}</p>
                <p>sort: ${globals.sort}</p>
                <p>randomID: ${id}</p>
    `;

    document.getElementById( "app" ).innerHTML = templ;
    window.globals = globals;
</script>

<div id="app"></div>

<div>
      <button onclick="document.getElementById('someId').value=globals.getId();">Generate An Id</button>
      <input type="text" id="someId" name="someId">
</div>

Now you can generate Ids on demand using the member function globals.getId() :

globals

I like this pattern for its simplicity and utility when you need to bundle together a set of global constants for use in an application. It works equally well on the server side in NodeJS and the client side in the browser.