deferred-require
Advanced tools
Comparing version 0.3.0 to 0.4.0
(function() { | ||
var Module, RequireHandler, RequireTarget, originalRequire; | ||
var Module, RequireProxyHandler, RequireProxyTarget; | ||
@@ -8,48 +8,36 @@ require('harmony-reflect'); | ||
originalRequire = Module.prototype.require; | ||
module.exports = function(parentPath, errorHandler) { | ||
var module; | ||
try { | ||
Module.prototype.require = function(path) { | ||
return Proxy(new RequireTarget(this, path, errorHandler), RequireHandler); | ||
}; | ||
module = originalRequire.call(module, parentPath); | ||
} finally { | ||
Module.prototype.require = originalRequire; | ||
} | ||
return module; | ||
module.exports = function(path, errorHandler) { | ||
var target; | ||
target = new Function; | ||
target.path = path; | ||
target.errorHandler = errorHandler; | ||
target.__proto__ = RequireProxyTarget; | ||
return Proxy(target, RequireProxyHandler); | ||
}; | ||
RequireTarget = (function() { | ||
function RequireTarget(parentModule, path, errorHandler) { | ||
this.parentModule = parentModule; | ||
this.path = path; | ||
this.errorHandler = errorHandler; | ||
} | ||
RequireTarget.prototype.getModule = function() { | ||
RequireProxyTarget = { | ||
getModule: function() { | ||
return this.module != null ? this.module : this.module = this.requireModule(); | ||
}; | ||
RequireTarget.prototype.requireModule = function() { | ||
var e; | ||
}, | ||
requireModule: function() { | ||
var error, handlerResult; | ||
if (this.errorHandler != null) { | ||
try { | ||
return originalRequire.call(this.parentModule, this.path); | ||
return Module.prototype.require.call(module.parent, this.path); | ||
} catch (_error) { | ||
e = _error; | ||
this.errorHandler(e); | ||
return {}; | ||
error = _error; | ||
handlerResult = this.errorHandler(error); | ||
if (typeof handlerResult === 'object') { | ||
return handlerResult; | ||
} else { | ||
return {}; | ||
} | ||
} | ||
} else { | ||
return originalRequire.call(this.parentModule, this.path); | ||
return Module.prototype.require.call(module.parent, this.path); | ||
} | ||
}; | ||
} | ||
}; | ||
return RequireTarget; | ||
})(); | ||
RequireHandler = { | ||
RequireProxyHandler = { | ||
get: function(target, name, receiver) { | ||
@@ -56,0 +44,0 @@ return Reflect.get(target.getModule(), name, receiver); |
{ | ||
"name": "deferred-require", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "A require function that defers actual reads until the first use of the required object", | ||
@@ -5,0 +5,0 @@ "main": "./lib/deferred-require", |
# Deferred Require | ||
To use, run node with the `--harmony_proxies` and `--harmony_collections` flags. | ||
**Using this module requires that you run node with the `--harmony_proxies` and | ||
`--harmony_collections` flags.** | ||
This npm exports a single top-level function. When called with a path, this | ||
function will require the file at the given path as usual, but any `require` | ||
calls *within* that file will return a special deferred objects that delay | ||
actually requiring anything until the required object is used. | ||
## Basic Example | ||
```coffee | ||
# file-1.coffee | ||
deferredRequire = require 'deferredRequire' | ||
foo = deferredRequire('./file-2') | ||
deferredRequire = require 'deferred-require' | ||
myHugeModule = require 'my-huge-module' | ||
# actually performs the requires in file-2 because of usage | ||
foo() | ||
``` | ||
# ... some time later ... | ||
```coffee | ||
# file-2.coffee | ||
bar = require 'huge-expensive-require' | ||
module.exports = -> bar() + 1 | ||
myHugeModule.doSomething() # the module isn't loaded and required until here | ||
``` | ||
In `file-2`, we require `huge-expensive-require`, but we don't use its exports | ||
immediately. Because `file-2` is required with `deferredRequire`, we won't | ||
actually perform the expensive require until it is used in file-1. | ||
This npm exports a single top-level function, `deferredRequire`, which you can | ||
use just as you would use node's global `require` function. When you require a | ||
module with `deferredRequire`, no code is actually loaded or evaluated until | ||
the module you require is first used. This is achieved through the magic of | ||
harmony proxies. | ||
## Error Handling | ||
Normally, if a required module throws an exception as it's being required it | ||
can be caught by the code doing the requiring. With deferred-require, the | ||
exception might not get thrown until the object is first used. If you want to | ||
catch these exceptions, pass an error handler function to `deferredRequire`. | ||
```coffee | ||
# file-1.coffee | ||
deferredRequire = require 'deferred-require' | ||
deferredRequire './file-2', (error) -> console.warn("Error", e.stack) | ||
``` | ||
```coffee | ||
# file-2.coffee | ||
bar = require 'exception-throwing-module' | ||
module.exports = -> bar() + 1 | ||
``` | ||
## Caveats | ||
This is achieved via ES6 harmony proxies. If your top-level require is an | ||
irregular object such as an array, a Date object, or host object, you may | ||
encounter instability until V8 fully supports these kinds of objects. | ||
Warning: Because of instability in the v8 proxy implementation when combined | ||
with "exotic objects" like arrays, strings, and dates, you should only use | ||
`deferredRequire` with modules that export regular objects or functions as their | ||
top-level module. This is true of almost every npm module, so in practice this | ||
shouldn't be a big issue. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5353
104
26
1