Installation error #97

Closed
spadgos opened this Issue Oct 29, 2012 · 19 comments

8 participants

@spadgos

When running sudo npm install -g lodash (and even without the -g), I get the following errors:

** snip **
npm http 304 https://registry.npmjs.org/mkdirp
npm http 304 https://registry.npmjs.org/rimraf
npm http 304 https://registry.npmjs.org/graceful-fs

> lodash@0.9.0 install /usr/local/lib/node_modules/lodash
> node build/post-install

module.js:340
    throw err;
          ^
Error: Cannot find module '/usr/local/lib/node_modules/lodash/build/post-install'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)
npm ERR! error installing lodash@0.9.0
npm WARN This failure might be due to the use of legacy binary "node" 
npm WARN For further explanations, please read
npm WARN /usr/share/doc/nodejs/README.Debian
npm WARN 

npm ERR! lodash@0.9.0 install: `node build/post-install`
npm ERR! `sh "-c" "node build/post-install"` failed with 1
npm ERR! 
npm ERR! Failed at the lodash@0.9.0 install script.
npm ERR! This is most likely a problem with the lodash package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node build/post-install
npm ERR! You can get their info via:
npm ERR!     npm owner ls lodash
npm ERR! There is likely additional logging output above.
npm ERR! 
npm ERR! System Linux 3.5.0-17-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "lodash"
npm ERR! cwd /usr/local/lib/node_modules
npm ERR! node -v v0.6.19
npm ERR! npm -v 1.1.4
npm ERR! code ELIFECYCLE
npm ERR! message lodash@0.9.0 install: `node build/post-install`
npm ERR! message `sh "-c" "node build/post-install"` failed with 1
npm ERR! errno {}
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /usr/local/lib/node_modules/npm-debug.log
npm not ok

The above seems to suggest that I'm running node 0.6.19, but:

$ node -v
v0.8.12

This is on Ubuntu 12.10. In /usr/local/lib/node_modules/ there are other modules which I've installed globally, but no lodash directory.

@kitcambridge

Are you using n, by chance?

@jdalton jdalton closed this Oct 30, 2012
@spadgos

@kitcambridge yeah, I'm using n. I'll try the official channels.

@jdalton
Lodash Utilities member

Maybe this is an npm issue with its support for older versions of Node and scripts.

@pscheit

newer node version fixed the install problem

@spadgos

I just did npm install npm -g and it worked.

This worked for me too.

@kud

I've got some troubles to install lodash on my machine: https://gist.github.com/be24c2c7f6c3d7934e99
Oh and by the way; https://gist.github.com/2c2c4259c7eb5a0353b0

I've reinstalled two times npm / nodejs. I did via aptitude. It seems I've got the latest npm / nodejs versions.
@isaacs @evnm @cowboy @shama Do you have any idea what's wrong here?

@isaacs

This package is not compiling an addon. There's no reason to do these things in postinstall. Please move the build stuff to a prepublish script, so that the computation is done once in a single place where you can debug it, rather than on the machine of every user.

@jdalton
Lodash Utilities member

@isaacs
build/post-install.js exists to download the minifiers if a user is installing lodash globally.
Pre-publish would defeat the purpose wouldn't it?
Which addon requires compilation?
The /vendor/tar/tar.js is a modified version of tar that includes all dependencies and the others should just be normal node modules.

@isaacs

@jdalton Why not just have the minifiers installed locally as devDependencies, and create the minified copy in prepublish?

Addons that require compilation are those that use node-waf to create a .node file from C++ source. Those need to be compiled on the target system, but minification is universal and deterministic for all systems, so you should do it ahead of time, and just include it in the tarball.

@jdalton
Lodash Utilities member

@isaacs
The minifiers are used to minify custom builds created with lodash (builds with lots of variations/configurations).
Can you point to the addon that would be causing the problem?

@isaacs

@jdalton My point is that, if your postinstall script assumes that its dependencies are all loaded, then it will probably end up failing a lot. Also, it'll get run if lodash is the dependency of a package that's being installed globally, which is silly, and not what you want. Also, it won't get run if a package uses the binary out of a locally installed lodash.

In the use-case you describe, it'd be better to have it try to load the stuff it needs the first time it's called, and just error out if that fails.

@jdalton
Lodash Utilities member

@isaacs

My point is that, if your postinstall script assumes that its dependencies are all loaded, then it will probably end up failing a lot.

