Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot install the package using node v16 #1711

Closed
strowk opened this issue Oct 26, 2021 · 30 comments
Closed

Cannot install the package using node v16 #1711

strowk opened this issue Oct 26, 2021 · 30 comments

Comments

@strowk
Copy link

strowk commented Oct 26, 2021

I am running npm install --save-dev esbuild in a folder with only package.json file and getting this output:

npm ERR! code 1
npm ERR! path /home/tim/testesbuild/node_modules/esbuild
npm ERR! command failed
npm ERR! command sh -c node install.js

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/tim/.npm/_logs/2021-10-26T10_37_48_991Z-debug.log

Log file ends with following:

170 info run esbuild@0.13.9 postinstall node_modules/esbuild node install.js
171 info run esbuild@0.13.9 postinstall { code: 1, signal: null }
172 timing reify:rollback:createSparse Completed in 5ms
173 timing reify:rollback:retireShallow Completed in 0ms
174 timing command:install Completed in 1718ms
175 verbose stack Error: command failed
175 verbose stack     at ChildProcess.<anonymous> (/home/tim/.npm-global/lib/node_modules/npm/node_modules/@npmcli/promise-spawn/index.js:64:27)
175 verbose stack     at ChildProcess.emit (node:events:390:28)
175 verbose stack     at maybeClose (node:internal/child_process:1064:16)
175 verbose stack     at Socket.<anonymous> (node:internal/child_process:450:11)
175 verbose stack     at Socket.emit (node:events:390:28)
175 verbose stack     at Pipe.<anonymous> (node:net:687:12)
176 verbose pkgid esbuild@0.13.9
177 verbose cwd /home/tim/testesbuild
178 verbose Linux 5.11.0-34-generic
179 verbose argv "/snap/node/5510/bin/node" "/home/tim/.npm-global/bin/npm" "install" "--save-dev" "esbuild"
180 verbose node v16.12.0
181 verbose npm  v8.1.0
182 error code 1
183 error path /home/tim/testesbuild/node_modules/esbuild
184 error command failed
185 error command sh -c node install.js
186 verbose exit 1

I am using
Ubuntu 20.04

node --version                
v16.12.0
npm --version                 
8.1.0
@strowk
Copy link
Author

strowk commented Oct 26, 2021

I tried installing with node v14, it worked. At the same time installing npm install --save-dev esbuild@0.13.3 gives a very similar error even with node v14.
I think this problem might be related to #1642 (which was fixed in esbuild@0.13.4) even though I do not have exactly the same log.
Maybe fix made in esbuild@0.13.4 somehow only works with node v14, but not with node v16?

@strowk strowk changed the title Cannot install the package Cannot install the package using node v16 Oct 26, 2021
@evanw
Copy link
Owner

evanw commented Oct 26, 2021

I'm unable to reproduce the problem on macOS. Both node v14 and node v16 work fine for me. In addition, I suspect there is more useful information in the log that was omitted when you copied the last few lines. The copied lines only seem to indicate that there was an error but doesn't say what the cause was.

@nozzlegear
Copy link

nozzlegear commented Nov 16, 2021

I'm having the same problem installing esbuild using node v16 on Ubuntu 21.04. Strangely I did not have this issue using WSL on Windows or on Mac.

Here's the full log file for npm install --save-dev esbuild

Edit: ignoring the postinstall script (npm install --save-dev --ignore-scripts esbuild) got it installed and esbuild seems to be building my project without issue.

@majeedraza1
Copy link

I am also facing same issue.

OS: Ubuntu 20.04
npm 8.2.0
node v16.13.1

npm install

npm ERR! code 1
npm ERR! path /home/sayful/Downloads/vitejs-vite-uun9ga/node_modules/esbuild
npm ERR! command failed
npm ERR! command sh -c node install.js

npm ERR! A complete log of this run can be found in:
npm ERR! /home/sayful/.npm/_logs/2021-12-22T06_00_53_027Z-debug-0.log

@evanw
Copy link
Owner

evanw commented Jan 22, 2022

Unfortunately even that full log doesn't provide enough information. And I'm still not able to reproduce this with these instructions on my Linux VM. Here's what I tried:

$ mkdir test
$ cd test
$ echo {} > package.json

$ lsb_release -ds
Ubuntu 21.10

$ node --version
v16.13.1

$ npm --version
8.1.2

$ npm i esbuild@0.13.3
added 2 packages, and audited 3 packages in 2s
found 0 vulnerabilities

It seems to work fine. I'm going to close this issue because realistically there's nothing I'm going to be able to do about it. If someone is experiencing it themselves then it would be great if they could debug it and post here about what the problem is. If the problem is identified, then the issue can be reopened.

To debug this what you'll want to do is download the esbuild package from npm and extract it manually like this:

