Where to put "Q.longStackSupport = true"? - javascript

From the documentation of Q (the Javascript promise library):
Q.longStackSupport = true;
This feature does come with somewhat-serious performance and memory overhead, however. If you're working with lots of promises, or trying to scale a server to many users, you should probably keep it off. But in development, go for it!
I find myself always writing code like this:
var Q = require('q');
Q.longStackSupport = true;
However, if I decided to turn off longStackSupport, I would have to touch a lot of files in my code.
So, I wonder if there is a more elegant solution:
Is there a recommended pattern when including Q?
Is it sufficient to call Q.longStackSupport only once?

Yes, it is sufficient to only call it once in one place.
In init.js, or whatever your root file is, I would put
if (process.env.NODE_ENV === "development") {
Q.longStackSupport = true;
}
Then this will automatically enable it if you have the NODE_ENV environment variable set to development.
$ export NODE_ENV=development
$ node init.js

Related

Is there a performance difference if we use "global" or "require" in node module?

lets say, we have node app.js
let lib= require("./big_library.js");
...
// some logic here, using myLib //
...
global.myLib = lib;
let other= require("./other.js");
and in other.js module we have:
let lib= require("./big_library.js");
//or it's better : lib = global.myLib;
so, my question is directly with the theoretical perfromance effects. Will using global.myLib make it's performance better (accessing the library), instead of additional require in each module?
The cost of second require is the cost of looking up its internal cache to see that the module is already resolved.
But I don't think it's only about the performance. It's about the order. require is guaranteed to be executed once, when you first call it. And no matter where you first call it.
On the other hand, if you start to rely on your explicit ordering (setting the variable always preceedes its usage), sooner or later you'll be hit by this.

Ignoring specific require()s in Webpack?

