npm / cli

the package manager for JavaScript
https://docs.npmjs.com/cli/
Other
8.48k stars 3.16k forks source link

[BUG] npx script does not appear to load dependencies #5650

Open cutterbl opened 2 years ago

cutterbl commented 2 years ago

Is there an existing issue for this?

This issue exists in the latest npm version

Current Behavior

I am attempting to write my first package to use for automated scripting, writing npx commands. I am attempting to use Google ZX for that scripting. After some initial testing I was finally able to run commands, when npm linking the package locally. But, after publishing my package, the commands no longer worked when running from other directories/terminal prompts. I have a very simple setup to begin with:

{
  "name": "pure-scripts",
  "version": "0.0.16",
  "description": "A repository of scripts that can be run using the npx command",
  "files": [
    "bin"
  ],
  "bin": {
    "pure-scripts": "chmod +x bin/index.mjs && bin/index.mjs"
  },
  "dependencies": {
    "zx": "7.0.8"
  }
}

My CI process publishes my package to a local private repository, with a bin/index.mjs file that looks a little like this:

#!/usr/bin/env zx
async function foo() {
  echo`This is foo!`;
}

async function hello() {
  $.verbose = false;
  let branch = await $`git branch --show-current`;
  $.verbose = true;

  echo`Hello`;
  echo`Current branch is ${branch}.`;
}

const commands = {
  foo,
  hello
};

const { _: [command] } = argv;

console.log('[pure-scripts] dirname: ', process.cwd());

if (commands[command]) {
  commands[command]();
}

As I said, this works fine locally. I build, run npm link, then run npx pure-scripts foo and get the expected output.

However, when I publish my package I do the following from another directory and new terminal

npm cache clean -f
// typical output
npx pure-scripts foo
// output: "env: zx: No such file or directory"

This appears to indicate that my defined dependencies, from my package.json, have not been installed for use by my scripts. I should note that I never get asked to install the package either.

Expected Behavior

That, after publishing my package, that running the npx <packagename> <command-args> command would install all of the dependencies required for my package scripts to run properly.

Steps To Reproduce

  1. On any OS
  2. With the package.json defined similar to above, and a bin/index.mjs as above, published
  3. Run npx <packagename> <command-args> (in this case foo or hello)
  4. Gets error env: zx: No such file or directory

Environment

//npm.pkg.github.com/:_authToken = (protected) //registry.npmjs.org/:_authToken = (protected) ; email = "" ; overridden by project ; registry = "https://registry.npmjs.org/" ; overridden by project

; "project" config from /Users//Documents//packages//.npmrc

email = "" registry = ""

; node bin location = /Users//.nvm/versions/node/v16.16.0/bin/node ; node version = v16.16.0 ; npm local prefix = /Users//Documents//packages/ ; npm version = 8.11.0 ; cwd = /Users//Documents//packages/ ; HOME = /Users/ ; Run npm config ls -l to show all defaults.

; "publishConfig" from /Users//Documents//packages//package.json ; This set of config values will be used at publish-time.

maverick1872 commented 2 years ago

I feel like I'm also experiencing a similar issue, although I feel like I've been able to replicate it on NPM v7.21.1 as well. I have a private package I publish that includes a bin entry. When attempting to execute this with npx via npx <scope/package-name> I get a missing module error that is one of the (prod) dependencies of that package.

When installing this same package with npm i <scope/package-name> and executing via npx in the same manner, the script functions as one would expect. Upon further investigation it appears that the missing module is not present in the _npx/<id>/node_modules directory but is present in the generated $(pwd)/node_modules/ directory.

This further reinforces my believe that npx is failing to correctly resolve all the necessary dependencies for this package. If it provides any value this package is hosted on the GitHub package registry. Additionally I've replicated.

Edit: maybe this will be the push I need to spend some time figuring out how to leverage @vercel/ncc so everything is pre-bundled.

nlf commented 1 year ago

the immediate problem i can see is here:

  "bin": {
    "pure-scripts": "chmod +x bin/index.mjs && bin/index.mjs"
  },

the value for keys in the bin field are a path to the file that contains the bin logic and cannot contain actual commands, in your case this would just be bin/index.mjs. see the docs here: https://docs.npmjs.com/cli/v9/configuring-npm/package-json#bin

try correcting that and see if it gets your package working for you. let us know!

cutterbl commented 1 year ago

@nlf Yes. I did this because every time I was attempting to run the script (without calling zx directly with zx <path>) it would give me a permission denied unless I explicitly changed the file permissions. Perhaps my issue is in finding clear tutorials on writing npx scripting scenarios...