$ curl -O https://registry.npmjs.org/esbuild/-/esbuild-0.14.12.tgz
$ tar xf esbuild-0.14.12.tgz
$ rm esbuild-0.14.12.tgz
$ cd package

You can make whatever edits you want to the install script in the package directory (e.g. throwing an error that contains more information so it'll show up in the log) and then try out the installation to see what happens:

$ cd package
$ npm pack # this will generate a new esbuild-0.14.12.tgz
$ cd ..
$ mkdir demo
$ cd demo
$ npm init -y
$ npm i ../package/esbuild-0.14.12.tgz

@evanw evanw closed this as completed Jan 22, 2022
@grancalavera
Copy link

Hi @evanw , thanks for suggesting a debugging approach, I have followed your instructions, and did setup the following test harness:

.
├── esbuild
│   ├── bin
│   │   └── esbuild
│   ├── install.js
│   ├── lib
│   │   ├── main.d.ts
│   │   └── main.js
│   ├── package.json
│   └── README.md
└── esbuild-project
    ├── node_modules
    │   └── esbuild -> ../../esbuild
    ├── package.json
    └── package-lock.json

Where the top level directory esbuild is the extracted contents of package in your solution, and esbuild-project is a test project that depends directly on the contents of esbuild, using file install paths:

{
  "name": "esbuild-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "esbuild": "file:../esbuild"
  }
}

Running npm install reproduces the issue in Ubuntu 20.04:

$ npm install
npm ERR! code 1
npm ERR! path /xxx/xxx/xxx/esbuild-issue/esbuild
npm ERR! command failed
npm ERR! command sh -c node lib/install.js

Adding a node js shebang to lib/install.js as suggested here fixes the issue in my system:

image

and:

$ npm install

up to date, audited 3 packages in 555ms

found 0 vulnerabilities

I'm not sure what are the consequences for all possible operating system, but maybe is something worth looking at.

@evanw
Copy link
Owner

evanw commented Jan 23, 2022

That's very strange because the log line sh -c node lib/install.js suggests the command being run is just node lib/install.js which should be interpreting the file as JavaScript code, not as shell code. Do you have some strange shell installed by any chance? Or maybe you have some wrapper around the node command?

I can add that shebang line because it's harmless (node strips it before it runs the code). But I'm not sure that will actually fix your problem.

Side note: I believe the log line is actually sh -c "node lib/install.js" as a single string, which happens here, but the quotes around the string aren't printed for some reason.

evanw added a commit that referenced this issue Jan 23, 2022
@grancalavera
Copy link

Good observation, this is a screenshot of what I see:

image

No quotes indeed.

From the file you linked above, it seems node determines how to run the script, and chooses to run it as sh -c "node lib/install.js, I can dig a little bit more.

For reference, the first thing I tried was running the script directly with node:

node lib/install.js

Which reaches the js script but fails for a different reason, and I would say is expected to fail since we haven't installed anything yet:

node install.js 
[esbuild] Failed to find package "esbuild-linux-64" on the file system

This can happen if you use the "--no-optional" flag. The "optionalDependencies"
package.json feature is used by esbuild to install the correct binary executable
for your current platform. This install script will now attempt to work around
this. If that fails, you need to remove the "--no-optional" flag to use esbuild.

node:internal/modules/cjs/loader:933
  const err = new Error(message);
              ^

Error: Cannot find module 'esbuild'

This made me think that there's probably nothing wrong with the install script, but with the way it is executed, hence trying the first thing that came to mind which was adding a shebang...

@grancalavera
Copy link

That's very strange because the log line sh -c node lib/install.js suggests the command being run is just node lib/install.js

I think what happens is that npm is handing over the postinstall script to sh, which then is choosing how to run it, even when we know it should run in node. The shebang is the hint sh needs to determine is ok to use node? Not sure, but kind of checks out?

See this:

sh stands for "shell" and shell is the old, Unix like command line interpreter. An interpreter is an program that executes specific instructions written in a programming or scripting language. So basically you say "Execute that file for me".

@evanw
Copy link
Owner

evanw commented Jan 25, 2022

@grancalavera The addition of the shebang line has been released in version 0.14.14: https://unpkg.com/esbuild@0.14.14/install.js. Does that fix the problem for you?

@grancalavera
Copy link

Hi @evanw, no sadly it doesn't work. I'm sure I made a mistake while testing during the weekend. I wrote a little test harness and now I can make it fail consistently:

VERSION=0.14.14

rm -rf esbuild project

curl -O https://registry.npmjs.org/esbuild/-/esbuild-"${VERSION}".tgz
tar xf esbuild-"${VERSION}".tgz
rm esbuild-"${VERSION}".tgz
mv package esbuild

mkdir project
cd project
npm init -y
npm install ../esbuild

That fails the same way as before:

$ ./install-from-tgz.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 24431  100 24431    0     0  50686      0 --:--:-- --:--:-- --:--:-- 50686
Wrote to esbuild-issue/project/package.json:

