Hello there,
I'm trying to set up a bunch of custom nodes that combine p5 library and Mathjs.
Inspired by the nice contrib-example-lower-case https://nodered.org/docs/creating-nodes/first-node I create the building blocks of my node (html, json and js).
I then install with the npm install --verbose D:\mydevfolder from the console pointing to the folder where I keep my new node.
In order to import p5 and mathjs I placed them into the same local folder and used 'require' statements in the javascript.
Similar to what other contrib-libraries' nodes do:
Here is my .js code:
module.exports = function (RED) {
'use strict';
const mathjs = require('./mathjs/dist/math');
const p5 = require('./p5');
function p5SynthNode(config) {
RED.nodes.createNode(this,config);
var node = this;
//my nice functions go here
node.on('input', function(msg) {
node.send(msg);
});
}
RED.nodes.registerType("p5synth",p5SynthNode);
}
The problem is that the node does not appear in the palette.
Commenting out the p5 require line solves the problem (local mathjs is correctly imported).
What is the correct way to require libraries when setting up a custom node?
The proper way is to include a package.json file in your node that makes it a proper module. In that file you can declare what npm modules your node depends on so that when you run the npm install command, npm will take care of installing those dependencies in the right place.
Then, in your code, you don't use relative paths in your require statements - you use require('p5') and require('mathjs/dist/math').
Thank you very much knolleary.
I figured out that p5 was raising issues due to window reference (usually available when running as usual via an html). I have it commented out, since I need to circumvent this.
The dependency workflow logic you explain makes sense. I do have a package.json. I did not include any dependencies though.
I'm now trying it for mathjs, with the following text:
This is not the correct process for consuming Node.js libraries.
You should install them using npm:
npm install mathjs
Then, as Nick says, you can simply do
const mathjs = require('mathjs')
// or, to use a single function
const { sqrt } = require('mathjs')
console.log(sqrt(-4).toString()) // 2i
These things are shown in the documentation and this isn't really a Node-RED issue.
P5, on the otherhand is a JavaScript version of the Processing language. It is front-end code as it expects and needs a browser as an output medium. I very much doubt it will work in Node.js server environments.
To use it with Node-RED, you need to build a web-page and include the library that way. Node-RED has several methods to do this ranging from the http-in/-out nodes, Dashboard with the Dashboard Template node, or contributed nodes such as my own uibuilder (which would make an excellent platform for working with P5 and Node-RED).
Thank you. I don't consume Node.js libraries that way. I'm sorry that is what it looked like.
I was just trying to circumvent the require statement problem mentioned with relative paths, as the global require does not manage to find the libraries.
The npm install changing the package.json is the way to go.
As per p5, my idea of using it came after noticing its npm https://www.npmjs.com/package/p5
However, I'll need to tests approaches like the http-out and uibuilder you mention.
Thanks
So, as indicated by knolleary, package.json is updated also when no flag is given.
I managed to install (within my custom node folder) and use mathjs, no local path
It modified the package.json and created a local folder with the lib contents.
This is really an npm topic however, it doubtless confuses many people.
You need to understand a little more about how npm works. For more recent versions of npm, it attempts to keep the packages as "flat" as possible. What used to happen is that each package got its own node_modules folder with its dependencies installed. However, as this can add 10's to 100's of thousands of files, it quickly gets unmanagebly large. So now, it tries to keep everything to a single node_modules folder except where there are clashing version requirements.
Here are a couple of links that help you understand:
And from one of my own helper libraries. Here I have a need to manually find where a package is installed (if it is). If have to jump through hoops because this code is, itself buried in a module that is buried several layers deep in Node-RED. So the standard resolve method in the link above doesn't always work. The JSDoc for that function gives a little more explanation.