Search code examples
node.jsnpmnpx

How to publish [my own] npm package that can be invoked globally


I've published a new public node app via npm. (Note: This is clearly an alpha. Don't expect very good, much less perfection.) I'm unable to get it work as a global install.

https://www.npmjs.com/package/khutzpa

To test, I installed it globally with this:

npm install -g khutzpa

On macOS, that installs in /usr/local/lib/node_modules/khutzpa for me.

I expected to be able to execute it at this point from the command line like this:

khutzpa /usr/local/lib/node_modules/khutzpa/tests/fakeSite /openInBrowser

I cannot. When I run that line, I receive:

zsh: command not found: khutzpa

I have other packages installed globally that are found, including prettier and eslint.

If I run it via a full path to its index.js, it's happy and runs exactly like I'd expect.

node /usr/local/lib/node_modules/khutzpa/index.js /usr/local/lib/node_modules/khutzpa/tests/fakeSite /openInBrowser

That's the basic issue. Is there something additional I'm supposed to set up?


More info

index.js

I think all I need in package.json is the main entry, and I have that...

"main": "index.js",

You can see the index.js file in full here.

In that file, I'm doing a if (require.main === module) { check to see if it's used as a module, which might be an issue now (?), but that doesn't seem to explain why it's not found at all.

npx

If I run with...

npx khutzpa /usr/local/lib/node_modules/khutzpa/tests/fakeSite /openInBrowser

I receive...

npm ERR! could not determine executable to run

There's not a lot more info in the log it creates afaict.

34 verbose stack Error: could not determine executable to run
34 verbose stack     at getBinFromManifest (/usr/local/lib/node_modules/npm/node_modules/libnpmexec/lib/get-bin-from-manifest.js:17:23)
34 verbose stack     at exec (/usr/local/lib/node_modules/npm/node_modules/libnpmexec/lib/index.js:114:15)
34 verbose stack     at async module.exports (/usr/local/lib/node_modules/npm/lib/cli.js:66:5)
35 verbose pkgid khutzpa@0.0.1-alpha
36 verbose cwd /usr/local/lib/node_modules/prettier
37 verbose Darwin 21.5.0
38 verbose argv "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/bin/npm-cli.js" "exec" "--" "khutzpa" "/usr/local/lib/node_modules/khutzpa/tests/fakeSite" "/openInBrowser"
39 verbose node v16.15.0
40 verbose npm  v8.5.5
41 error could not determine executable to run
42 verbose exit 1

as a require in another package

Just tried invoking as an include, and it seems to work okay, except that I have to use khutzpa.default to invoke it, which I didn't think I needed to do. Maybe a hint. I'mma googling.

But I...

  1. Created a dir.
  2. npm init -y
  3. On command line in that dir ran npm install khutzpa
  4. Inserted this code:
const khutzpa = require("khutzpa");

console.log(khutzpa);
khutzpa.default("/usr/local/lib/node_modules/khutzpa/tests/fakeSite", 3000, 1);

That works, though khutzpa("/usr/local/lib/node_modules/khutzpa/tests/fakeSite", 3000, 1); does not, so maybe an export issue?


Solution

  • Looks like there may have been two issues:

    I needed a "sharp-exclamation" in my index.js file to let npm know where node is (?).

    I needed a "bin" entry in package.json.

    The best way to sum this is probably by pointing at this commit that fixed things.

    Here's a summary in an image with a reasonably good alt description, I believe. I'll add some WinMerge reports in a bit:

    added #!/usr/bin/env node to first line of index.js and "bin": "index.js", to the package.json file, as well as incremented the version in package.json from "version": "0.0.1-alpha", to "version": "0.0.1-alpha.1",