Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

shrinkwrap and optionalDependencies #2679

Closed
seanmonstar opened this issue Aug 6, 2012 · 37 comments
Closed

shrinkwrap and optionalDependencies #2679

seanmonstar opened this issue Aug 6, 2012 · 37 comments

Comments

@seanmonstar
Copy link

We have to shrinkwrap, since some of our dependencies are loose, and that's no good for production. Still, some of the dependencies are optional, depending on the OS.

If we include a shrinkwrap file, then npm doesn't even try to install optional dependencies. And if we shrinkwrap after the optional has been installed, it's no longer optional.

@jbergstroem
Copy link

Same applies to devDependencies. Kinda defeats the purpose of npm install --production as well.

@tadeuszwojcik
Copy link

Exactly, in current form npm-shrinkwrap is not optimal as using it installs dev dependencies when building deployment package what is far from optimal, also when hosting on azure or heroku shrinkwrapped dev deps are also being installed

@dmcinnes
Copy link

+1 -- we just ran into this problem. It loads dev dependencies in production which do not work.."precommit-hook" module for instance looks for the .git directory which doesn't exist and the whole thing fails.

We've had to stop using shrinkwrap altogether.

The different dependency groups should be separated in the shrinkwrap file so we can still install in production mode

@gabrielf
Copy link
Contributor

The devDependencies issue seems to be solved, they are no longer included by default, but it creates another problem similar to the optional dependency problem described above.

If we don't include devDependencies in npm shrinkwrap by using npm shrinkwrap --dev then our build server cannot run the tests since the dev dependencies are not included. If we include the devDependencies in the shrinkwrap then the dev dependencies end up in production which we don't want.

Would this be solved by the npm-shrinkwrap file having the same sections as the package.json? Instead of:

{
"name": "...",
"version": "0.0.0",
"dependencies": {...}
}

It could mimic the package.json:

{
"name": "...",
"version": "0.0.0",
"dependencies": {...},
"devDependencies": {...}
}

Then it would be up to npm install and whether NODE_ENV is set to production if the devDependencies are actually installed or not.

But the use case for optional dependencies is perhaps more complex then this since it's not an all or nothing deal?

@walling
Copy link

walling commented Oct 2, 2013

We ran into this issue as well. We basically want to shrinkwrap the production modules, and leave devDependencies and optionalDependencies in a loose state. There are a few issues:

  • npm shrinkwrap always locks optionalDependencies, if they are installed (no option to disable this behaviour).
  • npm install --dev is impractical as it installs all devDependencies recursively. This takes forever and makes node_modules directory huge.
  • npm install does not install devDepencies, if it wasn't locked before with npm shrinkwrap --dev (but we don't want to lock those).
  • The normal behaviour of npm install is to install devDependencies in package.json, but not recursively. This behaviour is different with a shrinkwrap file.

I haven't tested with npm install --production. I expect that it should not install devDependencies, but I fear that it just installs everything in the shrinkwrap file.

Is anyone working on this? I think it's quite important, now that we are supporting multiple platforms (Linux, OS X, and Windows) for development and production. We don't want to add node_modules to the git repository. npm shrinkwrap could be a perfect solution, but this issue makes it more difficult than it should be.

@luk-
Copy link
Contributor

luk- commented Oct 2, 2013

No, I don't think anyone is working on it (to answer your question). It's
not a high priority issue. Having devDependencies on your server will not
cause you any problems.

On Wednesday, October 2, 2013, Bjarke Walling wrote:

