How Can I Set An Environment Variable Inside "bin" Field of "package.json"

Viewed 795

I have an npm package that has a cli:

  "bin": {
    "myprogram": "./cli.js"
  }

It is executable by running myprogram --param value with no problem. I couldn't find it in npm's docs but I wonder if there is an approach to set an environment variable before running cli.js

I've tried:

  "bin": {
    "myprogram": "TZ=utc ./cli.js"
  }

but looks like npm doesn't handle it:

npm ERR! code ENOENT
npm ERR! syscall chmod
npm ERR! path /usr/local/lib/node_modules/@myprogram/myprogram/TZ=utc ./cli.js
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, chmod '/usr/local/lib/node_modules/@myprogram/myprogram/TZ=utc ./cli.js'

I don't want to do this by TZ=utc myprogram.

1 Answers

You cannot set environment variables the way you are hoping, but I can suggest an alternative solution.

In your package.json set the scripts field to:

"scripts": {
  "start": "TZ=utc ./cli.js"
}

Then create a file in the same folder as cli.js, lets call it cli-wrapper.js.

You can then create cli-wrapper.js with the following snippet:

#!/usr/bin/env node

const spawn = require('child_process').spawn;
const started = spawn('npm', ['run', 'start'], { cwd: __dirname });

started.stdout.on('data', function (data) {
  console.log('stdout:', data.toString());
});

started.stderr.on('data', function (data) {
  console.log('stderr:', data.toString());
});

started.on('exit', function (code) {
  console.log('child process exited with code:', code.toString());
});

The above snippet is a small piece of code that simply spawns a node script process in the current directory using 'npm run script'. You may need to make some adjustments to this snippet depending on how you are running the bin file. Maybe use path to resolve the correct directory and change to it before issuing the command. I don't believe adjusting the directory is necessary anymore, I have adjusted the above code and it seems to be functioning as expected.

Then you can adjust your package.json file's bin parameter:

"bin": {
  "myprogram": "./cli-wrapper.js"
}

And as long as the spawn snippet runs in the correct folder it should allow you to specify different environment parameters within the scripts.start field in your package.json.

Related