Creating and using facades in JavaScript
When writing a JavaScript module or library it is important to always try to make sure your code is concise and easy to understand, other developers are going to want to use it and they should be able to quickly and easily use the code that you have produced. There are numerous ways to make your code easier to understand, writing good documentation and using good variable/function names come to mind. The method I want to look at today is by using the facade pattern.
A facade pattern can help in hiding the inner working of your module, and expose only the necessary public features/properties.
Where do I start?
This depends on the environment you will be building the JavaScript in, each comes with it’s own set of tools to help you get the job done.
If you are building a node application or module you will make use of node’s require() method and module.exports syntax to construct a facade.
If you are building a web application or module using requirejs you will use define() and require() to build your facade, or if you are using es6 syntax you will be using the import and export statements.
For all the following examples we will be creating a module with the following structure (A clock/timer utility module within an existing application).
src/
...
utilities/
...
chronos/
clock
clock.js
hour-hand.js
minute-hand.js
second-hand.js
utilities.js
timer
digit.js
timer.js
utilities.jsFrom this we can see that the end-user (or developer) of this module will be interested in the clock.js and timer.js files, these are the main entry points into our Chronos module. The rest needs to be hidden away behind our facade to create less confusion and make our new module simple to consume.
Okay, let’s build that facade
Now that we know which parts of our module need exposed, let’s use the facade pattern to do so.
node
To define a module in node we are going to use module.exports. Please take note that node supports varying degrees of es6, please check the feature support table for information on which version to use, depending on your node version.
/src/utilities/chronos/index.js (New file — es6)
const clock = require('./clock/clock.js');
const timer = require('./timer/timer.js');module.exports = { clock, timer };
/src/utilities/chronos/index.js (New file — es5)
var clock = require('./clock/clock.js');
var timer = require('./timer/timer.js');module.exports = {
clock: clock,
timer: timer,
};
Now you can use this module in any other part of your application with node’s require() method.
another/place/in-the-application.jsx (es6)
const { clock, timer } = require('./utilities/chronos');const clockInstance = new clock();
const timerInstance = new timer();
another/place/in-the-application.jsx (es5)
var chronos = require('./utilities/chronos');var clockInstance = new chronos.clock();
var timerInstance = new chronos.timer();
requirejs
To export a module using requirejs we will make use of the define() method.
/src/utilities/chronos/index.js (New file — es6)
define([
'utilities/chronos/clock/clock.js',
'utilities/chronos/timer/timer.js'
],
(clock, timer) => ({ clock, timer }));/src/utilities/chronos/index.js (New file — es5)
define([
'utilities/chronos/clock/clock.js',
'utilities/chronos/timer/timer.js'
],
function (clock, timer) {
return { clock: clock, timer: timer };
});Now our module can be used in another part of our application simply by requiring it.
another/place/in-the-application.jsx (es6)
require([
'utilities/chronos/index.js'
],
(chronos) => {
const clockInstance = new chronos.clock();
const timerInstance = new chronos.timer();
});another/place/in-the-application.jsx (es5)
require([
'utilities/chronos/index.js'
],
function (chronos) {
var clockInstance = new chronos.clock();
var timerInstance = new chronos.timer();
});Pure es6/es2015
To export a part of our es6 module we are going to make use of the export syntax.
/src/utilities/chronos/index.js (New file)
export clock from './clock/clock';
export timer from './timer/timer';Now we can use our module with the import syntax.
another/place/in-the-application.jsx
import { clock, timer } from 'utilities/chronos';const clockInstance = new clock();
const timerInstance = new timer();
So simple
With this knowledge sharing modules/libraries should be even easier than before.