We ran into this issue as well. We basically want to shrinkwrap the
production modules, and leave devDependencies and optionalDependencies in a
loose state. There are a few issues:

  • npm shrinkwrap always locks optionalDependencies, if they are
    installed (no option to disable this behaviour).
  • npm install --dev is impractical as it installs all devDependencies
    recursively. This takes forever and makes node_modules directory huge.
  • npm install does not install devDepencies, if it wasn't locked
    before with npm shrinkwrap --dev (but we don't want to lock those).
  • The normal behaviour of npm install is to install devDependencies in
    package.json, but not recursively. This behaviour is different with a
    shrinkwrap file.

I haven't tested with npm install --production. I expect that it should
not install devDependencies, but I fear that it just installs everything in
the shrinkwrap file.

Is anyone working on this? I think it's quite important, now that we are
supporting multiple platforms (Linux, OS X, and Windows) for development
and production. We don't want to add node_modules to the git repository. npm
shrinkwrap could be a perfect solution, but this issue makes it more
difficult than it should be.


Reply to this email directly or view it on GitHubhttps://github.com/isaacs/npm/issues/2679#issuecomment-25523878
.

@aseemk
Copy link

aseemk commented Oct 24, 2013

I believe some of this was implemented a while back:

  • npm shrinkwrap ignores dev dependencies now by default (only at the top level though).
  • npm install will install dev dependencies now by default after the shrinkwrap dependencies.

Try upgrading to the latest npm.

@IgorMinar
Copy link

the issue with optional dependencies still exists.

if one of my dependencies contains:

  "optionalDependencies": {
   "fsevents": "0.1.6",
   "recursive-readdir": "0.0.2"
  },

and I run npm shrinkwrap it produces npm-shrinkwrap.json that contains:

        "chokidar": {
          "version": "0.8.1",
          "from": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
          "dependencies": {
            "fsevents": {
              "version": "0.1.6",
              "from": "fsevents@0.1.6",
              "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.1.6.tgz"
            },
            "recursive-readdir": {
              "version": "0.0.2",
              "from": "recursive-readdir@0.0.2",
              "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-0.0.2.tgz"
            }
          }
        },

during the subsequent npm install these optional dependencies are attempted to be installed as normal dependencies, which breaks the install if the target platform is not supported by these dependencies (in my case fsevents is mac-only package, but after shrinkwrap it is being installed on linux as well where it fails)

IgorMinar added a commit to IgorMinar/angular.js that referenced this issue Mar 12, 2014
We need to be able to build angular at older shas, without the lock file / shrinkwrap file
the dependencies will resolve differently on different machines and at different times.

This will help us avoid broken builds and hard to track down issues.

I had to manually edit this file after it was generated because `npm shrinkwrap` will install
optional dependencies as if they were hard dependencies.

See: npm/npm#2679 (comment)

My manual edit:

diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 756df44..dc157eb 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -3110,19 +3110,7 @@
         "chokidar": {
           "version": "0.8.1",
           "from": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "dependencies": {
-            "fsevents": {
-              "version": "0.1.6",
-              "from": "fsevents@0.1.6",
-              "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.1.6.tgz"
-            },
-            "recursive-readdir": {
-              "version": "0.0.2",
-              "from": "recursive-readdir@0.0.2",
-              "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-0.0.2.tgz"
-            }
-          }
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz"
         },
         "glob": {
           "version": "3.2.9",
IgorMinar added a commit to IgorMinar/angular.js that referenced this issue Mar 12, 2014
We need to be able to build angular at older shas, without the lock file / shrinkwrap file
the dependencies will resolve differently on different machines and at different times.

This will help us avoid broken builds and hard to track down issues.

I had to manually edit this file after it was generated because `npm shrinkwrap` will install
optional dependencies as if they were hard dependencies.

See: npm/npm#2679 (comment)

My manual edit:

```
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 756df44..dc157eb 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -3110,19 +3110,7 @@
         "chokidar": {
           "version": "0.8.1",
           "from": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "dependencies": {
-            "fsevents": {
-              "version": "0.1.6",
-              "from": "fsevents@0.1.6",
-              "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.1.6.tgz"
-            },
-            "recursive-readdir": {
-              "version": "0.0.2",
-              "from": "recursive-readdir@0.0.2",
-              "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-0.0.2.tgz"
-            }
-          }
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz"
         },
         "glob": {
           "version": "3.2.9",
```

After this change is applied, developers don't need to do anything differently, except when
updating dependencies we need to call `npm update && npm shrinkwrap --dev` followed by reappling
my patch above until npm's bug.
IgorMinar added a commit to angular/angular.js that referenced this issue Mar 12, 2014
We need to be able to build angular at older shas, without the lock file / shrinkwrap file
the dependencies will resolve differently on different machines and at different times.

This will help us avoid broken builds and hard to track down issues.

I had to manually edit this file after it was generated because `npm shrinkwrap` will install
optional dependencies as if they were hard dependencies.

See: npm/npm#2679 (comment)

My manual edit:

```
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 756df44..dc157eb 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -3110,19 +3110,7 @@
         "chokidar": {
           "version": "0.8.1",
           "from": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "dependencies": {
-            "fsevents": {
-              "version": "0.1.6",
-              "from": "fsevents@0.1.6",
-              "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.1.6.tgz"
-            },
-            "recursive-readdir": {
-              "version": "0.0.2",
-              "from": "recursive-readdir@0.0.2",
-              "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-0.0.2.tgz"
-            }
-          }
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz"
         },
         "glob": {
           "version": "3.2.9",
```

Additionally chokidar doesn't list the dependencies above as optional, but that will hopefully
be soon fixed: paulmillr/chokidar#106

In the meantime the patch from the PR above needs to be applied to
node_modules/karma/node_modules/chokidar/package.json before running `npm shrinkwrap`

----

After this change is applied, angular core developers don't need to do anything differently,
except when updating dependencies we need to call `npm update && npm shrinkwrap --dev`
followed by reappling my patch above until npm's bug.

Closes #6653
IgorMinar added a commit to angular/angular.js that referenced this issue Mar 12, 2014
We need to be able to build angular at older shas, without the lock file / shrinkwrap file
the dependencies will resolve differently on different machines and at different times.

This will help us avoid broken builds and hard to track down issues.

I had to manually edit this file after it was generated because `npm shrinkwrap` will install
optional dependencies as if they were hard dependencies.

See: npm/npm#2679 (comment)

My manual edit:

```
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 756df44..dc157eb 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -3110,19 +3110,7 @@
         "chokidar": {
           "version": "0.8.1",
           "from": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz",
-          "dependencies": {
-            "fsevents": {
-              "version": "0.1.6",
-              "from": "fsevents@0.1.6",
-              "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.1.6.tgz"
-            },
-            "recursive-readdir": {
-              "version": "0.0.2",
-              "from": "recursive-readdir@0.0.2",
-              "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-0.0.2.tgz"
-            }
-          }
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-0.8.1.tgz"
         },
         "glob": {
           "version": "3.2.9",
```

Additionally chokidar doesn't list the dependencies above as optional, but that will hopefully
be soon fixed: paulmillr/chokidar#106

In the meantime the patch from the PR above needs to be applied to
node_modules/karma/node_modules/chokidar/package.json before running `npm shrinkwrap`

----

After this change is applied, angular core developers don't need to do anything differently,
except when updating dependencies we need to call `npm update && npm shrinkwrap --dev`
followed by reappling my patch above until npm's bug.

Closes #6653
@jumoel
Copy link

jumoel commented Aug 19, 2015

+1

This is still a problem.

@sarith
Copy link

sarith commented Sep 4, 2015

+1

We just ran into this as well.
Any workarounds?

@othiym23
Copy link
Contributor

othiym23 commented Sep 5, 2015

This is now tagged onto the npm road map. I can't promise that this is something we'll get to immediately, but the npm CLI team does plan to address this within the medium term (6-12 months). It will probably require making some hard choices about how to handle this case in a robust way, and may end up being a semver-major change (in that shrinkwraps that fix this may end up not being interoperable with older versions of npm).

Also, this is at least partially a duplicate of #6801.

@othiym23 othiym23 added the bug label Sep 5, 2015
@jackwanders
Copy link

Hi @othiym23, my organization has also been suffering from this issue. I've read through the v3 source involved in installing and shrink-wrapping dependencies, and from a technical angle, it seems feasible to create a shrinkwrap process that can account for the installation failure of optional dependencies.

The two scenarios that seem to require resolution are:

  1. Properly allowing a shrinkwrapped optional dependency to fail on unsupported platforms
  2. Properly installing an optional dependency of a shrinkwrapped dependency that itself was not installed at the time of shrinkwrapping (i.e. the shrinkwrap occurred on the unsupported platform)

For the first scenario, would it be possible to simply check if the package's parent has it listed in its optionalDependencies, and if so, adding an optional failure rollback to its installSteps?

The second scenario seems a bit more complicated. It would seem that, during the shrinkwrap process, you would want to iterate through all optional dependencies, generating an optionalDependencies block within npm-shrinkwrap.json, including data for all such packages, regardless of whether they are currently installed. Essentially, we want to provide as much data as possible about what WOULD have been installed on the system that's doing the shrinkwrap, assuming the installation did not fail. This would both generate exact specs of non-installed optional dependencies and allow future installations to attempt their own installation of these dependencies, rolling back on failure.

I'm curious to know if there is anything glaringly infeasible about this approach. Given the impact this is having on my team, I'm invested in at least discovering if a resolution is possible, and contributing to the cause if it is.

@lxe
Copy link
Contributor

lxe commented Oct 22, 2015

The workaround I've been doing is:

  1. Remove the entry of your optional dependency from your npm-shrinkwrap.json tree
  2. Add it as an optionaDependencies entry in the package.json of your shrinkwrapped project.

Not ideal, but easy-ish to automate, and not too difficult to manage.

@mikemaccana
Copy link
Contributor

Thanks @lxe I've been doing the same and it works.

Jonahss added a commit to Jonahss/appium that referenced this issue Jan 12, 2016
Jonahss added a commit to Jonahss/appium that referenced this issue Jan 12, 2016
@caseyhoward
Copy link

caseyhoward commented Sep 7, 2016

If this issue isn't going to get fixed, can we get something added to the caveats section of the documentation (https://docs.npmjs.com/cli/shrinkwrap#caveats) that npm shrinkwrap isn't meant to be used between different environments? The optionalDependencies documentation (https://docs.npmjs.com/files/package.json#optionaldependencies) should also be updated to say that it's not compatible with "npm shrinkwrap". It could save people a lot of time. I don't know how many this issue has bitten me.

@Jessidhia
Copy link

I really wish this wasn't just closed as "won't fix, the bug is now intended behavior".

Documenting it as a caveat is fine, but not that it is not meant to be used between different environments, just that it isn't currently supported.

At least I'm pretty sure the overwhelming majority of Mac developers don't use Mac servers for their production hosts. You would also have to get all your developers to run the same OS. Systems like Vagrant and Docker help, but requiring developing in a VM to be able to deal with shrinkwraps is not very nice.

@palmerj3
Copy link
Contributor

palmerj3 commented Sep 8, 2016

@JamieMason apparently this makes no difference, i've learned.

markjaquith pushed a commit to markjaquith/WordPress that referenced this issue Nov 29, 2016
fsevents is macOS only, and npm-shrinkwrap tries to force it onto other architectures, causing build failures. Upstream: npm/npm#2679.

fixes #38657 for the 4.7 branch.

Built from https://develop.svn.wordpress.org/branches/4.7@39368


git-svn-id: http://core.svn.wordpress.org/branches/4.7@39308 1a063a9b-81f0-0310-95a4-ce76da25c4cd
dustinrue pushed a commit to openfcci/wordpress that referenced this issue Dec 7, 2016
fsevents is macOS only, and npm-shrinkwrap tries to force it onto other architectures, causing build failures. Upstream: npm/npm#2679.

fixes #38657 for the 4.7 branch.

Built from https://develop.svn.wordpress.org/branches/4.7@39368


git-svn-id: http://core.svn.wordpress.org/branches/4.7@39308 1a063a9b-81f0-0310-95a4-ce76da25c4cd
lachenmayer added a commit to HackCampus/apply that referenced this issue Dec 7, 2016
josephfrazier added a commit to josephfrazier/browser-extension that referenced this issue Jan 10, 2017
I'm not sure if this actually makes a difference, though. See the
following issues for more info:

* npm/npm#3870
* npm/npm#2679
ks888sk pushed a commit to ks888sk/svntest that referenced this issue Feb 17, 2017
fsevents is macOS only, and npm-shrinkwrap tries to force it onto other architectures, causing build failures. Upstream: npm/npm#2679.

fixes #38657 for the 4.7 branch.

Built from https://develop.svn.wordpress.org/branches/4.7@39368
@felixfbecker
Copy link

This should be a way higher priority to fix. yarn has shown that people need lockfiles, and npm's lockfile system (shrinkwrap) is obviously broken

@thom-nic
Copy link

FWIW, yarn has also had issues with optional dependencies:

For my part, I have had good luck with --production --no-optional using npm@4.2.0.

@ntwb
Copy link

ntwb commented May 28, 2017

Per the release of npm v5: http://blog.npmjs.org/post/161081169345/v500

"package locks no longer exclude optionalDependencies that failed to build. This means package-lock.json and npm-shrinkwrap.json should now be cross-platform. (#15900)"

Does npm v5 fix this optionalDependencies issues, it sounds like it to me 🤔

@ntwb
Copy link

ntwb commented Jun 22, 2017

Arghhhh... I just created a package-lock.json on Mac where fsevents was installed and included in the package-lock.json file, I then created a PR and Travis CI failed the build.

I immediately thought of this issue which I thought was resolved as part of npm 5 (per my own above comment FWIW), turns out it's not.

Once I manually removed fsevents from package-lock.json Travis CI was happy once more 😢

Here's the PR where this occurred: stylelint/stylelint#2670

I'm going to close that PR and add package-lock.json to our .gitignore until this issue is sorted once and for all.

@kyrios
Copy link

kyrios commented Jun 28, 2017

So package-lock.json/shrinkwrap is a dead concept?

kierzniak pushed a commit to friendsofwp/wordpress that referenced this issue Jul 11, 2017
fsevents is macOS only, and npm-shrinkwrap tries to force it onto other architectures, causing build failures. Upstream: npm/npm#2679.

fixes #38657 for the 4.7 branch.

Built from https://develop.svn.wordpress.org/branches/4.7@39368
fcc-machine-user pushed a commit to openfcci/wordpress that referenced this issue Sep 22, 2017
fsevents is macOS only, and npm-shrinkwrap tries to force it onto other architectures, causing build failures. Upstream: npm/npm#2679.

fixes #38657 for the 4.7 branch.

Built from https://develop.svn.wordpress.org/branches/4.7@39368


git-svn-id: http://core.svn.wordpress.org/branches/4.7@39308 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@zkat zkat closed this as completed in bc263c3 Nov 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests