Use files from dependent npm module

Hi folks,

I'm stuck again with one of my new nodes.

My custom node depends on another NPM module, so I have added it as a dependency in my package.json file. That module contains a couple of files that I need. For example I need this CSS file:

image

As soon as my config screen needs that CSS file, I load it via my http admin endpoint:

RED.httpAdmin.get('/xterm_shell/:config_node_id/:command/:info', function(req, res) {
   var options = {
      root: "/home/pi/.node-red/node_modules/xterm/css",
      dotfiles: 'deny'
   };
   // req.params.info contains "xterm.css"
   res.sendFile(req.params.info, options);
}

However now I fetch the file from it's absolute path, which works fine in my case. But I assume that is bad practice and won't work in all cases (other operating systems, older NPM versions, ...)

Does anybody knows how to do this correctly?

P.S. I don't want to copy those files manually to my own Github repository, because then I need to repeat that process every time the dependent module is upgraded ...

Thanks !!
Bart

within your node __dirname should be your absolute path - so you should be able to relative path from there.

Hey Dave,
I thought I had read somewhere on this forum that (in newer versions of NPM) the directory structure of the dependent nodes? I.e. that the node_modules folder had been moved to another location. But perhaps I'm seeing ghosts :ghost: ...

So I need to start from __dirname to get my current node's path, and then I need to find a "node_modules/xterm "subfolder and append it to my current node's path. And that should work on all systems. Will give it a try. Thanks !!!

Hmm now you say it like that I'm less convinced.

Use require.resolve("xterm") to get the path to the xterm module, wherever it has been installed, and go from there.

https://nodejs.org/api/modules.html#modules_require_resolve_request_options

1 Like

That is indeed the recommended and best way. However, require.resolve only works if the package defines a main script. I've noticed that some don't - it caught me out with uibuilder as that has to do extensive checking for installed packages. I even tried to raise an issue for it which got knocked back since the devs say that this is the way it works.

This is an area that is hard to get right and a real weakness of the npm/node.js packaging process in my opinion.

Bart, you might check out the uibutils.js and the tiutils.js files in uibuilder as they have a number of functions for finding the paths to packages. Of course, if it is only that one package and it defines a main entry point in package.json then you are fine.

You certainly cannot rely on a package being in a peer folder of your own package. It could be in the global location or at the wrong end of a link or, with @ groupings, it could be in a sub-folder of one of those locations.

1 Like