Got an npm-based monorepo used by hundreds of developers.
I'm trying to enforce strict peer dependencies, which as I understand it would force the user to make explicit (in a project's package.json
) any hacks that are in place for dependencies that are incompatible with each other (based on the package.json
documentation).
The problem is that npm presents the users with flags that allow them to override this option when set in .npmrc
.
Is there an npm command that will check the peer dependencies are in fact strict (so I can infer the user hasn't run with one of the overriding flags)?
My understanding is that users can still run npm install
with any of the following flags: --legacy-peer-deps
, no-strict-peer-deps
, --force
which alter the way the install algorithm runs allowing potentially incompatible versions of libraries to be used with each other.
If I were to delete the package-lock.json
file and run npm install
, as I understand it, I'll get errors because I don't have the flags that were previously used.
Whether I also get the errors on a fresh checkout (without deleting the package-lock.json
file), I'm yet to confirm.
Got an npm-based monorepo used by hundreds of developers.
I'm trying to enforce strict peer dependencies, which as I understand it would force the user to make explicit (in a project's package.json
) any hacks that are in place for dependencies that are incompatible with each other (based on the package.json
documentation).
The problem is that npm presents the users with flags that allow them to override this option when set in .npmrc
.
Is there an npm command that will check the peer dependencies are in fact strict (so I can infer the user hasn't run with one of the overriding flags)?
My understanding is that users can still run npm install
with any of the following flags: --legacy-peer-deps
, no-strict-peer-deps
, --force
which alter the way the install algorithm runs allowing potentially incompatible versions of libraries to be used with each other.
If I were to delete the package-lock.json
file and run npm install
, as I understand it, I'll get errors because I don't have the flags that were previously used.
Whether I also get the errors on a fresh checkout (without deleting the package-lock.json
file), I'm yet to confirm.
- A pr with dep problems will naturally fail CI tests, this doesn't need any specific npm functionality you ask about – Estus Flask Commented Mar 7 at 10:32
- Can you share examples of "hacks" you're trying to avoid? It would help make the question clearer. – Mureinik Commented Mar 7 at 14:06
- @Mureinik - I've tried to add further information to make my concern clearer – Cheetah Commented Mar 8 at 9:43
1 Answer
Reset to default 1To set the scope for the answer, there's nothing really you can do to prevent developers from using hacks or messing up their own local copy of the project. No matter what protections you include in the repo, in the worst case a developer could edit their local copy and alter them or even remove them altogether.
Thus, the scope of this answer is twofold. First, it aims to minimize such "hacks" happening by mistake - the assumption is that the developers are not malicious but may not always be aware of all the considerations or implementation details behind the dependency management policy, and could use as much help as they could get to not mess it up by mistake. Second, it aims to include safety measures in the CI process to make sure that any PR made by a developer will continue to adhere to the same policy.
There are a few steps that could (and should) be taken here.
As you noted, you should commit your package-lock.json
file with the correct dependencies you expect to use, and document in the project's README.md
or CONTRIBUTING.md
that npm ci
should be used and not npm install
. If these dependencies were installed using non-obvious or non-trivial flags (e.g., --legacy-peer-deps
), don't leave it up to the developers to use them, but add them to an .npmrc
file, and commit that too. See npm ci
's documentation for additional details.
If you really want to make this visible to the developers, you can use a preinstall hook that fails when npm install
is used and only allows npm ci
.
The hook itself can be pretty simple:
// preinstall.js
'use strict';
if (process.env.npm_command === 'install') {
console.error("Don't use 'npm install', use 'npm ci' instead");
process.exit(1);
}
and the definition is as simple as adding it an entry to the scripts
part of package.json
:
{
"name": "myproject",
"version": "1.0.0",
"scripts": {
"preinstall": "node preinstall.js"
},
"dependencies": {
"some-dependency": "1.2.3"
}
}
This isn't foolproof, and it can always be worked around by running npm install --ignore-scripts
, but again - the intend here isn't to hermetically block developers, it's to avoid careless mistakes.
On the CI side, as Estus Flask mentioned in the comments, it should be straight forward - the CI should run npm ci
(so it uses the dependencies defined in package-lock.json
) and the tests, and if the installation fails or causes the tests to fail, the PR should not be merged.
For an extra degree of scrutnity, most collaboration platforms have a way to assign reviewers to specific files or directories (e.g., code owners in GitHub or in GitLab). You could define that changing the package-lock.json
file (meaning dependencies have changed) requires the review of some specific reviewer with the explicit responsibility to make sure any changes to that file adhere to the policy the was defined for the project.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744941198a4602334.html
评论列表(0条)