The Revealing Module Pattern | Javascript
Tags: javascript, webdev, programming, tutorial
Published: 2023-04-11 08:24:40

One of the biggest challenges of every developer is to maintain code organization. 
There is a plethora of the so called "best practices" someone can follow to result in better code.

The **revealing module pattern** is one of those practices someone can use to achieve better code organization. And it's a pattern that modern features of frontend frameworks are based on. Like React Hooks and Vue Composables.

## The Revealing Module Pattern in Javascript

### What is the Revealing Module Pattern?
In JavaScript, there are no `private` and `public` specifiers.
But as you may know, you can achieve the `private` effect with closures. 

#### Nice opportunity to remember closures!
A simple example: Let's say we have a function `funcInner` encapsulated inside another function `funcOuter` alongside some more variables and even methods. Then, if we return only the `funcInner`, we eventually have `private` staff declared inside the `funcOuter` that only live in the scope of this method.

When `funcOuter` is executed, it creates a new scope for itself. This scope contains its variables, parameters, and inner functions. When `funcInner` is defined, it has access to all the variables and parameters in the scope of `funcOuter`, including those that are not passed as arguments to funcInner.

**Code Example:**
``` javascript
function funcOuter() {
  const outerVariable = "I am outer!";
  const thisIsInsideFuncOuterScope = "Can't access from outside"
  
  function funcInner() {
    const innerVariable = "I am inner!";
    console.log(outerVariable);
    console.log(innerVariable);
  }
  
  return funcInner;
}

const func = funcOuter();
func(); 
// prints "I am outer!" and "I am inner!"
// We don't have access on `thisIsInsideFuncOuterScope`
// We could also run `funcOutter()()` to immediately run the returned function

```

### The next step:
Using closures, we can actually create modules with private and public methods and variables.
This is what we do in the revealing module pattern. 
We use closures to create methods and variables that are hidden from the outside world. All these exist inside a function and we only `return` an **object** that contains only what we want to expose.

This pattern allows us to encapsulate functionality and create modular, reusable code.

#### Let's see it in action
```javascript
const myModule = () => {
  const privateVar = "Hello outer world";

  function privateFunction() {
    console.log(privateVar);
  }

  function publicFunction() {
    privateFunction();
  }

  return {
    publicFunction: publicFunction,
  };
};

const { publicFunction } = myModule(); 
publicFunction() // Outputs "Hello outer world"
```

The `publicFunction` is returned as an object from the closure and can be accessed outside the closure.

## ...A real life example
You can see [here](https://github.com/nickap/vue-exit-intent/blob/d72ad6dc8f5032fa458f60f41fc4df4ad5f6a7da/src/utils/handlers/touchDeviceHandler.ts) how I return only the methods that are responsible only to add and remove the event listeners.
```javascript
export function touchDeviceHandler(options, callback){
  // Private Variables
  let startY = 0;
  let scrolling = false;

  //Private Methods
  const onTouchStart = (event: TouchEvent) => {
    console.log("onTouchMove");
  };

  const onTouchMove = (event: TouchEvent) => {
    console.log("onTouchMove");
  };

  const onTouchEnd = () => {
    scrolling = false;
  };

  // We will expose this
  const addTouchListeners = () => {
    document.addEventListener('touchstart', onTouchStart);
    document.addEventListener('touchmove', onTouchMove);
    document.addEventListener('touchend', onTouchEnd);
  };

  // We will expose this too
  const removeTouchDeviceListeners = () => {
    document.removeEventListener('touchstart', onTouchStart);
    document.removeEventListener('touchmove', onTouchMove);
    document.removeEventListener('touchend', onTouchEnd);
  };
/* Returned Object, containing only what we want to expose */
  return {
    addTouchListeners,
    removeTouchDeviceListeners
  };
}
```
And [here](https://github.com/nickap/vue-exit-intent/blob/d72ad6dc8f5032fa458f60f41fc4df4ad5f6a7da/src/composables/useVueExitIntent.ts) you can see how we use `touchDeviceHandler`.

I just destructure the returned object 
```javascript
const { addTouchListeners, removeTouchDeviceListeners } = touchDeviceHandler(
    options,
    fire
  );
```
And eventually, lower in the code, it's so clean and easy for someone to understand what I am actually doing when calling ```javascript
removeTouchDeviceListeners();
```

In case you are interested, here is the [repo](https://github.com/nickap/vue-exit-intent)

#### Eventually
Using the revealing module pattern, the code is so clean and modular that I can even expose  `addTouchEventListeners();` and `removeTouchDeviceListeners();` from the composable. That way, the user of the composable could act on his own style, adding and removing the listeners at his convinience.

Finally
## Advantages of the Revealing Module Pattern

- Encapsulation.
- Preventing Variable Name Collisions.
- Modularity.

Thank you for reading up to this line!