Starting Meteor dev from NPM scripts causes CPU spike - node.js

Picking up on a suggestion I read, I thought I would try starting my Meteor processes in dev mode from npm scripts in package.json files, since I have some verbose startup settings. I'm aware that I can use a bash script or the like but npm run whatever seemed like a nice clean solution.
Unfortunately doing this causes huge CPU spikes that render my system unusable. For example, running meteor -p 6001 and meteor -p 7001 yields two node processes utilizing 0.3% CPU each. But running npm run appA and npm run appB where the scripts point to the same commands above yields a first node process utilizing over 70% of CPU, and a second process over 100%.
Apparently this is not doing what I thought it was doing. It's not mission-critical but I'd love to learn what's going on under the hood or, even better, a fix. I'm running node version 5.4.1 and Meteor version 1.2.1 (which utilizes node version 0.10.40).
Can someone explain what's causing this?

Exactly same thing happened here, glad to find out that this is because of npm script, I was thinking that I'm due to deep profiling my app to find what's wrong.
Would love an explanation and a fix too.

Related

Node JS Randomly stops executing - Shows no errors

I am not sure where to start looking for the issue here.
I recently updated from angular 5 to angular 8. The application runs fine after the update. I don't know if this is related.
All of the sudden, my Node JS scripts stop seemingly at random. Sometimes they run, usually they don't. This is any script.
By "Stopping" I mean the console, mid execution, leaves the last line it wrote up, and on the next line, I am able to write more commands.
Example:
C:\location\> npm start
ng serve --aot
** Angular Live development server is listening on .....*
12 % building 22/23 modules 1 active ...somefile.ts
C:\location\>
There is no error, even when I run --verbose. Also, if I have multiple windows up or multiple servers running, they all stop at the same time. It is happening regardless of the application or package, including http-server, Angular, and installing dependencies.
I couldn't find anything related online. Has anyone ever seen this?
Update:
The issue is caused by my lack of CPU.
I thought I fixed it by updating, but that didn't work.
----------- (previous reply, not a solution)
It appears some of my installed dependency versions conflicted with package.json. Basically something did not fully update as expected.
I resolved the issue by running npm install.

Correct way to use yarn/npm from node script

Inside my script I want to use some functionality from yarn/npm
Like get results of yarn info packageName. I could spawn command and get output, but I believe there should be more correct way to do that.
Can't find any documentation about usage of yarn as package. Any ideas?
NPM and Yarn were designed as CLI tools. It's possible to load them with require but since executable script does a lot of work on options processing, this isn't practical.
The most straightforward and predictable way is to run them with child_process spawn or exec. There are npm-programmatic and yarn-programmatic third-party packages that do this internally. Since their APIs don't necessarily cover 100% of CLI functionality, it may still be beneficial to run commands directly.
There are open issues for NPM and Yarn regarding programmatic use.

PhantomJS from Node on Windows

