Is it possible to replace or alias core modules in Node.js? - node.js

I'm currently working on a project where one of the core Node.js modules (dns) does not behave the way I need it to. I've found a module that seems like it would work as a replacement: https://github.com/tjfontaine/node-dns. However, the code using the DNS module is several layers down from the application code I've written. I'm using the Request module (https://github.com/mikeal/request) which makes HTTP requests and uses several core modules to do so. The Request module does not seem to be using the DNS module directly, but I'm assuming one of those core modules is calling the DNS module.
Is there a way I can tell Node to use https://github.com/tjfontaine/node-dns whenever require('dns') is called?

Yes and you should not,
require.cache is a dangerous thing, extremely. It can cause memory leaks if you do not know what you are doing and cache mismatch which is potentially worse. Most requests to change core modules can also result in unintentional side effects (such as discoverability failures with DNS).
You can create a user-space require with something like : https://github.com/bmeck/node-module-system ; however, this faces the same dangers but is not directly tied to core.
My suggestion would be to wrap your require('dns').resolve with require('async').memoize, but be aware that DNS discoverability may fall over.

For better or worse, I've implemented module white lists before doing something as demonstrated below. In your case, it ought to be possible to explicitly check for dns module name and delegate everything else to original require(). However, this implementation assumes that you have full control of when and how your own code is being executed.
var _require = constructMyOwnRequire(/*intercept 'dns' and require something else*/);
var sandbox = Object.freeze({
/* directly import all other globals like setTimeout, setInterval, etc.. */
require : Object.freeze(_require)
});
try {
vm.runInContext(YOUR_SCRIPT, Object.freeze(vm.createContext(sandbox)));
} catch (exception) {
/* stuff */
}

Not really.
require is a core var which is local to each module, so you can't stub it, because Node will give the untouched require var to the loaded module.
You could run those things using the vm module. However, you would have to write too much code to do a "simple workaround" (give all needed variables to the request module, stub the needed ones to work properly, etc, etc...).

Related

How to run javascript outside of router function in Foxx

I would like to do some variable toggling for dev and prod production but it seemed like If..else does not run outside of router code. Am I doing something wrong?
//Other variable declare above
//This one wont run
if(isDev){
coll=db._collection("DevColl")
}
else{
coll=db._collection("ProdColl");
}
//////////////////////////////////
//Later use coll in the router code
router.get("/"),function{
}
Please note that ArangoDB starts several Javascript V8 contexts (they call this "Isolate") while NodeJS just has one.
During the lifecycle of ArangoDB new Isolates may be spawned, and old ones flushed. Global objects in Isolates that are not being referenced may be removed to save memory.
Thus there is no direct way to have global setting inside of javascript.
However, there are three possible ways to achieve this:
A collection that can switch the state (may be slow in production too...)
using the system environment via process.env which you then would have to set in the initscripts starting ArangoDB.
install another instance of your foxx service, access the collections via module.context.collection()

Shim config not supported in Node, may or may not work

I am working on a project which works fine on browser , now we are trying to run it on server side using nodejs.
I have below configurations :
node : v4.2.1
npm : v2.14.7
and when I am trying to run my project on nodejs , getting the error as :
Shim config not supported in Node, may or may not work
Since the modules and dependencies (AMD) are working fine on browser I assume the shims config are correct .
Please let me know if I am missing something ?
https://github.com/jrburke/requirejs/issues/1443
Regards
Manish
Since the modules and dependencies (AMD) are working fine on browser I assume the shims config are correct .
That's an incorrect assumption. The problem is that Node.js operates with a set of basic assumptions that are very different from how browsers work. Consider this statement:
var foo = "something";
If you execute this at the top of your scope in Node.js, you've created a variable which is local to the file Node is executing. If you really want to make it global, then you have to explicitly shove it into global.
Now, put the same statement at the top of the scope of a script you load in a browser with the script element. The same statement creates a global variable. (The variable is global whether or not var is present.)
RequireJS' shim configuration is used for scripts that expect the second behavior. They expect a) that anything they declare at the top of their scope is leaked to the global space and b) that anything that has been leaked to the global space by scripts they depend on is available in the global space. Both expectations are almost always false in Node. (It would not be impossible for a module designed for node to manipulate global but that's very rare.)
The author of RequireJS explained in this issue report that he does not see it advisable for RequireJS to try to replicate the browser behavior in Node. I agree with him. If you want to run front-end code in the back-end you should replace those modules that need shim in the browser with modules that are designed to run in Node.

Mocking Repository but Then Swapping Out for Real Implementation in Node.js

