infuser
Inject code before or after required modules, or translate the module source altogether.
Last updated 6 years ago by bluejeansandrain .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install infuser 
SYNC missed versions from official npm registry.

infuser

Inject code before or after required modules, translate the module source altogether, or modify the module object before or after the module is compiled.

Useful for unit testing, dependency injection, transpiling, debugging, etc.

Core modules and modules that have already been required and cached before an API method is called, will not be affected.

Installation

npm install infuser --save

Usage

Infuser actually provides three API instances: global, local, and safe.

var infuser = require('infuser');

infuser.global.<method>;
infuser.local.<method>;
infuser.safe.<method>;
  • global methods will affect all modules that have not already been loaded and cached.
  • local methods will only affect modules in the current path or a descendent path.
  • safe methods will only affect modules in the current path or a descendent path, and only if the relative path does not include a "node_modules" directory.

This instances are not actually created until accessed (using getter properties). They can be overridden by assigning over them. Deleting them will restore them to their original instances.

Each of these API instances has the following methods.

  • translate
  • define
  • prepend
  • append
  • before
  • after

The API class is also exposed as infuser.Api. It is the class of all three predefined APIs.

translate

Modify or replace the source of a module before it's compiled.

.translate( callback( module, source, callbackPath, [arg...] ), [arg...] )

The callback function will be passed the module object, source, the path of the module that registered the translate callback, and any additional arguments passed to the translate method. If the callback returns a string, the string becomes the new module source.

define

Create or replace module "free" variables. Module free variables are variables that are scoped to a module. For example, Node automatically creates module free variables for module, exports, and require. Using define lets you mimic this behavior.

.define( callback( module, source, callbackPath, [arg...] ), [arg...] )

The callback function will be passed the module object, source, the path of the module that registered the define callback, and any additional arguments passed to the define method. If the callback returns an object, all of the owned key/value pairs in the object will become module free variables.

The source passed to define callbacks is translated, but does not include any prepended/appended source from prepend/append callbacks yet.

Free variables created this way ARE available to prepended/appended source.

prepend/append

Inject code before or after the source of a module before it's compiled. Code injected using these methods is not affected by translation, so only JavaScript should be injected.

.prepend( callback( module, source, callbackPath, [arg...] ), [arg...] )
.append( callback( module, source, callbackPath, [arg...] ), [arg...] )

The callback function will be passed the module object, source, the path of the module that registered the prepend/append callback, and any additional arguments passed to the prepend/append method. If the callback returns a string, the string will be prepended/appended to the module's source.

The source passed to prepend/append callbacks is translated, but does not include any prepended/appended source from earlier prepend/append callbacks yet.

If the module's source includes a file level "use strict"; invocation, then the original source will be automatically wrapped in a closure so that the strict invocation does not affect the prepended/appended source.

before/after

Modify the module object before or after the module's source is compiled and run.

.before( callback( module, source, callbackPath, [arg...] ), [arg...] )
.after( callback( module, source, callbackPath, [arg...] ), [arg...] )

The callback function will be passed the module object, source, the path of the module that registered the before/after callback, and any additional arguments passed to the before/after method. The callback can modify the module object, but not replace it. The return value of the callback is ignored.

before callbacks are called first so that any changes to the module object are visible to all other callbacks. This also means the source that is passed to before callbacks is the original module source, without any infuser generated modifications.

after callbacks are called after the module has been run. Asyncronous actions within the module may still modify the module object. The source passed to after callbacks is the final compiled module source after translation, prepending, and appending.

Api class

If you want to create an API with your own rules on which modules it should affect, you can create a new instance of the infuser.Api class.

new infuser.Api( [filter( module, source, [arg...] )], [arg...] )

The filter function is optional. It will be passed the module object, source, and any additional arguments passed to the constructor. If the callback returns false (strictly compared), then any callbacks registered with the API instance will not be invoked.

How the module system is hooked

Infuser wraps a single protected method in Node's module system in order to affect the module object and source before the module is loaded. The method that is affected is 'Module.prototype._compile'. This method is not changed until the first call to an infuser method.

Node's module system is supposed to be locked. However, the _compile method is not a public one and so might be subject to change even if the public API does not change. Use Infuser at your own risk and be aware that updating Node may cause it to stop working.

Infuser will probably NOT have any effect after compiling your source into a bundle using Browserify or some other compiler. Compilers usually don't use or include the Node module system, and therefore Module.prototype._compile won't exist. It's still safe to use Infuser in a project that WILL be compiled, because it checks to make sure Module.prototype._compiler exists before hooking it. You will need to duplicate the affects of your Infuser callbacks in your compilation step.

Current Tags

  • 1.0.0                                ...           latest (6 years ago)

1 Versions

  • 1.0.0                                ...           6 years ago
Maintainers (1)
Downloads
Today 0
This Week 0
This Month 0
Last Day 0
Last Week 0
Last Month 0
Dependencies (3)
Dev Dependencies (2)

Copyright 2014 - 2016 © taobao.org |