You can use augmentation to separate your modules out in to different files. Once you are ready for a production release, you can concatenate those files into one or several files.
File1 defines module M.n
var M = M || {};
M.n = M.n || {};
(function (self) {
self.doSomething = function () {
console.log("something");
};
})(M.n);
File2 defines module M.n.p
var M = M || {};
M.n = M.n || {};
M.n.p = M.n.p || {};
(function (self) {
self.doSomethingElse = function () {
console.log("something else");
};
})(M.n.p);
Now in your "main" script you can freely use the members of these modules.
M.n.doSomething();
M.n.p.doSomethingElse();
Defining the modules can be a little tedious, but you should be able to whip something up to automate it. In the past, I've used this little script to help make it easier, but feel free to make your own. You may even be able to bake in dependency management with consistent file naming.
var namespace = function(path, context, args) {
var finalLink = namespace._generateChain(path, window);
context.apply(finalLink, [finalLink].concat(args));
};
namespace._generateChain = function(path, root) {
var segments = path.split('.'),
cursor = root,
segment;
for (var i = 0; i < segments.length; ++i) {
segment = segments[i];
cursor = cursor[segment] = cursor[segment] || {};
}
return cursor;
};
To use:
namespace("M.n.p", function (self) {
self.doSomethingElse = function () {
console.log("something else");
};
});
If for some reason you want to include a variable under a different alias, you can pass it to the namespace function and it will be passed to the function as an argument.
namespace("M.n.p", function (self, $) {
self.doSomethingElse = function () {
$("p").text("something else");
};
}, jQuery);