This is not a dependency issue. Lo-Dash has no traditional module dependencies (non in the package.json). All required modules are rolled into the Lo-Dash package except for UglifyJS and the 5mb Closure Compiler. UglifyJS and Closure Compiler are tar files that live in the lodash/vendor folder. The build/post-install.js script simply attempts to detect if Lo-Dash was installed globally, this is where the errors come up. Then, if it was installed globally, it downloads and extracts the minifiers so that they'll be present when the dev tries to use the lodash build utility.

Also, it'll get run if lodash is the dependency of a package that's being installed globally, which is silly, and not what you want.

It beats pushing 5mb on devs for the much more common case of Lo-Dash being installed as a local dependency.

Also, it won't get run if a package uses the binary out of a locally installed lodash.

That's fine and outside the documented usage.

Most issues have stemmed from devs running older Node v6.x and having compat issues with npm, devs with corrupted npm installs (primarily caused by n or brew), or devs on Windows x64 with exec vs execFile issues.

It would be great if there was a way to specify in the package.json that a dependency was only for global use. That way devs installing it locally could avoid the cost, especially when space is limited.

@isaacs

So, there are two problems with your approach. I'll try to spell them out more clearly, and also suggest a solution to them both.

  1. If I have a globally-installed package which uses lodash as a local dependency, but doesn't use the lodash exe, then you will download the 5mb download, unnecessarily. As you say, this is something you don't want to do.
  2. If I have lodash locally installed, and want to use the lodash executable out of my local env (as part of a start script, for example), then it won't have the extra pieces, and won't function properly.

Since you don't need these extra pieces until and unless the lodash exe is run, you should download them on the first run, only if they're not already present. This approach would allow you to have those added jars and whatnot in every case where they're needed, and none of the cases where they're not needed, and not rely on having lodash behave remarkably different depending on its global-ness. This is a more resilient and effective solution.

npm packages should not behave differently depending on whether or not they are globally installed. What you're really trying to detect is "Will the binary be executed?", but being global is a poor indicator of that, because all you are seeing is "Is npm doing a global install right now?" but you don't know if lodash is the top-level install target (and you can't know that, without adding even more concern-mixing problematic behaviors). Also, locally installed package executables can be and often are executed by their dependents, so you're requiring them to install lodash globally when they really don't have to. (And I don't even know how this would work if lodash is linked, it's probably all messed up.)

The with-the-grain approach is to make lodash have a single set of behavior for global and local installs, and have the executable bootstrap itself if you don't want to include the stuff in the package (which, in this case, I agree is probably not worth the added bytes for the minority use-case it covers).

@cowboy

I'm assuming that the reason lodash might be installed globally is because it has a script component that should be placed in the system path.

If that's the case, do something akin to what we're doing with grunt. Make lodash a lib that should be installed locally, and create a lodash-cli that can be installed globally, that contains the bin script + lodash as a dependency.

@isaacs

Well, if lodash is installed as the dependency of something that's currently being installed globally, then process.env.npm_config_global will be set to "true".

@jdalton
Lodash Utilities member

@isaacs

So, there are two problems with your approach. I'll try to spell them out more clearly, and also suggest a solution to them both.

  1. If I have a globally-installed package which uses lodash as a local dependency, but doesn't use the lodash exe, then you will download the 5mb download, unnecessarily. As you say, this is something you don't want to do.

  2. If I have lodash locally installed, and want to use the lodash executable out of my local env (as part of a start script, for example), then it won't have the extra pieces, and won't function properly.

Right, as I mentioned before these are edge cases and I'm fine with not supporting them or having them incur the minifier file size tax.

Since you don't need these extra pieces until and unless the lodash exe is run, you should download them on the first run, only if they're not already present. This approach would allow you to have those added jars and whatnot in every case where they're needed, and none of the cases where they're not needed, and not rely on having lodash behave remarkably different depending on its global-ness. This is a more resilient and effective solution.

This was our first approach to the issue, but it failed because if Lo-Dash was installed globally we would lack permissions to extract the files within the lodash module directory :(

@jdalton
Lodash Utilities member

I've given it another shot with 9260f3e.

@jden

This looks good - who knew lazy-loading of server-side modules could be so useful? What's nice about this approach is that even in global installs, it doesn't download the external dependencies until you actually go to run the build tool.

@kud
kud commented Jan 5, 2013

It seems to work. I had to install lodash itself before installing grunt-contrib-watch instead not to have any dependance when installing it. It's ok, thank you @jdalton!

@kengz kengz referenced this issue in matthewmueller/date Mar 2, 2016
Merged

NLP-time implementation: language normalization #75

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