Revealing Module Pattern in JavaScript
Tags: webdev, javascript, beginners, tutorial
Published: 2020-01-07 06:41:37

After taking a short break during the holidays, I'm happy to be back with a new post. This time, we'll be taking a look at a Revealing Module Pattern, frequently used by JavaScript developers.

It's a very useful pattern that keeps our codebase clean and prevents malicious JavaScript manipulation from the browser console. Both junior and senior JavaScript developers are not usually aware of this pattern and it can be really useful for both performance and security. 

I'm very fond of this pattern and I'm using it all the time when working on non-React projects.

## About the window object

JavaScript's `window` object **represents the browser window**. Sounds simple enough. Like any object, it **contains properties (variables) and methods (functions)**. 

For example, some of the window properties are:

`window.innerHeight` - inner height of the browser window
`window.innerWidth` - inner width of the browser window


And some of the window methods are:
`window.alert()` - opens a popup window with a message
`window.open()` - opens a new window
`window.close()` - closes the current window


What's special about the **window object is that it's globally accessible** in most cases. Properties and methods of the objects can be accessed from any file that supports client-side JavaScript... and they can be accessed even from **your regular browser** via the dev tools.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ht4jlvn1c1v0cmwfok0p.JPG)
<figcaption>Try running some of those commands </figcaption>

## Potential issues with the window object

### Malicious code manipulation

Try defining a JavaScript file that contains only the following line:

```js
let score = 0;

const updateScore = (newScore) => score = newScore;
```

It looks like a regular JavaScript, right? No apparent issues can be seen.

If you open this website in your browser, you can see the `score` variable included in the `window` object. Meaning that you can **freely manipulate the variable directly from dev tools in your browser!** If this variable is crucial to the site's functionality or it contains sensitive information, it can be easily accessed and exploited.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jgcpubrno2e6hxudwzmv.JPG)
<figcaption>Uh oh...</figcaption>

The same rule applies to methods (function). Any function present in the `window` object can be called from the dev tools.

### Performance & Garbage collection

You might have come across the advice along the lines of: **Avoid polluting the global namespace**. This basically means that we should avoid declaring global variables and functions. What is the reason for that?

**Garbage collection** means that the browser automatically manages memory by deciding which resources are needed at that moment. When a function or a variable is no longer needed, the browser frees up space. If all our variables and functions are part of a global `window` object, the browser automatically assumes that these are needed as long as the window (or a tab) is opened, so they will never be removed. The memory will always be allocated for those resources regardless of the fact if they are actually used. That is why we refer to this as **garbage** and **pollution** in terms of the code.

### Public and private scope

Javascript doesn't really have the usual **public** or **private** scope modifiers like the regular Object-oriented languages do. We can solve this in a really elegant and simple way by using JavaScript's regular function-level scoping.

## Revealing module pattern

This is where **Revealing module pattern** Javascript comes in. Let's take a look at the following example.

```js
const game = (() => {
 let score = 0;

 const setScore = (newScore) => score = newScore;

 const incrementScore = () => setScore(score + 1);

 return {
  incrementScore
 }
})();
```

We can see how **Revealing module pattern** lives up to its name.

```js
const example = (() => {
  /* Variable and function definitions */

  return {
    /* Variables and functions that we would like to expose */
  }

})();
```

**All variables and functions that are not returned are considered private and cannot be accessed outside the scope of the function.**

By returning an object that can contain any variables and functions declared in the IIFE (immediately-invoked function expression, which is explained later) we are choosing what parts of the functionality to **reveal**. These cannot be altered from the global scope. In a worst-case scenario, manipulation would cause the functionality to fail and the site would break on the client's side, but that is also true for any other kind of code manipulation that we can do from our browser's dev tools (HTML, CSS or JavaScript manipulation).

In our example, we have the following **private** elements:
* `score` - a variable that keeps track of the current score value
* `setScore` - a function that directly manipulates the `score` variable by setting its value directly. Also known as a **setter** function.

Those two functionalities are very important in our example and should not be accessed outside the function, so we need a create an **interface** that we can **reveal** that will update the `score` variable indirectly.

This is where the `incrementScore` function comes in. It only calls the private function and determines how the score should be incremented. Thusly, this functionality **cannot** be altered or manipulated in a malicious way beyond simply breaking the website on the client's side.

And, finally, by wrapping our `game` expression in the **IIFE (immediately-invoked function expression)**, we prevent the function from being included in the `window object` and we avoid the possibility of someone to initialize another `game` from dev tools.

Now that we understand how Revealing Module Pattern works and how it can be implemented, let's go through an example.

## Example

Let's imagine that we are working on a game and our task is to create a score tracking function that has the following functionality:
* Initialize the score tracking with value of 0
* Allows us to increment the score by 1 (rule of the game)
* Resets the score
* Submits the current score once the game is finished
* Displays score state in HTML

### window object implementation

Let's first implement this in a "regular way" just to get a better grasp of the functions and highlight the potential issues that we've explained.

**Note**: You might want to open this codepen link in a window to use the **Console** functionality in order to try and manipulate the score.

{% codepen https://codepen.io/AdrianBece/pen/qBEVWKM default-tab=js,result %}

Let's see if we are able to manipulate the score from the browser's dev tools.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/nhj2j6mhwbhq4n2zmzg5.JPG)
<figcaption>We have a full access to the variables and functions</figcaption>

As expected, we can easily access and manipulate the score value and call any function that we want.

### Revealing module pattern implementation

Let's convert our JavaScript implementation into a Revealing module pattern. We can easily determine which parts of the interface need to be revealed by looking at which functions are being directly called from the HTML.

{% codepen https://codepen.io/AdrianBece/pen/ExabxVd default-tab=js,result %}

Let's see if we are now able to manipulate the score from the browser's dev tools.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/lpiro0wlswfaq86tpr34.JPG)
<figcaption>As expected, score variable and the setter function is no longer the part of the global object</figcaption>

We have successfully removed our functionality and variables from the `window` object and we've prevented the possibility of manipulating the values in a malicious way.

We could have also taken a look into how to better protect the `incrementScore` function so the user cannot call it from the dev tools, but that would make this example a bit more complex than it needs to be. Also, this function is only revealed so it can be connected to a button for convenience. We could imagine that this would be tied into game mechanics which would also remain private functions.

<hr />

These articles are fueled by coffee. So if you enjoy my work and found it useful, consider buying me a coffee! I would really appreciate it.

<a href="https://www.buymeacoffee.com/ubnZ8GgDJ" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-red.png" alt="Buy Me A Coffee" style="height: 51px !important;width: 217px !important;" ></a>

Thank you for taking the time to read this post. If you've found this useful, please give it a ❤️ or 🦄, share and comment.