I'm building a Repository layer with higher level API for my abstractions above to make calls to the database persistence. But since JavaScript doesn't have the concept of Interfaces like a language such as C# or Java does, how do you swap out the mock for the real implementation?
I prefer creating custom mocks, node repository modules with data persitence high level methods in them vs. Sinon.js or something like that.
If I'm creating node modules, then how? I could send in a mock representation of the repository where I mock out what the repository methods are doing but then the actual node modules using those repository modules would need to use the real repository implementation that calls the real database. How is this done in Node? I want to just inject via a property, I don't want some gigantic injection IoC framework either.
Since there's no concept of an interface then wtf do you do in Node/JS? I have to create a data layer below the repository (whether it be a custom set of modules making real query calls to Postgres or whether I'm using Mongoose or whatever it may be, I need a DL set of modules that the repository calls for tis real DB calls under the hood).
And lets say I do choose to use some framework like Sinon.js, what's the common interface for the module you're mocking that can be shared by the mocking framework and the real module?
There's more than one way to do it. If you come from a different background it may take some getting used to Node.
You can do this:
module.exports = function(db) {
this.db = db;
this.myQuery = function(n, cb) {
this.db.query(n, cb);
}
}
Then in config.js
var exports.db = require('./mydb');
Then
var config = require('./config.js');
var db = require('./db')(config.db);
There are lots of variations possible. You could do a dynamic require somewhere based on a string or something. Or use classes or init functions. Most are going to probably end up being similar.
The proxyrequire module could be helpful. So can Sinon.js.
Since there really isn't type checking people generally are verifying that with their tests at runtime. If you are really doing TDD it might not make a huge difference.

Grunt task to optionally include an AMD module for different environment

I'm developing a web app using Require.js for AMD and amplify.request to abstract away my AJAX calls. The other advantage to amplify.request is that I've defined an alternative module containing mocked versions of my requests that I can use for testing purposes. Currently, I'm switching between the two versions of my request module by simply commenting/un-commenting the module reference in my main.js file.
What I'd love to do is use Grunt to create different builds of my app depending on which module I wanted included. I could also use it to do things like turn my debug mode on or off. I'm picturing something similar to usemin, only for references inside JavaScript, not HTML.
Anyone know of a plugin that does this, or have a suggestion about how I could do it with Grunt?
On our current project we have a few different environments. For each of them, we can specify different configuration settings for the requirejs build.
To distinguish between these different environments, I've used a parameter target.
You can simply pass this to grunt by appending it to your call like
grunt --target=debug
And you can access this parameter in the Gruntfile, by using grunt.option, like
var target = (grunt.option('target') || 'debug').toLowerCase();
The line above will default to debug. You could then make use of the paths configuration setting of requirejs to point the build to the correct module. Example code below.
requirejs: {
compile: {
options: {
paths: {
"your/path/to/amplify/request": target === "debug" ? "path/to/mock" : "path/to/real",
}
}
}
}

is require.js the right tool (for the job) for "normal" web sites"

I have started building a web site and have used Require.js for selectively loading scripts which I require to implement functionality. What I am experiencing is:
the "main" script has not finished executing (or even downloading) before some of my code uses "require" to load dependencies. What this means is that the require.js config has not run and does not know the locations of my scripts.
because the require.js config has not run by the time my code needs to use it, the "shim" mechanism has not been initialised and cannot be used.
The Common Errors page along with a lot of the issues I seem to be reading about online while trying to solve my own problems seem to suggest that this is not the right tool for the job.
This seems to be useful for single page applications or node.js applications, but not traditional sites where other scripts could be running before require.js has been initialised.
If require.js is not the right tool for the job, is there a right tool for this job? If so then what is?
Are you loading the require.js script asynchronously (with an async='async')? You want requirejs to load synchronously. Once it's loaded, it will load further scripts, like your main.js file, asynchronously. They may all load out of order, but the code will actually get executed in the right order (respecting the declared dependencies).
So in your page template, you would have this:
<script src="/Scripts/require.js" type="text/javascript" data-main="main.js"></script>
That will load RequireJS, and once it's loaded it starts loading your main.js asynchronously. Typically main.js does not define any modules, it just makes use of modules defined in other files. These dependencies are listed in the require() call:
require(["moduleA", "moduleB"], function(A, B){
// Do something with A and B
A.someFunction();
B.someOtherFunction();
});
The files moduleA.js and moduleB.js must wrap their contents inside a define(). In moduleA.js (which depends on module C):
define(["moduleC"], function () {
// Build up an A
var A = ....;
return A;
});
I wonder now if you're wrapping your modules in a define call. Not doing that could explain the out-of-order execution you're experiencing.
RequireJS is a perfectly valid tool on a traditional site, not just on a single-page site.

Resources