Closed JamieMason closed 2 years ago
I don't know about other people but I always tend to rm -rf ./package-lock.json ./npm-shrinkwrap.json node_modules
and do a full reinstall.
Trying to make changes while the "cake lid" is still covering the project can expose you to whatever potential problems may lie in npm's resolution logic. Nuking and regenerating from scratch has always resulted in a clean, valid install for me.
We try to avoid nuking npm-shrinkwrap.json
and node_modules
at @venuu if possible, and figure out what packages we'd need to reinstall to create a clean result.
...although, the reason why it might work is that we're still using npm@2 😅 . Looking forward to npm@5 support, as v3 and v4 weren't quite satisfactory for us yet :)
and figure out what packages we'd need to reinstall to create a clean result
Can you expand on this? I don't follow sorry, can you explain the scenario?
Yeah, sorry to leave just a drive-by comment 😅 . Had a hurry to review another PR in the meantime.
Anyway, the approach we've used to upgrade a package is to remove it, install a newer version and shrinkpack it. Then we'd make other team members uninstall the same package before reinstalling from a clean shrinkpack.
Sometimes this method might cause drift between different developer's machines, though, where some sub-sub-dependency is moved to a different part of the module tree.
Basically,
npm uninstall babel-plugin-transform-class-properties
npm install babel-plugin-transform-class-properties@latest
npm run shrink
# The `shrink` npm script does this:
#
# npm prune && npm shrinkwrap --silent && npm run shrinkpack && ./script/clean-shrinkwrap.js
#
# ...where the `shrinkpack` script is just `"shrinkpack": "shrinkpack"`
We're also using a slightly outdated version of shrinkpack
(https://github.com/venuu/shrinkpack/commit/1b92aa158eb6828075e7d20b58cd434568e6c5ea) but it shouldn't matter here.
Oh, and the ./script/clean-shrinkwrap.js
script looks like this:
#!/usr/bin/env node
/**
* this script is just a temporary solution to deal with the issue of npm outputting the npm
* shrinkwrap file in an unstable manner.
*
* See: https://github.com/npm/npm/issues/3581
*/
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
function cleanModule(module, _name) {
delete module.from;
_.forEach(module.dependencies, (mod, dependencyName) =>
cleanModule(mod, dependencyName)
);
}
function deepSorted(objToSort) {
return Object.keys(objToSort)
.sort()
.reduce((result, key) => {
const current = objToSort[key];
if (typeof current === 'object') {
result[key] = deepSorted(current);
} else {
result[key] = current;
}
return result;
}, {});
}
console.log('Reading npm-shrinkwrap.json');
const shrinkwrap = require('../npm-shrinkwrap.json');
console.log('Cleaning shrinkwrap object');
cleanModule(shrinkwrap, shrinkwrap.name);
const cleanShrinkwrapPath = path.join(__dirname, '..', 'npm-shrinkwrap.json');
console.log('Writing cleaned to', cleanShrinkwrapPath);
fs.writeFileSync(
cleanShrinkwrapPath,
`${JSON.stringify(deepSorted(shrinkwrap), null, 2)}\n`
);
Basically, it avoids npm shuffling shrinkwrap contents by sorting them, and removes fields from shrinkpack file that are different if the package is installed via a local copy or resolved from a remote repository.
Then we'd make other team members uninstall the same package before reinstalling from a clean shrinkpack
Just to verify that the install works? ok makes sense.
it avoids npm shuffling shrinkwrap contents by sorting them, and removes fields from shrinkpack file that are different if the package is installed via a local copy or resolved from a remote repository.
From npm5 there is no from
field in the shrinkwrap so that will be a bonus. I like the idea of sorting the keys to try and keep noise in diffs to a minimum, maybe shrinkpack could do this.
Thanks a lot for explaining!
Just to verify that the install works? ok makes sense.
Oh, it's to verify that when they run npm run shrink
again, they'd get no diff. Usually the small differences there'd be won't cause functional differences, not anything large anyway.
From npm5 there is no from field in the shrinkwrap so that will be a bonus
That's a great thing to know, thanks!
I like the idea of sorting the keys to try and keep noise in diffs to a minimum, maybe shrinkpack could do this.
Could be — it has always been a bit weird that built-in shrinkwrap doesn't do this already.
Thanks a lot for explaining!
My pleasure! 🙇
Either as part of the documentation or the CLI, add interactive guides/recipes for;
while updating the lockfile and shrinkpack in a clean and predictable way, avoiding common gotchas.
An analogy I like to use is that a lockfile is a bit like a cake lid. You take it off while you're making changes then put it back after you've finished changing it and want to protect it from the outside world.