{
  "name": "project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


npm ERR! code 1
npm ERR! path esbuild-issue/esbuild
npm ERR! command failed
npm ERR! command sh -c node install.js

npm ERR! A complete log of this run can be found in:
npm ERR!npm/_logs/2022-01-27T20_51_15_793Z-debug-0.log

I'll look into it a bit more.

@evanw
Copy link
Owner

evanw commented Jan 31, 2022

There's a report that using node 17.4 fixes this issue: #1973 (comment). If someone who is able to reproduce this issue has the time to debug this, it would still be very useful to understand how far the install script gets before it fails and what's causing it to fail.

@JamesBoon
Copy link

JamesBoon commented Jan 31, 2022

Hi, I got the same error on my machine.

Ubuntu 18.04
node 16.13.2 (installed via snap)
npm 8.4.0

I used the script by @grancalavera to have full control over the installed esbuild version. I just changed the install command to this:

npm install ../esbuild --no-progress --foreground-scripts --loglevel silly 2>&1 | tee

This helps to see all messages from the postinstall script. The tee hack works around a current npm bug which ignores the no-progress flag.

I added some more logging and the error seems to be caused by this line in downloadedBinPath, where require.resolve('esbuild') seems to throw: Error: Cannot find module 'esbuild'

Comparing the log results, it is the exact same error which I would get when calling node install.js directly from within the esbuild folder.

I hope this helps.

@JamesBoon
Copy link

Replacing each line of path.dirname(require.resolve('esbuild')); with a call to this helper function fixed the issue for me:

function getEsbuildLibDir() {   
  try {
      return path.dirname(require.resolve("esbuild"));
  } catch {
      // as "install.js" is always inside the esbuild folder, this should be ok as fallback
      return __dirname; // or better process.cwd()?
  }
}

Some notes to reproduce this issue:

  • no node_modules folder should be present in the target folder
  • no package-lock.json should be present in the target folder
  • it works if called via yarn 1

@evanw, what do you think? Is this fix ok? Should I open a PR?

@evanw
Copy link
Owner

evanw commented Feb 2, 2022

Thanks for the research. This is valuable progress!

I do still wonder what's actually going on though (why require.resolve doesn't work on certain people's machines). Maybe snap-installed node is part of the problem? Ideally we'd be able to figure out why it's happening because esbuild's install script also needs to call require.resolve on packages other than itself and I suspect it can't always rely on being able to do e.g. __dirname + '/../esbuild-linux-64' to find other packages since npm sometimes installs other packages in random other places instead.

Edit: I just put together a new VM and I think I can reproduce it when node is installed with snap. Currently investigating.

@evanw
Copy link
Owner

evanw commented Feb 2, 2022

I was finally able to reproduce this issue in a new VM. I had to install node via snap instead of downloading the official version to reproduce the issue.

But when I debug the failure in my VM, I confusingly narrowed the issue down to the fact that stdout and stderr aren't writable? I tried an install script only containing one line that writes to stdout in a few different ways:

// This "install.js" file installs fine
console.log('test');
// This "install.js" file throws "Error: EACCES: permission denied, write"
process.stdout.write('test\n');
// This "install.js" file also throws "Error: EACCES: permission denied, write"
require('fs').writeSync(1, 'test\n');

I don't understand why this is happening or why console.log works while the others don't. Maybe console.log is buffered somehow? I have no idea how it works under the hood.

These test cases were reduced down from the original problem which was that require('child_process').execFileSync('esbuild', ['--version']) crashed with EACCES: permission denied, write. This was in the install verification step, which is the last step (the package appears to have been installed fine on my machine only to fail on the verification step).

I seem to be able to fix that problem by adding { stdio: 'pipe' } to the call to execFileSync. The documentation for execFileSync says this about the stdio option:

stdio <string> | <Array> Child's stdio configuration. stderr by default will be output to the parent process' stderr unless stdio is specified. Default: 'pipe'.

So maybe the underlying issue here is that when node is installed via snap, stderr is somehow not writable from install scripts?

@evanw
Copy link
Owner

evanw commented Feb 2, 2022

I just released version 0.14.17 with my fix described above and I have verified that it fixes the issue for me. I can no longer reproduce the issue in my VM with the latest version of esbuild. Any chance that fixes esbuild installation for anyone who couldn't install esbuild before?

@JamesBoon
Copy link

JamesBoon commented Feb 2, 2022

Hi @evanw, I'm super sorry, but double checking my test-setup I found out I was actually debugging an error caused by the test setup itself. 🤦

Your patch fixed it 😄
And well... I got troubles reproducing the error, because I used my debug line with npm install ... --foreground-scripts and this fixes it too! Which actually makes perfectly sense reading your findings.

@yabuking84
Copy link

I just had this error when using Snap NodeJS, but no issues when using NodeSource NodeJS.

@JamesBoon
Copy link

@yabuking84 did you try the latest esbuild release? did this fix the issue?

@hpx7
Copy link

hpx7 commented Feb 6, 2022

I'm seeing still issues on Ubuntu, using node install with nvm

npm i esbuild works, but installing globally via npm i -g esbuild fails with:

info run esbuild@0.14.14 postinstall node_modules/esbuild node install.js
info run esbuild@0.14.14 postinstall { code: 1, signal: null }
timing reify:rollback:createSparse Completed in 21ms
timing reify:rollback:retireShallow Completed in 0ms
timing command:install Completed in 762ms
verbose stack Error: command failed
verbose stack     at ChildProcess.<anonymous> (/root/.nvm/versions/node/v16.13.2/lib/node_modules/npm/node_modules/@npmcli/promise-spawn/index.js:64:27)
verbose stack     at ChildProcess.emit (node:events:390:28)
verbose stack     at maybeClose (node:internal/child_process:1064:16)
verbose stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5)
verbose pkgid esbuild@0.14.14
verbose cwd /root/hathora-test
verbose Linux 5.4.0-77-generic
verbose argv "/root/.nvm/versions/node/v16.13.2/bin/node" "/root/.nvm/versions/node/v16.13.2/bin/npm" "i" "-g" "esbuild@0.14.14"
verbose node v16.13.2
verbose npm  v8.1.2
error code 1
error path /root/.nvm/versions/node/v16.13.2/lib/node_modules/esbuild
error command failed
error command sh -c node install.js
error node:internal/modules/cjs/loader:930
error   throw err;
error   ^
error
error Error: Cannot find module '/root/.nvm/versions/node/v16.13.2/lib/node_modules/esbuild/install.js'
error     at Function.Module._resolveFilename (node:internal/modules/cjs/loader:927:15)
error     at Function.Module._load (node:internal/modules/cjs/loader:772:27)
error     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
error     at node:internal/main/run_main_module:17:47 {
error   code: 'MODULE_NOT_FOUND',
error   requireStack: []
error }

