Sharing is Caring: Using JavaScript on the Frontend and the Backend
Sharing is Caring: Using JavaScript on the Frontend and the Backend
A major benefit of using a shared language on the browser and the server is a smaller amount of duplicate code in your codebase. Let’s assume you want to be able to share the file shared.js
between the client and the server:
On the server
var shared = require('./shared');
console.log(shared.hello());
On the browser
<script src="shared.js"></script>
<script>
console.log(shared.hello());
</script>
There are a number of libraries that can be used to facilitate this type of sharing including RequireJS, gemini, or node-browserify. If you’re looking to stay away from libraries here are two patterns for creating sharable JavaScript files that can be used on both the client and the server.
Lightweight Solution
From Piler, the quickest pattern is a closure that mimics the exports
functionality of Node in the browser.
(function (exports) {
exports.hello = function () {
return 'Hello World';
};
}(typeof exports === 'undefined' ? this.shared = {} : exports));
For use in your own code be sure to change shared
to the name of your JavsScript file.
Heavyweight Solution
For a pattern that will support a wide range of environments, including CommonJS and the old Node.js require()
method, use the following (from Underscore.js):
(function () {
// Establish the root object, `window` in the browser,
// or `exports` on the server.
var root = this;
// Create a safe reference to the shared object for use below.
var shared = function (obj) {
if (obj instanceof shared) {
return obj;
}
if (!(this instanceof shared)) {
return new shared(obj);
}
this.sharedwrapped = obj;
};
// Export the shared object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `shared` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = shared;
}
exports.shared = shared;
}
else {
root.shared = shared;
}
shared.hello = function () {
return 'Hello World';
};
}).call(this);
Again, you’ll want to replace s/shared/yourFileName/g
in your own codebase.