In my ASP.NET MVC project I simply inserted <script></script>
into my views - it caused code duplications and spaghetti code.
Now, I have decided to switch to modular JS and have implemented the following mechanism:
- ALL actions are only executed through the framework and its modules - whether it is a view or object behavior, date-to-string converter or websocket connection
- every module exposes
exports
functions, which can be called by anybody, including other modules - all functions including
exports
andinit
are called within a sandboxedcontext
, which includes both objects specific for the module and objects, injected by a framework (currently, I am implementing the mechanism to "hide" / disallow non-context methods within a module)
Framework object with the only register
function:
window.kibfw = {
register: function(name, module) {
if (!name || !module.init)
throw new Error('Could not load a module ' + name);
if (name === 'register')
throw new Error('Module cannot have name "register" which is reserved');
if (this[name])
throw new Error('Module ' + name + ' is already registered.');
module.context = module.context || {};
/* Here, inject the required context objects (jQuery, libraries etc.) */
module.context.$ = window.jQuery;
module.context.kibfw = window.kibfw;
try {
module.init.apply(module.context, arguments);
} catch(e) {
throw new Error('Error during module initialization: ' + e.message + '\n' + e.stackTrace);
}
var moduleExports = (this[name] = {});
for (var exportFnName in module.exports) {
if (!module.exports.hasOwnProperty(exportFnName))
continue;
moduleExports[exportFnName] = (function (exportFn) {
return function() {
try {
exportFn.apply(module.context, arguments);
} catch (e) {
throw new Error('Module: ' + name + '. Error during method invocation: ' + e.message + '\n' + e.stackTrace);
}
};
})(module.exports[exportFnName]);
}
}
};
Example module:
kibfw.register('decorator', {
init: function () {
this.$decorateItems = this.$('input');
},
context: {
$decorateItems: undefined
},
exports: {
setColor: function (color) {
this.$decorateItems.css('color', color);
}
}
});
// Usage:
$("button").click(function() {
kibfw.decorator.setColor($(this).attr('data-color'));
});
How do you think, would it be useful and scalable?
Which problems can I stumble upon while using this approach?