@evanw
Copy link
Owner

evanw commented Feb 6, 2022

It looks like it’s saying it can’t even find the install script in the first place? That’s a problem with npm/node, not with esbuild. The install script is published in that location as part of the esbuild package.

@yabuking84
Copy link

yabuking84 commented Feb 7, 2022

@JamesBoon
I didnt yet, I didnt use Snapcraft package manager, I just used NodeSource's install script. Ill try to install latest esbuild release using Snapcraft's package manager.

@strowk
Copy link
Author

strowk commented Jul 8, 2022

I can confirm that change from

"esbuild": "^0.13.0",

to

"esbuild": "^0.14.17",

fixes the issue I initially described

Thanks for the fix!
Sorry I only now noticed this is fixed

@david-commit
Copy link

I'm having the same problem installing esbuild using node v16 on Ubuntu 21.04. Strangely I did not have this issue using WSL on Windows or on Mac.

Here's the full log file for npm install --save-dev esbuild

Edit: ignoring the postinstall script (npm install --save-dev --ignore-scripts esbuild) got it installed and esbuild seems to be building my project without issue.

This solved my issue running npm install on a Vite app. Deleted the directory and generated a new one. Thanks!

@airtonix
Copy link

airtonix commented Apr 5, 2023

@evanw it's worth mentioning that if you're

That's very strange because the log line sh -c node lib/install.js suggests the command being run is just node lib/install.js

I think what happens is that npm is handing over the postinstall script to sh, which then is choosing how to run it, even when we know it should run in node. The shebang is the hint sh needs to determine is ok to use node? Not sure, but kind of checks out?

See this:

sh stands for "shell" and shell is the old, Unix like command line interpreter. An interpreter is an program that executes specific instructions written in a programming or scripting language. So basically you say "Execute that file for me".

sh also doesn't load any profile/*rc, so if you're relying on that to get things sane... then just dont rely on sh doing anything for you here.
This is one of many reasons why the env interpretor exists.

@Monariih
Copy link

Monariih commented Aug 7, 2023

I had the same issue in UBUNTU 23.04 then i run npm i esbuild and it worked

@zwq-88
Copy link

zwq-88 commented Apr 3, 2024

/home/keqing/Mocap-Drones/computer_code/node_modules/esbuild/install.js:117
} catch {
^

SyntaxError: Unexpected token {
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)

@evanw
Copy link
Owner

evanw commented Apr 3, 2024

Optional catch bindings are supported in node ≥10, and esbuild requires node ≥12. So } catch { shouldn't be a syntax error as long as you are using a supported version of node. If that happens because you're using a really old version of node, then you should update to a newer version of node.

@zwq-88
Copy link

zwq-88 commented Apr 3, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests