diff --git a/npm-shrinkwrap.readme.md b/npm-shrinkwrap.readme.md index 59083339c9..d57ad1e930 100644 --- a/npm-shrinkwrap.readme.md +++ b/npm-shrinkwrap.readme.md @@ -3,16 +3,11 @@ All of our npm dependencies are locked via the `npm-shrinkwrap.json` file for th - our project has lots of dependencies which update at unpredictable times, so it's important that we update them explicitly once in a while rather than implicitly when any of us runs npm install - locked dependencies allow us to do reuse npm cache on travis, significantly speeding up our builds - (by 5min or more) + (by 5 minutes or more) - locked dependencies allow us to detect when node_modules folder is out of date after a branch switch which allows us to build the project with the correct dependencies every time -However npm's shrinkwrap is known to be buggy, so we need to take some extra steps to deal with this. -The most important step is generating the npm-shrinkwrap.clean.js which is used during code reviews -or debugging to easily review what has actually changed. -See https://github.com/npm/npm/issues/3581 for related npm issue. A common symptom is that the `from` -property of various dependencies in `npm-shrinkwrap.json` "arbitrarily" changes depending on when and -where the shrinkwrap command was run. +We also generate `npm-shrinkwrap.clean.js` file which is used during code reviews or debugging to easily review what has actually changed without extra noise. To add a new dependency do the following: @@ -20,14 +15,11 @@ To add a new dependency do the following: installation. This is due to an optional `fsevents` dependency that is really required on MacOS to get good performance from file watching. 2. make sure you are in sync with `upstream/master` -3. ensure that your `node_modules` directory is not stale or poisoned by doing a clean install with - `rm -rf node_modules && npm install` +3. ensure that your `node_modules` directory is not stale by running `npm install` 4. add a new dependency via `npm install --save-dev ` -5. update npm-shrinkwrap.json with `npm shrinkwrap --dev` -6. run `./tools/npm/clean-shrinkwrap.js` -7. these steps should change 3 files: `package.json`, `npm-shrinkwrap.json` and - `npm-shrinkwrap.clean.json` -8. commit changes to these three files and you are done +5. run `./tools/npm/reshrinkwrap` +6. these steps should change 3 files: `package.json`, `npm-shrinkwrap.json` and `npm-shrinkwrap.clean.json` +7. commit changes to these three files and you are done To update existing dependency do the following: @@ -36,16 +28,14 @@ To update existing dependency do the following: installation. This is due to an optional `fsevents` dependency that is really required on MacOS to get good performance from file watching. 2. make sure you are in sync with `upstream/master`: `git fetch upstream && git rebase upstream/master` -3. ensure that your `node_modules` directory is not stale or poisoned by doing a clean install with - `rm -rf node_modules && npm install` +3. ensure that your `node_modules` directory is not stale by running `npm install` 4. run `npm install --save-dev @` or `npm update ` to update to the latest version that matches version constraint in `package.json` -5. relock the dependencies with `npm shrinkwrap --dev` -6. clean up the shrinkwrap file for review with `./tools/npm/clean-shrinkwrap.js` -7. these steps should change 2 files: `npm-shrinkwrap.json` and `npm-shrinkwrap.clean.json`. +5. run `./tools/npm/reshrinkwrap` +6. these steps should change 2 files: `npm-shrinkwrap.json` and `npm-shrinkwrap.clean.json`. Optionally if you used `npm install ...` in the first step, `package.json` might be modified as well. -8. commit changes to these three files and you are done +7. commit changes to these three files and you are done To Remove an existing dependency do the following: @@ -54,10 +44,8 @@ To Remove an existing dependency do the following: installation. This is due to an optional `fsevents` dependency that is really required on MacOS to get good performance from file watching. 2. make sure you are in sync with `upstream/master`: `git fetch upstream && git rebase upstream/master` -3. ensure that your `node_modules` directory is not stale or poisoned by doing a clean install with - `rm -rf node_modules && npm install` +3. ensure that your `node_modules` directory is not stale by running `npm install` 4. run `npm uninstall --save-dev @` -5. relock the dependencies with `npm shrinkwrap --dev` -6. clean up the shrinkwrap file for review with `./tools/npm/clean-shrinkwrap.js` -7. these steps should change 3 files: `npm-shrinkwrap.json` and `npm-shrinkwrap.clean.json`. -8. commit changes to these three files and you are done +5. run `./tools/npm/reshrinkwrap` +6. these steps should change 3 files: `npm-shrinkwrap.json` and `npm-shrinkwrap.clean.json`. +7. commit changes to these three files and you are done diff --git a/tools/npm/clean-shrinkwrap.js b/tools/npm/clean-shrinkwrap.js index 40e3cd15a9..3fd05e1c70 100755 --- a/tools/npm/clean-shrinkwrap.js +++ b/tools/npm/clean-shrinkwrap.js @@ -27,12 +27,12 @@ function cleanModule(moduleRecord, name) { } -console.log('Reading npm-shrinkwrap.json'); +//console.log('Reading npm-shrinkwrap.json'); var shrinkwrap = require('../../npm-shrinkwrap.json'); -console.log('Cleaning shrinkwrap object'); +//console.log('Cleaning shrinkwrap object'); cleanModule(shrinkwrap, shrinkwrap.name); var cleanShrinkwrapPath = path.join(__dirname, '..', '..', 'npm-shrinkwrap.clean.json'); -console.log('Writing cleaned to', cleanShrinkwrapPath); +console.log('writing npm-shrinkwrap.clean.json'); fs.writeFileSync(cleanShrinkwrapPath, JSON.stringify(sorted(shrinkwrap), null, 2) + "\n"); diff --git a/tools/npm/copy-npm-shrinkwrap b/tools/npm/copy-npm-shrinkwrap index cbc722c199..b36528ec04 100755 --- a/tools/npm/copy-npm-shrinkwrap +++ b/tools/npm/copy-npm-shrinkwrap @@ -11,6 +11,7 @@ var PROJECT_ROOT = path.join(__dirname, '../../'); process.chdir(PROJECT_ROOT); if (fs.existsSync(NPM_SHRINKWRAP_FILE)) { + console.log('copying shrinkwrap fingerprint to', NPM_SHRINKWRAP_CACHED_FILE); fse.copySync(NPM_SHRINKWRAP_FILE, NPM_SHRINKWRAP_CACHED_FILE); } else { console.warn(`${NPM_SHRINKWRAP_FILE} not found. Copy operation will be skipped.`); diff --git a/tools/npm/reshrinkwrap b/tools/npm/reshrinkwrap new file mode 100755 index 0000000000..b8f4c1454a --- /dev/null +++ b/tools/npm/reshrinkwrap @@ -0,0 +1,15 @@ +#!/usr/bin/env node + +'use strict'; + +let childProcess = require('child_process'); + +childProcess.spawn('npm', ['shrinkwrap', '--dev'], {stdio: 'inherit'}).on('exit', (exitCode) => { + if (exitCode !== 0) return; + + childProcess.fork('./tools/npm/clean-shrinkwrap.js').on('exit', (exitCode) => { + if (exitCode !== 0) return; + + childProcess.fork('./tools/npm/copy-npm-shrinkwrap'); + }); +});