Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does npm3 decides to install flat vs. nested?

My project depends on angular2 beta.6 and another project that depends on angular2 beta.0.

package.json for my project

"dependencies": {
    "angular2": "2.0.0-beta.6",
    "another-project": "0.0.1"
}

package.json for another-project

"dependencies": {
    "angular2": "2.0.0-beta.0",
}

When I npm install my project, it installs angular2 twice:

  1. node_modules/angular2 (beta.6)
  2. node_modules/another-project/angular2 (beta.0)

Trying to understand how npm3 decides to nest angular2 beta.0. Is it because both are called angular2 and hence they can not both sit at the top level?

like image 248
Naresh Avatar asked Feb 14 '16 19:02

Naresh


People also ask

How NPM3 works?

While npm2 installs all dependencies in a nested way, npm3 tries to mitigate the deep trees and redundancy that such nesting causes. npm3 attempts this by installing some secondary dependencies (dependencies of dependencies) in a flat way, in the same directory as the primary dependency that requires it.

What is NPM3?

Nucleoplasmin-3 is a protein that in humans is encoded by the NPM3 gene. NPM3. Identifiers. Aliases. NPM3, PORMIN, TMEM123, nucleophosmin/nucleoplasmin 3.

Which is better yarn or npm?

Speed and Performance. As mentioned above, while NPM installs dependency packages sequentially, Yarn installs in-parallel. Because of this, Yarn performs faster than NPM when installing larger files. Both tools also offer the option of saving dependency files in the offline cache.

Why do we use Bower?

Bower is a package manager, like npm, which manages frameworks, libraries, assets, and utilities, installs them, and makes sure they are up to date. Traditionally, many web development projects combined npm and Bower. npm was used to manage back-end dependencies, while Bower was used for front-end dependencies.


3 Answers

Trying to understand how npm3 decides to nest angular2 beta.0. Is it because both are called angular2 and hence they can not both sit at the top level?

Yes, this is correct. Node code require's a module by name, using code like this:

require('angular2');

Node itself is not aware of the different versions, that's the job of npm, so it just uses whatever module matches in the require path first, relying on matching directory names.

npm accommodates this by installing specific versions in directories for each module when a conflict occurs, so that the require path will include that first.

like image 138
Alexander O'Mara Avatar answered Dec 19 '22 22:12

Alexander O'Mara


Yes, it is because of the beta.0. Because npm has found another version of angular2 on the global level, it will install it locally.

npm3 will install globally dependencies only if there is no other versions of the dependencies on a higher level.

Here is a little example I've found :

  • [node_modules]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0 (uses root version)
    • dep C v1.0
      • dep A v2.0 (this version is different from the root version, so it will be an nested installation)
like image 20
RallionRl Avatar answered Dec 19 '22 22:12

RallionRl


Flat dependencies were introduced in npm v3. The documentation can be found here https://docs.npmjs.com/how-npm-works/npm3.

To answer your question from the docs

However, since B v1.0 is already a top-level dep, we cannot install B v2.0 as a top level dependency. npm v3 handles this by defaulting to npm v2 behavior and nesting the new, different, module B version dependency under the module that requires it -- in this case, module C.

So order matters. The module you install first will get it's dependency on the top level. Subsequent modules will have nested dependencies.

you can run npm dedupe to remove nested module dependencies if they exist in the top level.

like image 32
wyu Avatar answered Dec 19 '22 21:12

wyu