Calling node.js from makefile fails - javascript

I have a simple hello world js file I run from terminal with node, and everything works fine. When I try to run the exact same thing from my makefile it prints the hello world part but then fails. Here is the relevant target from makefile:
run: ${JS_DIR}/main.js
node ${JS_DIR}/main.js
And here is the error I get:
$ make run
node /some/dir/main.js
Hello World
makefile:44: recipe for target 'run' failed
make: *** [run] Error 254
What's going on here?

A make target will fail if any of its recipes return an error code (i.e., non-zero). node is returning a non-zero. Try running
node /some/dir/main.js; echo $?
to confirm.
You could either update main.js to not return an error (I believe this is done by calling process.exit() with no parameters or a 0 parameter, but I'm not a node or js expert, so take that with a grain of salt).
Alternatively, you could make make ignore the return code by adding a - to the beginning of the recipe:
run: ${JS_DIR}/main.js
-node ${JS_DIR}/main.js

Related

Unexpected stdout of "'Saved file tree to doc-filelist.js\n' + 'Copied JS to doc-script.js\n' + 'Compiled CSS to doc-style.css\n'

I am working on a Docker Swarm data visualization tool with a team.
It works as follows:
Our backend is set up in a way that terminal commands can be executed from our code, where these terminal commands have been promisified and the result of this command should be a string of nodeIDs corresponding to the active nodes in my Docker Swarm. This data is then passed to another helper function, however, I am unable to move past the previously explained step due to an unexpected output from my promisified terminal command.
const getNodeIDs = () => {
console.log('in nodeID helper function');
return execProm("docker node ls --format '{{json .ID}}'").then(
(rawNodeIDs) => {
console.log('rawNodeIds: ', rawNodeIDs);
const parsedNodeIDs = parseRawData(rawNodeIDs);
console.log('parsedNodeIDs: ', parsedNodeIDs);
return parsedNodeIDs;
}
);
};
My code fails on line 6 due to the fact that the data being passed to my parseRawData function is not what it is expected. The console log on line 5 above returns as follows:
{
stdout: 'Saved file tree to doc-filelist.js\n' +
'Copied JS to doc-script.js\n' +
'Compiled CSS to doc-style.css\n',
stderr: ''
}
In addition to this being the wrong output, every time I invoke this command, a new file is created in my codebase labeled "docs" with the following three files inside: doc-filelist.js, doc-script.js, doc-style.css. I am working in a team of 4 other engineers, and I seem to be the only person experiencing this behavior. When I attempt to run the terminal command (featured on line 3 in the first block of code) directly in the terminal itself, I receive the expected output of
"odwch32vsynhxbc0ia2nwicag"
which is the nodeID of the single node currently in my Docker Swarm and what I should be receiving when invoking the terminal command from the code.
I've only been able to find one other stack overflow article dealing with the same issue in which that person was told to try running the terminal command
npm uninstall -g docker
which I have done, and this did not fix my issues. I've also looked into making edits to the Docker daemon itself, but am unsure that this is the real root of the issue. Since I am the only person on my team that seems to be encountering this bug, I have reason to believe that this error has something to do with my dev environment. My containers are running on Docker v4.15.0 and I am working on macOS on an M1 chip computer.
Thanks!

Undefined variable causes huge verbose output from `esm.js`

I'm not sure why, but since upgrading to Node v16 from Node v14, I get this error only when I run node like node -r esm and there is a ReferenceError like:
ReferenceError: myVar is not defined
It causes a massive, 5000 line output of the esm.js module. How can I get rid of this?
const __global__ = this;(function (require, module, __shared__) { var __shared__;const e=module,t={Array:global.Array,Buffer:global.Buffer,Error:g
lobal.Error,EvalError:global.EvalError,Function:global.Function,JSON:global.JSON,Object:global.Object,Promise:global.Promise,RangeError:global.Ran
geError,ReferenceError:global.ReferenceError,Reflect:global.Reflect,SyntaxError:global.SyntaxError,TypeError:global.TypeError,URIError:global.URIE
rror,eval:global.eval},r=global.console;module.exports=(function(e){var t={};function r(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,export
s:{}};return e[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.d=function(e,t,r){Reflect.defineProperty(e,t,{configurable:!0,enumerable
:!0,get:r})},r.n=function(e){return e.a=e,function(){return e}},r(r.s=2)})([(function(e,t){var r;t=e.exports=$,"object"==typeof process&&process,r
=function(){},t.SEMVER_SPEC_VERSION="2.0.0";var i=256,n=Number.MAX_SAFE_INTEGER||9007199254740991,s=t.re=[],a=t.src=[],o=0,u=o++;a[u]="0|[1-9]\\d*
";var l=o++;a[l]="[0-9]+";var c=o++;a[c]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var p=o++;a[p]="("+a[u]+")\\.("+a[u]+")\\.("+a[u]+")";var h=o++;a[h]="("+a[l
]+")\\.("+a[l]+")\\.("+a[l]+")";var f=o++;a[f]="(?:"+a[u]+"|"+a[c]+")";var d=o++;a[d]="(?:"+a[l]+"|"+a[c]+")";var m=o++;a[m]="(?:-("+a[f]+"(?:\\."
+a[f]+")*))";var v=o++;a[v]="(?:-?("+a[d]+"(?:\\."+a[d]+")*))";var g=o++;a[g]="[0-9A-Za-z-]+";var y=o++;a[y]="(?:\\+("+a[g]+"(?:\\."+a[g]+")*))";v
ar x=o++,b="v?"+a[p]+a[m]+"?"+a[y]+"?";a[x]="^"+b+"$";var w="[v=\\s]*"+a[h]+a[v]+"?"+a[y]+"?",E=o++;a[E]="^"+w+"$";var S=o++;a[S]="((?:<|>)?=?)";v
ar R=o++;a[R]=a[l]+"|x|X|\\*";var P=o++;a[P]=a[u]+"|x|X|\\*";var _=o++;a[_]="[v=\\s]*("+a[P]+")(?:\\.("+a[P]+")(?:\\.("+a[P]+")(?:"+a[m]+")?"+a[y]
+"?)?)?";var k=o++;a[k]="[v=\\s]*("+a[R]+")(?:\\.("+a[R]+")(?:\\.("+a[R]+")(?:"+a[v]+")?"+a[y]+"?)?)?";var I=o++;a[I]="^"+a[S]+"\\s*"+a[_]+"$";var
A=o++;a[A]="^"+a[S]+"\\s*"+a[k]+"$";var N=o++;a[N]="(?:^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])";var C=o++;a[C]="(?
:~>?)";var O=o++;a[O]="(\\s*)"+a[C]+"\\s+",s[O]=RegExp(a[O],"g");var T=o++;a[T]="^"+a[C]+a[_]+"$";var M=o++;a[M]="^"+a[C]+a[k]+"$";var L=o++;a[L]=
"(?:\\^)";var D=o++;a[D]="(\\s*)"+a[L]+"\\s+",s[D]=RegExp(a[D],"g");var F=o++;a[F]="^"+a[L]+a[_]+"$";var j=o++;a[j]="^"+a[L]+a[k]+"$";var V=o++;a[
V]="^"+a[S]+"\\s*("+w+")$|^$";var G=o++;a[G]="^"+a[S]+"\\s*("+b+")$|^$";var B=o++;a[B]="(\\s*)"+a[S]+"\\s*("+w+"|"+a[_]+")",s[B]=RegExp(a[B],"g");
v..........
How can I stop node from printing this to the console?
Try resetting your computer. It works for me.

"istanbul ignore next" command seems to be ignored

I'm trying to use Jest to test my code. It was working quite fine until I tried to exclude a class method from the tests.
The querySelector() call is the reason why I want to skip this method from being tested ("document" is obviously null unless I run the script in the browser)
I tried this solution, which seems to be the most suggested one:
/* istanbul ignore next */
appendNewInputFields() {
const howMany = Number(document.querySelector('#items-to-add').value);
[...Array(howMany)].forEach( i => {
const newInputField = this.createNewItemInputField();
this.inputItemsContainerNode.append(newInputField);
});
}
But the test keeps failing and the line /* istanbul ignore next */ seems to be ignored.
I've also tried putting the comment between the function signature and its body (as was suggested somewhere here on SO), but no luck:
FAIL js/DOMManager.test.js
● Test suite failed to run
TypeError: Cannot read property 'value' of null
135 | appendNewInputFields() /* istanbul ignore next */ {
136 |
> 137 | const howMany = Number(document.querySelector('#items-to-add').value);
| ^
138 |
I've read around that this might be related to babel-plugin-istanbul. I've tried
npm --save-dev uninstall babel-plugin-istanbul
which in the terminal returned:
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents#2.3.2 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents#2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
removed 18 packages and audited 521 packages in 2.178s
but the folder babel-plugin-istanbul is still present in /node_modules/ inside my working folder and the test keeps failing as if nothing changed.
If I comment out the body of the function, the other test suites work perfectly. If I try to apply the ignore next command to any other part of the code, the tests pass just fine and the line is completely ignored.
If I try to manually delete the /babel-plugin-istanbul/ folder (from the /node_modules/ in my working folder), Jest stops working.
(This is the first time I installed Node.js, and I did it only because I wanted to start unit testing with Jest. I'm pointing this out because these are my first steps venturing out of the vanilla world. I don't know how to deal with Node.js nor npm, I just launched a couple commands to install it, I wrote a few tests for Jest and they all immediately worked fine. I'm not using any other framework, I'm trying to stick to vanilla JS as much as possible.)
----------------------- Edit:
I tried changing the code to this:
appendNewInputFields() {
// TODO solve the istanbul ignore issue
let howMany;
/* istanbul ignore if */
if(document != null) {
howMany = Number(document.querySelector('#items-to-add').value);
[...Array(howMany)].forEach( i => {
const newInputField = this.createNewItemInputField();
this.inputItemsContainerNode.append(newInputField);
});
console.log("added " + howMany + " input fields");
}
}
I keep getting
FAIL js/DOMManager.test.js
● Test suite failed to run
TypeError: Cannot read property 'value' of null
139 | /* istanbul ignore if */
140 | if(document != null) {
> 141 | howMany = Number(document.querySelector('#items-to-add').value);
| ^
142 |
143 | [...Array(howMany)].forEach( i => {
144 | const newInputField = this.createNewItemInputField();
I'm totally clueless at this point. Given the conditional, "document" should be null and that block entirely skipped, but it keeps failing the test.
The same code works exactly as intended when run in the browser.
So I made a few tests in a blank new folder, and it finally struck me.
Apparently I had misunderstood the purpose of /* istanbul ignore next */.
Its function is not to skip code from being executed during the tests, but rather prevent that portion of code to be taken into account when determining the amount of total code that has been tested. The code runs (if there is anything calling that function), but those lines just don't count when Jest sums up the amount of lines it tested (which is the purpose of --coverage, I guess). If an error occurs, it is thrown as it would normally be.
My problem wasn't really related to Jest nor the istanbul package. I feel pretty dumb realizing this now, but what I needed was just proper exception handling.
I implemented a few old fashioned try/catch blocks: now everything is tested smoothly and the istanbul ignore directive correctly behaves as expected (now that I know what to expect, that is): functions that are not tested and flagged to be ignored, they just don't appear in the final coverage report.
I hope this helps anybody who might stumble in my same misunderstanding.
Of course, if anybody more competent than me can confirm this interpretation or has any suggestion or further explanation, it would obviously be much appreciated.
I was with the same error with window.alert command with jest:
ReferenceError: alert is not defined
4 |
5 | /* istanbul ignore next */
> 6 | alert(helloWorld());
| ^
7 |
so I tried to use try-catch and SUCCESS!
before:
alert(helloWorld());
after:
const alerta = () => {
try {
return alert(helloWorld());
} catch (error) {
return false;
}
}
testes:
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
This might also happen if your bundling tool (esbuild, for instance) removes comments, therefore istanbul does not see them.
If that's the case, you might want to change your bundling tool to something like terser (make sure that comments are not omitted there, too) or adjust minification options of the bundling tool you use.
This is how it would look like if you use Vite:
build: {
minify: 'terser',
terserOptions: {
format: {
comments: 'all', // or regular expression /istanbul\signore\s/
},
},
},

node.js: suppress require()'s echoing of parse errors to stderr

node.js 10.26 will rightfully throw an error when you try to require a file that is not valid javascript (or JSON).
My problem is that it also outputs to stderr:
borken.js - know to be broken javascript file
,,>Z>badfile!=-csa&asd;'asdl ds]=}{ADS}DAS:LMFSV'
test.js
try {
var borken = require('./borken');
} catch (e) {} finally {
console.log('finally!');
}
Expected
$ node test.js
finally!
Actual
$ node test.js
/path/to/borken.js:1
(function (exports, require, module, __filename, __dirname) { asd;'asdl
^^^^^
finally!
The first three lines are output to stderr (running as node test.js 2> /dev/null suppresses them).
Is there any way to get rid of them?
What I've done so far:
I debugged while following the source and narrowed down the culprit to:
lib/module.js:439
var compiledWrapper = runInThisContext(wrapper, filename, true);
runInThisContext is defined in lib/vm.js, which unfortunately is a C++ wrapper, so I couldn't really follow what is going on through there.
I guess I'm looking for a magic "don't spam stderr" flag or any knowledge of this being fixed in any latest versions.
Apparently this has been fixed in the dev branch (0.11.x) but not in the latest stable (0.10.29)
Github issue: Syntax errors are printed to stderr, even when wrapped with try/catch #6920

Syntax check for JavaScript using command

Are there equivalent to perl -c syntax check for JavaScript from command? Given that I have NodeJS installed?
JSLint is not considered as it is not a real parser. I think YUI compressor is possible but I don't want to install Java on production machines, so I am checking if Node.JS already provided this syntax check mechanism.
If you want to perform a syntax check like that way we do in perl ( another scripting language) you can simply use node -c <js file-name>
e.g. a JS file as test.js has:
let x = 30
if ( x == 30 ) {
console.log("hello");
else {
console.log( "world");
}
now type in node -c test.js
it will show you
test.js:5
else {
^^^^
SyntaxError: Unexpected token else
at startup (bootstrap_node.js:144:11)
at bootstrap_node.js:509:3
Now after fixing the syntax issue as
let x = 30
if ( x == 30 ) {
console.log("hello");
} else {
console.log( "world");
}
check syntax - node -c test.js will show no syntax error!!
Note - we can even use it to check syntax for all files in a dir. - node -c *.js
Try uglify. You can install it via npm.
Edit: The package name has changed. It is uglify-js.
nodejs --help
explains the -p switch: it evaluates the supplied code and prints the results. So using nodejs -p < /path/to/file.js would be a disastrous way to check the validity of node.js code on your server. One possible solution is the one indicated in this SO thread. The one thing not so good about it - the syntax error messages it reports are not terribly helpful. For instance, it tell you something is wrong but without telling you where it is wrong.

Categories