Error: Cannot find module 'my-client'

#1

I'm developing a node-contrib module that creates a few nodes for network communication. After writing it all up, I get an error message on node-red startup:

25 Mar 23:34:26 - [warn] [node-red-contrib-my-client/my-client] Error: Cannot find module 'my-client'

The first npm package I installed is 'node-red-contrib-my-client', following the instructions in the docs and a similar existing (and working) package. It requires 'my-client' as dependency which does the actual network protocol handling.

I've installed the contrib package with 'npm i C:\path\to\node-red-contrib-my-client' and it has created a link to my dev directory under node_modules. Looks good. That dev directory also has 'node_modules\my-client' in it. But I get the error message. Even when I install the dependency directly to node-red with 'npm i C:\path\to\my-client', it creates a second directory as a link, but it doesn't help.

What have I done wrong?

node-red 0.20.0 on Windows 10. The Node-RED GUI works and I see the nodes from the other package I installed. It has dependencies, too, as my package. But mine fails to load.

PS: Node-RED's debug and trace logging isn't helpful. It lists my contrib package among others but then shows the error message. I have no idea where this thing is looking for the files but it's the wrong place.

Update: The error message seems to come from this line in my contrib module:

module.exports = function (RED) {
    "use strict";
    var events = require("events");
    var MyClient = require("my-client");   // <----- ERROR
    ...

When I set that variable to null, the error goes away, but the code will not work without it. When I set the string to "../my-client", as specified in the package.json, it also doesn't work.

Both of my packages are not published on npmjs, I only have them on my local machine because both are still in development. But it seems npm isn't made for development, it's just good for consumption of already published packages.

#3

Perhaps it may help to check if the filesystem links are created as expected.

You can check which is the global npm directory by typing npm root -g in your terminal

Then change to npm global root directory and type ls -al to see the links. In my case, for instance:

#4

Is the library my-client installed globally? Or its it a file relative to your node red node project?

As a test, try using the full path of my-client.js. I strongly suspect this is a relative path issue. You need the correct ..\\foldername\\ relative path

1 Like
#5

The packages should be installed correctly. As far as I understood npm's behaviour with installations from local directories, the links are set up as expected. Under ~/.node-red/node_modules there are two links now: node-red-contrib-my-client pointing to the development directory of that package, which includes node_modules and another link to my-client's development directory, and additionally the my-client link directly for node-red.

The packages are not installed globally, just locally for node-red.

What did work is altering the require call to this:

//var MyClient = require("my-client");   // Should be correct
var MyClient = require("../my-client/my-client");   // Works instead

I guess this will fail when I publish my packages and have them installed from npmjs.

The package my-client (used by node-red-contrib-my-client) has another dependency to @ygoe/msgpack which is already published on npmjs. That package has not caused any trouble whatsoever. And it's not installed for node-red directly, it just appears in node_modules/node-red-contrib-my-client/node_modules/my-client/node_modules/@ygoe/msgpack as well as node_modules/my-client/node_modules/@ygoe/msgpack (because these are linked together). It seems Node.js can't properly handle packages that are not installed from npmjs.

#6

It is not easy to understand the issue without knowing the exact structure of your directories.

As explained in below link Node.JS will check if your package (my-client) is installed in /node_modules of the parent directory. If it is not found it will check /node_modules directories all the way up to the root directory.

## Loading from node_modules Folders

When you use '../' you are overriding the search algorithm and telling Node.JS explicitly where to find the package.

#7

That's what I intended. The ../ path was to try and override the search. But the search should actually find the package, too, if it starts in the right location. I guess it doesn't. I'm going to create a simple test case with Node.js only, without node-red, and try to find support for that.