Created
June 23, 2016 08:49
-
-
Save anaisbetts/6fb2871fcb6e1b0d8bac761b156ee7df to your computer and use it in GitHub Desktop.
A failed attempt to make a lazy require
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const emptyFunc = () => {}; | |
emptyFunc.prototype = {}; | |
// On initial call, we just return the proxy | |
// On next tick or >1 call, we make getters call require | |
// Until then getters have to create a proxy too | |
// | |
// cases: | |
// require('foo')(); | |
// const {foo} = require('bar'); | |
// const baz = require('baz'); | |
class DelayedProxyHandler { | |
constructor(factory) { | |
this.factory = factory; | |
this.shouldReturnProxy = true; | |
process.nextTick(() => this.shouldReturnProxy = false); | |
} | |
getOrCreateBackingObject() { | |
if (this.factory) { | |
this.value = this.factory(); | |
this.factory = null; | |
} | |
return this.value; | |
} | |
get(target, property) { | |
if (!this.shouldReturnProxy) { | |
let backing = this.getOrCreateBackingObject(); | |
if (property !== 'default') return backing[property]; | |
if (!(property in backing)) return backing; | |
return backing[property]; | |
} | |
if (property === Symbol.toPrimitive) return undefined; | |
this.shouldReturnProxy = false; | |
let handler = new DelayedProxyHandler(() => this.getOrCreateBackingObject()[property]); | |
handler.shouldReturnProxy = false; | |
return new Proxy(emptyFunc, handler); | |
} | |
/* | |
* Boring methods that just return the real object | |
*/ | |
getPrototypeOf() { | |
return Object.getPrototypeOf(this.getOrCreateBackingObject()); | |
} | |
setPrototypeOf(target, proto) { | |
return Object.setPrototypeOf(this.getOrCreateBackingObject(), proto); | |
} | |
isExtensible() { | |
return Object.isExtensible(this.getOrCreateBackingObject()); | |
} | |
preventExtensions() { | |
return Object.preventExtensions(this.getOrCreateBackingObject()); | |
} | |
/* | |
getOwnPropertyDescriptor(target, prop) { | |
return Object.getOwnPropertyDescriptor(this.getOrCreateBackingObject(), prop); | |
} | |
defineProperty(target, prop, desc) { | |
return Object.defineProperty(this.getOrCreateBackingObject(), prop, desc); | |
} | |
*/ | |
has(target, prop) { | |
return prop in this.getOrCreateBackingObject(); | |
} | |
set(target, prop, val) { | |
this.getOrCreateBackingObject()[prop] = val; | |
} | |
deleteProperty(target, prop) { | |
delete this.getOrCreateBackingObject()[prop]; | |
} | |
ownKeys() { | |
return Object.getOwnPropertyNames(this.getOrCreateBackingObject()); | |
} | |
apply(target, thisArg, args) { | |
let ret = this.getOrCreateBackingObject(); | |
return ret.apply(thisArg, args); | |
} | |
construct(target, args) { | |
console.log("Constructing!"); | |
let Ctor = this.getOrCreateBackingObject(); | |
return new (Function.prototype.bind.apply(Ctor, args)); | |
} | |
} | |
module.exports = function(origRequire) { | |
let ret = function() { | |
let origArgs = arguments; | |
let that = this; | |
let handler = new DelayedProxyHandler(function() { return origRequire.apply(that, origArgs); }); | |
return new Proxy(emptyFunc, handler); | |
} | |
Object.keys(origRequire).forEach((k) => ret[k] = origRequire[k]); | |
return ret; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const origRequire = global.require; | |
const Module = origRequire('module'); | |
const origPrototypeRequire = Module.prototype.require; | |
let lazify = require('./deferred-require'); | |
let lazyRequire = lazify(origRequire); | |
global.require = function() { | |
if (arguments[0].match(/_global$/)) { | |
return global; | |
} | |
return lazyRequire.apply(this, arguments); | |
}; | |
global.eagerRequire = origRequire; | |
lazyModuleRequire = lazify(origPrototypeRequire); | |
Module.prototype.require = function() { | |
if (arguments[0].match(/_global$/)) { | |
return global; | |
} | |
return lazyModuleRequire.apply(this, arguments); | |
}; | |
module.exports = global.require; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment