Skip to content

Instantly share code, notes, and snippets.

@kwhinnery
Created July 19, 2011 22:52
Show Gist options
  • Save kwhinnery/1093947 to your computer and use it in GitHub Desktop.
Save kwhinnery/1093947 to your computer and use it in GitHub Desktop.
Monkey patch for require in Titanium Mobile
/*
add a monkey-patched "require" function to the global scope (global object).
It is smarter in two ways:
- It only loads a module once
- If the exports object contains a function matching the module base name, return that
value from "require" - this is a bit of sugar added because Titanium's require implementation
does not allow you to replace the "exports" object directly
*/
//monkey patch "require" in the global scope
require('require_patch').monkeypatch(this);
//regular modules are the same...
var module = require('module');
module.sayHello('Marshall');
module.sayGoodbye('Kevin');
//modules which contain a type by the same name as the module...
var Person = require('Person');
var jedi = new Person('Luke','Skywalker');
exports.sayHello = function(name) {
alert('Hello '+name+'!');
};
exports.sayGoodbye = function(name) {
alert('Goodbye '+name+'!');
};
exports.Person = function(firstName,lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
exports.monkeypatch = function(object) {
var scriptRegistry = {},
old_require = object.require;
object.require = function(moduleName) {
if (!scriptRegistry[moduleName]) {
var mod = old_require(moduleName),
moduleRoot = moduleName.split(/[\/ ]+/).pop();
if (typeof(mod[moduleRoot]) === 'function') {
scriptRegistry[moduleName] = mod[moduleRoot];
}
else {
scriptRegistry[moduleName] = mod;
}
}
return scriptRegistry[moduleName];
};
};
@pec1985
Copy link

pec1985 commented Aug 19, 2011

Hi Kevin, could you provide a couple lines of code on how to use this? I think it could be extremely useful for people to see.

For example, inside a click event...

Thanks!

Pedro

@motionharvest
Copy link

Hey Keven, Why do you only check of mod[moduleRoot] is a function? I've modified my own to also set scriptRegistry[moduleName] to mod[moduleRoot] if typeof(mod[moduleRoot]) is an Object. Can you fill me in on why Objects aren't included? I assume there's a good reason, and I'd prefer not to learn the hard way in 6 weeks when my app explodes.

@kwhinnery
Copy link
Author

This should no longer be needed post 1.8. the reason I did it is because pre-1.8, module.exports could not be set to an object value. That meant you couldn't do:

function MyObject() {}
MyObject.prototype.sayHello = function(name) { alert('Hello '+name); };
module.exports = MyObject;

Paired with a naming convention on the file, you could give the appearance of an instantiable object as the public API of the module. But again, this is no longer needed since module.exports is supported and modules are cached since 1.8

@motionharvest
Copy link

o_O
uh. That's completely different than what it fixes in my code. Removing the monkeyPatch breaks all sorts of stuff in my app on 2.0.2.GA
Looks like I've got some homework to do. Thanks for the response.

EDIT:
After looking at https://gist.github.com/2920512 i think i get it. I'll play around with it.

EDIT 2:
Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment