bahmutov / really-need Goto Github PK
View Code? Open in Web Editor NEWNode require wrapper with options for cache busting, pre- and post-processing
License: MIT License
Node require wrapper with options for cache busting, pre- and post-processing
License: MIT License
Hello, thanks a lot for this library.
I am evaluating it to see if I could use for a mutation testing library I am writing, I've setup a basic scenario to see how it works:
// source.js
var lib = {};
lib.fn = function() {
return true;
};
module.exports = lib;
// test.js
describe('fn', function() {
var lib = require('./source'),
expect = require('chai').expect;
it('returns true', function() {
expect(lib.fn()).to.be.true;
});
});
// runner.js
require = require('really-need');
var foo = require('./test', {
pre: function (source, filename) {
return source;
}
});
When I run it it gives me an error, it's quite long, I'll paste what I think it's relevant (here the whole thing https://gist.github.com/lazywithclass/93898774a3644be63c32)
patched compile has crashed
internalModule is not defined
ReferenceError: internalModule is not defined
at Module.eval (eval at <anonymous> (/Users/lazywithclass/workspace/mutagen/node_modules/really-need/index.js:230:25), <anonymous>:30:19)
at Module._compile (/Users/lazywithclass/workspace/mutagen/node_modules/really-need/index.js:251:29)
at load (/Users/lazywithclass/workspace/mutagen/node_modules/really-need/index.js:73:12)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at loadRealModule (/Users/lazywithclass/workspace/mutagen/node_modules/really-need/index.js:133:23)
at Module.reallyNeedRequire [as require] (/Users/lazywithclass/workspace/mutagen/node_modules/really-need/index.js:181:16)
at Object.<anonymous> (/Users/lazywithclass/workspace/mutagen/test/mutation-true-false/mutator.js:24:11)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
I am running node 4.3.1and really-need 1.9.2.
Any hint / help would be greatly appreciated.
UPDATE: Using node 4.2.2 and fake
seems to solve the issue... but still I am looking at your code to understand how can I use it with newer versions.
I'm thinking about ways one might incorporate ramda-t in development process without too much hassle.
One of those I've considered is conditionally overwriting require in non-production environment so that if you require('ramda')
instead of vanilla Ramda you'd get ramda-t
.
In order for this to be a feasible approach, the require
overwrite should only apply to the project's own files.
I know based on the README that really-need
can be used to overwrite require
in the way I described, but I also understood that it would apply to global scope and affecting all dependencies as well.
Looking for a way to pass default options, applied to all require invocations (unless overridden by per-invocation options). So, I'd like to do things like this:
require = require('really-need')({... some default options...})
and then later on, in any given module:
var mymodule = require("mymodule")
where since I haven't supplied an options object, the defaults specified when I required really-need would be used.
great project btw, very innovative.
Overwrite wrap string
With fake filename that does not resolve to anything.
require.cache['fake name'] = 'hi';
// somehow fake Function.Module._resolveFilename to accept loading 'fake name'
// the value is already in the cache
bust
- remove copy from cache before loading (false by default)
cache
(true by default) - remove copy from cache after loading
jshint / eslint / jscs, take settings from next-updater
Seems we do not give access to the underlying cache object
require = require('really-need');
Object.keys(require.cache).forEach(function (name) {
delete require.cache[name];
});
TypeError: Object.keys called on non-object
Hello, awesome module!
I have a requirement and wanted to check in with you before making a pr. Would you be willing to have the pre function below also accept a promise as its return value?
pre: function (source, filename) {
// transform the source before compiling it
return source;
},
Describe-it https://github.com/bahmutov/describe-it seems to try to overwrite the require again. Need to detect and avoid multiple overwrites
Use https://github.com/VictorBjelkholm/autochecker to test every available Node version
In addition to fake source, allow passing compiled code directly, objects, primitives and functions
var result = require('fake-module', {
fake: { foo: 42 }
});
// result is {foo: 42}
Instrument the loaded modules?
Should transform compiled object (exported) before putting it into the cache
var q = require('q', {
post: function (q) {
q.longStackSupport = true;
return q;
}
});
if function returns undefined
, keep original exported object.
Do not break dependencies.
I was noticing an error in my own project, so I cloned really-need and ran the tests, but am seeing errors such as this:
ReferenceError: resolvedArgv is not defined
at Module.eval (eval at (/home/sbasu/workspace-idea/really-need/index.js:115:45), :68:10)
at Module._compile (/home/sbasu/workspace-idea/really-need/index.js:127:31)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at Module.reallyNeedRequire as require
at require (module.js:380:17)
at Object. (/home/sbasu/workspace-idea/really-need/test/simple.js:8:11)
at Module._compile (module.js:456:26)
Essentially the eval'ed version of Module's _compile is failing due to the resolvedArg being undefined. As far as I can tell, the original _compile knows about this var because it's declared in the scope that _compile is. But when _compile is replaced, this isn't the case anymore looks like.
This is using Node 0.10.33, and the error above is if I just run the simple.js test.
> node some_file.js
undefined:4
content = content.replace(shebangRe, '');
^
ReferenceError: shebangRe is not defined
at Module.eval (eval at <anonymous> (/Users/some_user/some_dir/some_project/node_modules/really-need/index.js:144:45), <anonymous>:4:29)
at Module._compile (/Users/some_user/some_dir/some_project/node_modules/really-need/index.js:156:31)
at load (/Users/some_user/some_dir/some_project/node_modules/really-need/index.js:67:12)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:313:12)
at Module.reallyNeedRequire [as require] (/Users/some_user/some_dir/some_project/node_modules/really-need/index.js:105:23)
at Object.<anonymous> (/Users/some_user/some_dir/some_project/some_file.js:6:30)
at Module._compile (module.js:425:26)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
Turns out shebangRe
is pretty fresh, was introduced by Node v5.1.0
See diff here: nodejs/node@5c54fa0
Went back to Node v4.2.2 and v5.0.0 to verify, both worked fine.
Can args
have an object where the code is writing data to?
// foo.js
(function reallyPrivate() {
function getFoo() {
return 'foo';
}
if (typeof test === 'object') {
// pass data outside
test.exported.getFoo = getFoo;
}
}());
from outside we could
// test.js
require = require('really-need');
var myObject = {};
require('./add.js', {
args: {
test: {
exported: myObject
}
}
});
// hope that myObject.getFoo = getFoo from foo.js
Separate npm module, then add .dont-break
to really-need
See https://gist.github.com/adammcarth/5490b7cb77fc2c1eae42
from https://gist.github.com/adammcarth
// route_tests.js
module.exports = function(server) {
var request = require("supertest");
it("[GET] /", function(done) {
request(server).get("/").expect(200, done);
});
it("[GET] /posts", function(done) {
request(server).get("/posts").expect(200, done);
});
}
// run.js
// Runs the my-app testing suite
var require = require("really-need");
describe("Running all My App tests:", function() {
var server;
beforeEach(function () {
server = require("../server/server.js", { bustCache: true });
});
afterEach(function (done) {
server.close(done);
});
describe("Check that all public routes are responding...",
require("route_tests.js")(server));
});
with good commit message validation
print to console messages if require('really-need', { debug: true });
Functions that aren't defined as top-level properties of args
are not making through to the loaded module source. So for example, this works fine:
// another-require.js
require('something');
// index.js
require = require('really-need');
require('./another-require', {
args: {
require: function (name) {
console.log('no requires allowed');
}
}
});
// prints "no requires allowed"
... but this doesn't:
// stuff-with-lodash.js
console.log( _.yam );
_.filter();
// index.js
require = require('really-need');
require('./stuff-with-lodash', {
args: {
_: {
'yam': 678,
'filter': function () {
console.log('look! a fake lodash filter!');
}
}
}
});
// prints:
// 678
// _.filter is not a function
I already hacked together something that works using a dusty gist by @cowboy but I'm not in love with it.
Let me know if this is something you think worth looking into.
How really-need
differs from proxyquire
?
They seem to be really similar in features. Any pros/cons using really-need
over proxyquire
?
Keep cache
as an alias
Seems the internal code has changed. Need to at least allow some features to work, like busting the require cache
Probably don't need iojs but need node 4 and 5
Should transform loaded source code before compiling it
For example when loading one module from another, can we set parent
to undefined?
// first.js
require('./second');
// second.js
console.log(module.parent); // prints first.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.