I have written a Electron application using Node, Electron Boilerplate, and phantom. It works perfectly fine for me on my linux machine, I copied the source over to Windows 10, and ran with npm start, and all goes smoothly.
However, when I try to build the application with the boilerplate module using npm run release, things go a little less smoothly. I can install and open the application just fine, but when I click the button that activates the phantom module, the windows goes all white and nothing happens. I was able to logs some errors with the dev tools.
First, I have:
C:\...\dist\win-unpacked\resources\app.asar\node_modules\phantom\lib\phantom.js:361
Uncaught (in promise) Error: Error reading from stdin: Error: write EPIPE(…)
I did some research into similar issues, namely here, and it seems to me the issue is starting the child process, PhantomJS, with the npm module phantom. Originally, I was using a WPF application I wrote in C# to start the process, and that worked just fine. This leads me to believe that the phantom module is the culprit.
So I tried swapping out the npm phantom module for horseman, but got similar results:
Unhandled rejection HeadlessError: Phantom immediately exited with: 4294967295
at ChildProcess.immediateExit (C:\...\dist\win-unpacked\resources\app.asar\node_modules\node-horseman\node_modules\node-phantom-simple\node-phantom-simple.js:153:23)
at ChildProcess.g (events.js:286:16)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12)
Here is a shot in the dark. I am not positive this will solve your issue but here it goes:
GYP and miss-matched binaries
Phantom and many other node modules use binaries built for the specific OS that it will be running on. Sometimes in your npm log files you will see references to node-gyp. Node-gyp simply helps to build native add-on's in node modules. When the binaries are built they are usually built against, among others, three main parameters, the operating system, cpu architecture and version of node that is doing the installation.
I think you need to rebuild phantomjs to the version of node Electron is using. Most of the time the node version you have installed on your machine and the node version running in Electron are not the same. Electron does its best to keep up, but there is always a little lag because of the amount of work and testing required to keep up-to-date.
When you install phantom by running npm install phantom it will assume it needs to install or build the binaries for the node version your machine is using. Then when your Electron app tries to run phantom it tries to call the binary of the Electron's node version. When it isn't there the child process immediately exits with an error.
How to fix
Luckily, there are other people out there that have figured out how to fix this issue and have created a great tool to help generate the correct binaries.
Enter electron-rebuild:
https://github.com/electron/electron-rebuild
Electron-rebuild can be run in the command line, and it will rebuild all of your native modules to the version of Electron your project is using.
To install:
npm install electron-prebuilt
To use (in Windows):
.\node_modules\.bin\electron-rebuild.cmd
This should be enough to put the correct binaries in the right place.
Other thoughts
Sometimes you can use a package that uses a dependency called node-pre-gyp. E.g. sqlite3. There is a known issue I ended up running into when trying to rebuild my packages for Electron. Basically, in order to avoid this issue (if you run into it) just append --pre-gyp-fix to the above command.
Tangent for those who run into the pre-gyp-fix issue
One more thing on the pre-gyp-fix: If one or more of your dependencies depends on one of the modules that need the pre-gyp-fix then they will be looking for the binary in the wrong place even if they are running in Electron. All of the pre-gyp binaries are stored in a folder similar to this:
.\node_modules\sqlite3\lib\binding
In my current project I have three folders here, one for Electron-v1.4, and two for node-v46 and node-v50. (hack alert) In order to have sqlite3 work with my other dependencies I copy the binary found in the Electron-v1.4 folder and put it in both node-v* folders. That way when running in Electron, all dependencies are running the correct binaries even though they are looking for them in the wrong place. (end hack alert)
Conclusion
There is no way I can be sure this has anything to do with the issue you are seeing. But it is worth a shot to see if it fixes your problem. If not then at least I hope I can help someone else experiencing the same issues I ran into.

Publishing an npm package that strictly requires a minimum Node version

If I write a package I am certain requires Node 4 or higher, I don't want it to be installable with older versions.
I know about the package.json engines field, but that's just advisory (only causes a warning). And enginesStrict has been deprecated.
So what can I do?
One idea is to have a preinstall script that checks the Node version and errors if it's not high enough, preventing installation from continuing. Are there any problems with doing that? And is there a better way?
If you want a good experience, make your CLI entrypoint standard ES5 and CommonJS, detect the node version (process.version), and print a detailed and helpful message then exit non-zero. Keep in mind your module may get installed with some node version then the user futzes with nvm or their PATH or whatever and then runs your code under a different version. Thus I think failing nicely at run time is the most important thing. You can also choose to fail at install time if you like.

how can I debug a node app that is started via the command line (cli) like forever or supervisor?

I'm familiar with debugging my own node apps (usually with node-inspector). Today I'd like to debug someone else's program. I'm trying to track down an issue with supervisor. So naturally I just add a --debug (or debug-brk) to the command call, but it passes that to the code that it is supervising.
I've tried adding debugger lines to the js file for supervisor but that didn't work (probably because no debugger was attached at that time). There's a bit of a race here -- I need to start the debugger and attach it to the supervisor process after it starts but before it processes its arguments from the command line.
What I really want to do here is stop supervisor and debug it before it processes its command line arguments. How can I do this?
I had the same problem while developing my hexo blog. The documentation isn't all that complete yet so I find myself needing to reverse engineer at times.
The basic idea is that in Node.js even your cli apps are simply normal node apps that you are exposing to the OS command line interface. On Unix systems you are using this line:
#!/usr/bin/env node
To allow the environment to execute the script.
Many cli based node apps try to insist that you install them globally with the -g option.
npm install -g node-inspector
I personally prefer to have as much control of my development environment as I can get, so I prefer to break some conventions and check my node_modules in to source control along with installing everything I can locally by dropping the -g.
npm install node-inspector
Now you don't have to do this in order to make this work, I'm just describing this setup because it relates to your question. When I run node-inspector I can't simply use:
node-inspector
Instead I must explicitly invoke it from within my project. I do this by executing the symlink in my node_modules/.bin folder:
node_modules/.bin/node-inspector
Now I'm running node-inspector just like you.
Next all I need to do is start the cli process in debug and optionally pass params to it:
node --debug-brk node_modules/.bin/hexo generate
Note I am explicitly calling the symlink here and not simply:
node --debug-brk hexo generate
If I tried the line above I would get an error: "Error: Cannot find module".
I hope this helps.

Resources