Reputation: 628
My question is: how can I make node available to a shell script on Cloud functions for Firebase when I use an npm package like xml2json?
Context:
I am moving a piece of software from short-living Docker containers to Cloud functions for Firebase. The software processes large XML files and converts parts to JSON.
Due to the memory consumption, I use xmllint and xml2json via the shell.
var cmd = './xmllint --xpath "//OrderData" ' + this.filename + ' | ' + __dirname + '/node_modules/xml2json/bin/xml2json';
exec(cmd, function(error, stdout, stderr) { ... }
Xmllint works as expected (distributed in the npm package that I added to package.json in the functions directory)
"@niekoost/convertini": "file:niekoost-convertini-1.0.1.tgz"
But the pipe through xml2json produces the problem: The first line of xml2json is causing my issue
#!/usr/bin/env node
This leads to an error in the Cloud Functions log in the Firebase console
Error: Command failed: ./xmllint --xpath "//OrderData"
/tmp/kdjf6kv9hku86xw4h392j4i.xml | /user_code/node_modules/xml2json/bin/xml2json
/usr/bin/env: node: No such file or directory
Where is node located on Cloud functions for Firebase? Can I make it available to /usr/bin/env? Or should I fork the xml2json npm package and change that code.
Upvotes: 1
Views: 241
Reputation: 628
After some additional searches I have found a solution for my situation, without having to change the npm package that is provided for xml2json.
Since xml2json is used in a command that is being executed by 'exec', we only need to make the path to the Node binary available in the environment of that exec. This path can be derived from 'process.execPath':
var exec = require('child_process').exec;
var process = require('process');
// get path where the node binary is located from within the code that
// is being executed by the node runtime provided by Firebase
var nodePath = process.execPath;
nodePath = nodePath.split('/');
nodePath = nodePath.splice(0, nodePath.length-1).join('/');
// add path to the environment
process.env.PATH += ':' + nodePath;
var cmd = './xmllint --xpath "//OrderData" /xyz.xml | /user_code/node_modules/xml2json/bin/xml2json';
// call the command and provide the extended env
exec(cmd, {env: process.env}, function(error, stdout, stderr) {
...
});
Upvotes: 2