On Github kwiniarski / javascript-modules
Improving maintainability with style guidelines
Maintainable code is:
When you establish coding and naming conventionsstick to them!
Ideally code should look as if it was written by the same person.
Avoid complexity and stick to the programing principles
KISS, DRY, YAGNI, loose coupling, separation of concerns, open/closed, single responsibility, IoC
In JavaScript you have to think asynchronous
so it will be better if you are familiar with events, callbacks & promises
Some of those principles come together, creating design patterns, like for example SOLID:Why I see you are all embraced?
One of the most important habits, yet hardest to follow.
Embraced again?
TDD, BDD... No mater how you name it. What is important you will always write code you only need. Unit test will also warn anyone who will try to brake your implementation.
Improving maintainability with modules
but we can do this:
In JavaScript functions are first-class citizens and we can make strong use of it.
What is it, does anybody know? First-class citizen is an entity which supports all the operations generally available to other entities. These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.var myCart = { totalAmount: 0, items: [], placeholder: document.getElementById('#cart'), addItem: function (item) { this.items.push(item); this.totalAmount += item.price; } };
Lets add closure concept to the object notation.
var myCart = function () { var totalAmount = 0, items = [], placeholder = document.getElementById('#cart'); return { addItem: function (item) { items.push(item); totalAmount += item.price; }, total: function () { return totalAmount; } }; };
But what about dependencies?
var myCart = (function ($) { return function cart() { var totalAmount = 0, items = [], placeholder = $('#cart'); return { addItem: function (item) { items.push(item); totalAmount += item.price; }, total: function () { return totalAmount; } }; }; })(jQuery);
How about automatic dependency resolution?
Impossible without additional tools.
Modules/1.0
var $ = require('jquery'); module.exports = function cart() { var totalAmount = 0, items = [], placeholder = $('#cart'); var prototype = { addItem: function (item) { items.push(item); totalAmount += item.price; }, total: function () { return totalAmount; } }; return Object.create(prototype); };
What about browser?
Modules/AsynchronousDefinition
Not a CommonJS project anymoredefine('myCart', ['jQuery'], function ($) { return function cart() { var totalAmount = 0, items = [], placeholder = $('#cart'); var prototype = { addItem: function (item) { items.push(item); totalAmount += item.price; }, total: function () { return totalAmount; } }; return Object.create(prototype); }; });app.js
require(['myCart'], function (myCart) { var cart = myCart(); cart.addItem({price: 5}); });
(function (root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports !== 'undefined') { module.exports = factory(); } })(this, function () { return function cart () { // module body }; });
This will work in Node.js and in the browser(with RequireJS for example).
module Cart { import something from otherModule var internalData; function internalFunction() {} export function addItem(item) {} export function total() {} }app.js
import {addItem, total} from Cart; addItem({ptice: 5});
Proposed solution is not compatible with currently adopted solutions like CommonJS or AMD.
Improve maintainability with automation
npm install -g requirejs
node r.js name=main out=main.js
Thank you for your attention!