I have a library interoperable with NodeJS and the Browser and both are being run through Webpack to produce the final bundle. The issue I'm running into is Webpack will rewrite all require() statements to __webpack_require__() and try to bundle the library, which doesn't work for things like fs and worker_threads. How do I make it ignore certain require()s and related mechanisms (require.resolve(), import, etc) given a specific input string?
I've read that I can use the webpack.IgnorePlugin but I'd rather not have the user have to add a special rule in their build for my library. I also couldn't get this to work myself, it still rewrote the require()s. I've also read I can do eval('require("fs")') but this seems hacky, but I'm willing to do this if it's really the best way.
Example:
//example.js
if(typeof window !== "undefined") {
//Browser
var myWorker = new Worker();
}
else {
//NodeJS
var Worker = require("worker_threads"); //I want Webpack to keep this line as-is
var myWorker = new Worker();
}
To keep a require call as-is in your code after bundling with Webpack, simply replace require with __non_webpack_require__. So your example will look like this:
if (typeof window !== "undefined") {
var myWorker = new Worker();
}
else {
var Worker = __non_webpack_require__("worker_threads");
var myWorker = new Worker();
}
This is a hidden feature of Webpack (possibly because it isn't used very often) found here that ignores require calls so they can be evaluated when the app is run instead of when it's bundled.
Note that this shouldn't be used for apps targeting the web browser since it will result in resolve being used, and web browsers don't know what resolve is. Only use it in code that targets Node.

NodeJS Fork can't get childprocess to kill

I'm running against a wall here, maybe it's just a small problem where I can't see the solution due to my inexperience with NodeJS.
Right now I'm constructing a BT device which will be controlled by a master application and I have settled for the prototyping on a Raspberry PI 3 with NodeJS using the Bleno module.
So far everything worked fine, the device gets found and I can set and get values over Bluetooth. But to separate the different "programs" which the device could execute from the Bluetooth logic (because of loops etc.) I have opted to extract these into external NodeJS files.
The idea here was to use the NodeJS fork module and control the starting and stoppping of those processes through the main process.
But herein my problems start. I can fork the different JavaScript files without problem and these get executed, but I can't get them to stop and I don't know how to fix it.
Here's the code (simplified):
var util = require('util');
var events = require('events');
var cp = require('child_process');
...
var ProgramTypeOne = {
NONE: 0,
ProgramOne: 1,
...
};
...
var currentProgram=null;
...
function BLEDevice() {
events.EventEmitter.call(this);
...
this.currentProgram=null;
...
}
util.inherits(BLELamp, events.EventEmitter);
BLELamp.prototype.setProgram = function(programType, programNumber) {
var self = this;
var result=0;
if(programType=="ProgramTypeOne "){
if(programNumber==1){
killProgram();
this.currentProgram=cp.fork('./programs/programOne');
result=1;
}else if(programNumber==2){
...
}
self.emit('ready', result);
};
...
module.exports.currentProgram = currentProgram;
...
function killProgram(){
if(this.currentProgram!=null){
this.currentProgram.kill('SIGTERM');
}
}
There seems to be a problem with the variable currentProgram which, seemingly, never gets the childprocess from the fork call.
As I have never worked extensivley with JavaScript, except some small scripts on websites, I have no idea where exactly my error lies.
I think it has something to do with the handling of class variables.
The starting point for me was the Pizza example of Bleno.
Hope the information is enough and that someone can help me out.
Thanks in advance!
Since killProgram() is a standalone function outside of the scope of BLELamp, you need to call killProgram with the correct scope by binding BLELamp as this. Using apply (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) should resolve it. The following I would expect would fix it (the only line change is the one invoking killProgram):
BLELamp.prototype.setProgram = function(programType, programNumber) {
var self = this;
var result=0;
if(programType=="ProgramTypeOne "){
if(programNumber==1){
killProgram.apply(this);
this.currentProgram=cp.fork('./programs/programOne');
result=1;
}else if(programNumber==2){
...
}
self.emit('ready', result);
};
As a side note, your code is kind of confusing because you have a standalone var currentProgram then a couple prototypes with their own bound this.currentPrograms. I would change the names to prevent confusion.

override setTimeout in require.js

we are using require.js in our project and we need to override the setTimeout in line 705 , this is the code which we need to ignore/omit somehow this setTimeout at all(I mean run over it) ,the problem that if I change it in the open source code explicit when I change version the code will be lost,How should I override this setTimout from outside only for the require.js file and keep it as long as I use this lib, is it possible to do it in elegant way in JS globally ?
https://github.com/jrburke/requirejs/blob/master/require.js
This is line 705
//If still waiting on loads, and the waiting load is something
//other than a plugin resource, or there are still outstanding
//scripts, then just try back later.
if ((!expired || usingPathFallback) && stillLoading) {
//Something is still waiting to load. Wait for it, but only
//if a timeout is not already in effect.
if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
checkLoadedTimeoutId = setTimeout(function () {
checkLoadedTimeoutId = 0;
checkLoaded();
}, 50);
}
}
FYI ,The reason that we do it is
Chrome: timeouts/interval suspended in background tabs?
You've stated your goal is to work around the throttling that Chrome performs on setTimeout for tabs that are in the background. I do not think it is a good idea to do so but if you must, then you should definitely patch RequireJS instead of messing with setTimeout globally. You said:
if I change it in the open source code explicit when I change version the code will be lost
This is true only if you do not use a sensible method to perform the change. It is possible to do it sensibly. For instance, you can use Gulp to take the require.js file installed in node_modules (after you install RequireJS with npm) and produce a patched file in build. Then you use this patched file in your application. Here is the gulpfile.js:
var gulp = require("gulp");
// Bluebird is a good implementation of promises.
var Promise = require("bluebird");
// fs-extra produces a `fs` module with additional functions like
// `ensureDirAsync` which is used below.
var fs = require("fs-extra");
// Make it so that for each the function in fs that is asynchronous
// and takes a callback (e.g. `fs.readFile`), a new function that
// returns promise is created (e.g. `fs.readFileAsync`).
Promise.promisifyAll(fs);
var to_replace =
"if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {\n\
checkLoadedTimeoutId = setTimeout(function () {\n\
checkLoadedTimeoutId = 0;\n\
checkLoaded();\n\
}, 50);";
var replace_with =
"if (isBrowser || isWebWorker) {\n\
checkLoaded();";
gulp.task("default", function () {
// Use `fs.ensureDirAsync` to make sure the build directory
// exists.
return fs.ensureDirAsync("build").then(function () {
return fs.readFileAsync("node_modules/requirejs/require.js")
.then(function (data) {
data = data.toString();
// We use the split/join idiom to a) check that we get
// the string to be replaced exactly once and b)
// replace it. First split...
var chunks = data.split(to_replace);
// Here we check that the results of splitting the
// chunk is what we expect.
if (chunks.length < 2) {
throw new Error("did not find the pattern");
}
else if (chunks.length > 2) {
throw new Error("found the pattern more than once");
}
// We found exactly one instance of the text to
// replace, go ahead. So join...
return fs.writeFileAsync("build/require.js",
chunks.join(replace_with));
});
});
});
You need to have run npm install gulp fs-extra bluebird requirejs before running it. At any rate, you can use Gulp, you can use Grunt, or you can use any other system you want to perform a build. The points are:
You have a reproducible and automated method to patch RequireJS. If you install a new version of RequireJS with npm, when you rebuild your software the patch is applied automatically, so long as the code of RequireJS does not change in a way that prevents applying the patch. See the next point for what happens if a change prevents applying the patch.
This method is more robust than overriding setTimeout at runtime. Suppose James Burke decides in a newer version of RequireJS to rename checkLoaded to checkDone and renames the associated variables (so that checkLoadedTimeoutId becomes checkDoneTimeoutId). The gulpfile above will raise an exception when you run it again because it won't find the text to be replaced. You'll have to update the text to be replaced and the replacement so that the patch works with the new version of RequireJS. The benefit here is that you get an early warning that things have changed and that you need to review the patch. You won't have a surprise late in the game, perhaps after you've already delivered a new version of your software to clients.
The methods that override setTimeout at run time will just silently fail to do their job. They'll be looking for a function that contains checkLoadedTimeoutId, which won't exist anymore in the new version. So they will just let RequireJS behave the way it does by default. The failure will be a subtle one. (I've run RequireJS with the proposed custom versions of setTimeout with a project that loads upwards of 50 modules when not optimized. I saw no discernible difference between RequireJS using the stock setTimeout and RequireJS using a custom setTimeout.)
This method does not slow down every use of setTimeout. setTimeout is used by other code than RequireJS. No matter how you cut it, adding code in a custom replacement to setTimeout that starts looking for strings in each function passed to it will make all uses of setTimeout slower.
You can override setTimeout and check if the function passed as callback contains a variable used in that function from require.js (checkLoadedTimeoutId). If yes, call function immediately, otherwise call original setTimeout function.
(function(setTimeoutCopy) {
setTimeout = function(fn, timeout) {
if (fn.toString().indexOf("checkLoadedTimeoutId") >= 0) {
return fn();
} else {
return setTimeoutCopy.apply(null, arguments);
}
};
}(setTimeout));
Note that there are multiple issues with this code. If you pass a function to setTimeout which contains checkLoadedTimeoutId, it will be executed immediately too. Also, if require.js code is minified and variables are renamed, it won't work.
To sum up, there is no good way do this. Maybe try to find a different way to achieve what you want. Also be aware that, as Madara Uchiha said:
Changing global functions and objects is almost never a good idea.
If you really need this... Try add before loading requirejs:
function isTimeoutIgnoredFunction(fn, time) {
// you should configure this condition for safety, to exclude ignoring different timeOut calls!
return time == 50 && fn.toString().indexOf('checkLoadedTimeoutId') > -1;
}
window.setTimeoutOriginal = window.setTimeout;
window.setTimeout = function(fn, time) {
if (isTimeoutIgnoredFunction(fn, time)) {
return fn(); // or return true if you don't need to call this
} else {
return window.setTimeoutOriginal.apply(this, arguments);
}
};
Should work in last Chrome, Firefox, IE if no requirejs minify provided... You need to rewrite function "isTimeoutIgnoredFunction" for browsers you support and for minified require.js file.
To see what string you can use:
console.log((function () {
checkLoadedTimeoutId = 0;
checkLoaded();
}).toString());
But in some browsers it can just something like "Function".
If you have not many setTimeout's it can be suitable solution...
Other way to achieve it is making a ajax request of the library and patch it before load the library, but you will need to have loaded a way to make the request (vanilla js or jquery...)
The next code is an example of loading requirejs and patch it with a regexp before load it in the DOM.
$(function(){
// here you can put the url of your own hosted requirejs or a url from a CDN
var requirejsUrl = 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js';
function patch(lib){
var toReplace = /if\s*\(\(isBrowser\s*\|\|\s*isWebWorker\)\s*\&\&\s*!checkLoadedTimeoutId\)\s*\{([^{}]|\{[^{}]*\})*\}/;
var by = 'if (isBrowser || isWebWorker) { checkLoaded();}';
return lib.replace(toReplace, by);
}
$.get(requirejsUrl, function(lib){
var libpatched = patch(lib);
var script=document.createElement('script');
script.innerText=libpatched;
$('body').append(script);
console.log(window.require); // requirejs patched is loaded
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

RequireJs extend module initialize begin and end

I have created a JavaScript library which can be used for logging purposes.
I also want to support the logging of requirejs.
Which functions/events of requirejs can I prototype/wrap so I can log when a module is initialized and when it is done initializing and returns the initialized object.
For instance if I call require(["obj1","obj2", "obj3"], function(obj1, obj2, obj3){}
I would like to know when requirejs begins on initializing each of the object, and I would like to know when each object is completely initialized.
I looked into the documentation/code, but could not find any usefull functions I can access from the requirejs object or the require object.
Note: I do not want to change the existing code of requirejs I wish to append functionality from the outside by either prototyping or wrapping.
What I have tried (problem is that this only accesses the begin and end of the entire batch of modules):
var oldrequire = require;
require = function (deps, callback, errback, optional) {
console.log("start");
var callbackWrapper = callback;
callbackWrapper = function () {
console.log("end");
var args = new Array();
for(var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
callback.apply(this, args);
};
oldrequire.call(this, deps, callbackWrapper, errback, optional);
};
This is a "better than nothing answer", not a definitive answer, but it might help you look in another direction. Not sure if that's good or bad, certainly it's brainstorming.
I've looked into this recently for a single particular module I had to wrap. I ended up writing a second module ("module-wrapper") for which I added a path entry with the name of the original module ("module"). I then added a second entry ("module-actual") that references the actual module which I require() as a dependency in the wrapper.
I can then add code before and after initialization, and finally return the actual module. This is transparent to user modules as well as the actual module, and very clean and straightforward from a design standpoint.
However, it is obviously not practical to create a wrapper per module manually in your case, but you might be able to generate them dynamically with some trickery. Or somehow figure out what name was used to import the (unique) wrapper module from within it so that it can in turn dynamically import the associated actual module (with an async require, which wouldn't be transparent to user code).
Of course, it would be best if requirejs provided official hooks. I've never seen such hooks in the docs, but you might want to go through them again if you're not more certain than me.

Categories

Resources