In a different directory than NR, I tried installing a node module, separate from NR, # npm install . I got module not found using a require(''). So I did an uninstall, then global install of the module, # npm install -g . This resulted in EACCESS errors. What am I missing, are global install of modules not seen by node js? This lead me to the following qualification, https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally.
Is any of the above doing to break NR? Is NR variant of npm not installed with a version manager for npm?
There is no such thing as a node-red variant of npm. You have whatever version of npm you have. If you're using the Pi install script we provide, you'll have got whatever version of npm is packaged with the version of node.js that was installed.
Where was the code (relative to directory you ran the npm install in) that tried to do the require?
EACCESS means the process didn't have permission to write the files. This is because the global module location is typically somewhere that requires root access.
So node_modules under .node-red is a local repo, right? Modules in that 'dir tree' would be invisible to a require 'call' from some other directory not under .node-red, say /root for example, right? Thus npm run under .node-red is in 'effect' a local scope for npm. Especially if you do not use '-g' for npm installs in that directory. The npm command may be scope less, but what actions you take and where with npm do... in fact create a scope. This why you can end up with 'nobody' ownership, why you can end up with EACCESS errors. Right?
npm (not -g) installs to the current directory (ie node_modules is in the current directory). npm -g installs to a system location and on Linux will generally require sudo to write there, that is why you got the access permission error (you didn't use sudo). On linux generally it is either sudo npm -g install or npm install (no sudo, no -g).
Globally installed nodes will be available from anywhere in the system, locally installed ones are available only from the directory where they were installed.
This is good not odd. Global installs need root to install but not necessarily to run. That's because of the fact that global installs need write access to system folders. Read/execute access is then available to all.
So global installs are protected from change by ordinary users.
In general though, global installs of npm modules should be avoided since they can introduce unexpected security issues.
Rats... I reset the environment.. If I get the chance will try to recreate the scenario.
Moreover, I still see module not found issues for odd reasons in just using node. Google is just buried in issues and possible fixes to when or how node modules are not found, the prefix is wrong, or the NODE_PATH variable not set, the list of potential pit falls is extensive.
I have for now, just restored to using absolute paths. This is not a NR issue, as long as NR modules are placed under .node-red/node_modules, no issues.
It is when I am writing code under just node to get i2c, spi, etc. communication right, or code logic finalized, and once the code is solid, only then dropping it in or wrapping it up for NR.
I am developing a true love/hate relationship with npm.
Another question... is there a way to programmatically determine if code is running under NR versus just node? It would be cool if I could use console.log() versus node.log() at the appropriate time... using just node in writing the bulk of the code logic, for me, is faster than loading it into NR over and over.
Probably yes but a simple way would be to use an env variable e.g....
process.env.WITHOUTNODERED
If you determine you are NOT in node-red, then you could set node.xxxx functions to proxy functions instead of littering your code with if(isNodeRed) node.log(X) else console.log(X)
As I typed that from my mobile i thought it easier than asking if node was defined as often var node = this is written in custom nodes - so calling var node = node ? node : { log: console.log, error: console.error, warn: console.warn }; may have failed due to node === this regardless of whatever this is.
(few, hope that ^ made sense!)
I dont have time to run up a custom node-red contrib node and find a simple means of understanding if I took the red pill or blue pill so suggested a sure fire way of knowing via an explicit env var (if you set it - then its true right!).
PS, I'm bookmarking that nice snippet (because I always forget how that var xxx = { yyy, zzz} syntax works - just cant seem to commit it to memory (I used to struggle with arrow functions syntax too !)
Ah yes, anyone who has to wrangle with npm eventually ends up in that place!
There are many ways and it somewhat depends where you want to determine that. In most cases, if the object RED exists, you can be pretty sure that you are running under Node-RED. But of course, there are places in code when that won't be available. and in that case, you can use node.js's process module to find out what executable started the current process.
This is just to allow easy code development, debugging, so does not need to be complex or robust, the console references would be stripped from code as development cycle comes to a close. I typically have a helper function that does exception/status reporting, so easy to check each time I would call .log,, .debug, etc.