sanack / node-jq

Node.js wrapper for jq
MIT License
276 stars 51 forks source link

Not showing up in node_modules/.bin until npm rebuild #669

Closed mtfurlan closed 6 months ago

mtfurlan commented 6 months ago

Description

When I install node-jq, the symlink doesn't show up in node_modules/.bin until I do node-rebuild, so npx node-jq whatever fails.

Reproduction

create new directory

$ npm install node-jq tsc
...
$ ls node_modules/.bin/
ndh@  seek-bunzip@  seek-table@  tsc@  uuid@  which@
$ npm rebuild
rebuilt dependencies successfully
$ ls node_modules/.bin/
ndh@  node-jq@  seek-bunzip@  seek-table@  tsc@  uuid@  which@

Notice how tsc showed up the first time, node-jq only after npm rebuild.

If I run with --loglevel verbose both the install and the rebuild have

npm info run node-jq@4.3.0 postinstall node_modules/node-jq npm run install-binary
npm info run node-jq@4.3.0 postinstall { code: 0, signal: null }

Environment

All testing was done with node-jq 4.3.0

Systems tested:

The bit where it gets weird

If I modify the node-jq package.json bin field from

diff --git a/package.json b/package.json
index 94a445c..e07284e 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
     "url": "https://github.com/sanack/node-jq"
   },
   "bin": {
-    "node-jq": "bin/jq"
+    "node-jq": "bin/jq",
+    "foobar": "bin/jq"
   },
   "scripts": {
     "pretest": "npm run install-binary",

it works as expected.

So I tried making a test module with a single thing in the bin field, but it worked as expected.

{
  "name": "testpackage",
  "version": "1.0.0",
  "description": "",
  "bin": {
    "bar": "foo"
  }
}

So, any idea what might be happening? I can do bug report against npm if we can figure out how to reproduce.

davesnx commented 6 months ago

Whoa, this looks bad and the only thing that might be happening is the path? Checking tsc they use "./bin/tsc" https://github.com/microsoft/TypeScript/blob/main/package.json#L25 and node-jq uses "bin/jq".

mtfurlan commented 6 months ago

I tried that earlier, and it didn't work.

Though now whenever I install the node-jq package from a local directory it does the symlink, while the npm package still isn't. But it is a different process because from a local directory install also installs dev dependancies I think?

So I dunno what changed. I'll poke more monday.

Can you replicate any of this, or is it only being weird for me and a coworker?

mtfurlan commented 6 months ago

Okay I think I figured it out. I suspect the linking is done by install, and the binary is created by postinstall, so it doesn't link anything the first time.

Demonstration:

$ cd /tmp/whatever
$ git clone git@github.com:sanack/node-jq.git

$ npm i ./node-jq/
$ ls ./node_modules/.bin/node-jq
lsd: ./node_modules/.bin/node-jq: No such file or directory (os error 2).

# but install a second time, and it shows up
$ rm -rf ./node_modules/ package*
$ npm i ./node-jq/
$ ls ./node_modules/.bin/node-jq
./node_modules/.bin/node-jq@

# now delete node-jq/bin, created in postinstall
$ rm -rf node-jq/bin

$ rm -rf ./node_modules/ package*
$ npm i ./node-jq/
$ ls ./
lsd: ./node_modules/.bin/node-jq: No such file or directory (os error 2).

Solution:

diff --git a/package.json b/package.json
index 94a445c..47de719 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "lint": "standard --verbose | snazzy",
     "build": "swc ./src --delete-dir-on-start -d lib",
     "copy-ts-defintions": "copyfiles src/*.d.ts lib -f",
-    "postinstall": "npm run install-binary",
+    "preinstall": "npm run install-binary",
     "coverage": "nyc report --reporter=lcov",
     "precodeclimate": "npm run coverage",
     "codeclimate": "codeclimate-test-reporter < coverage/lcov.info",

I'm not sure how to test installing it as an npm module, but I think this will work?

davesnx commented 6 months ago

That's interesting, it should work indeed. Want to push a PR so we can play with a prerelease version?

github-actions[bot] commented 6 months ago

:tada: This issue has been resolved in version 4.3.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

davesnx commented 6 months ago

You can test the new version with the fix node-jq@4.3.1, will keep it open (was automatically closed)

mtfurlan commented 6 months ago

It works!