-
Notifications
You must be signed in to change notification settings - Fork 245
RFC for removing figgy-pudding from the CLI dep stack #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ae26205
to
3ba4fb8
Compare
Internally, we also use the following as our base-figgy-pudding config:
We should clean that up too and make it clear which files/commands are actually in need of said config. |
npm-registry-fetch, which then calls make-fetch-happen, etc.), we can | ||
just pass the options object to the deeper dep. | ||
|
||
It's _fine_, really. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Until someone forgets to clone and mutates the config object passed down. I've seen that anti-pattern far too many times inside npm-owned code (with no equivalent to eslint no-param-reassign enabled) to be especially confident of this.
Especially when considering third-party consumers of said npm-owned libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, leaving aside the parameter hygiene issue, you now have to document (or at least be aware of?) config that isn't relevant in the context of a given module. I'm less confident folks will apply this "just pass around a bag of options" pattern 100% consistently across 100% of the stack without some help, either via static analysis, really really good memories, or some other (hopefully) automated process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, figgy-pudding doesn't actually solve most of those problems. Config hygiene has still been a huge problem.
There is no One Weird Trick for this. It comes down to:
- good docs that outline which configs are used
- tests with 100% coverage
- removing configs that are no longer relevant, and refactoring them when they don't make sense (see: only/also/production/optional/dev flags)
- setting good defaults close to where they matter.
Third-party consumers of npm-owned libraries generally just passed in POJOs anyway, which would get figgy-ified. The problem is that once a module is using figgy-pudding, everything it uses must also use figgy-pudding, and it has to be careful not to accidentally exclude an option that one of its deps will end up using, so every level of the stack effectively has to know about every other. It's not encapsulation, it's the opposite of that. And no one can debug its peculiar restrictions.
We can explore doing something clever with config management later, but for now, nothing, and just having good tests, is far better than the something we have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Until someone forgets to clone and mutates the config object passed down.
The recent move to 100% test coverage in all new code and for all dependencies has caught a ton of these types of problems, with far less hazardous side effects or bizarre restrictions imposed by figgy-pudding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason not to Object.freeze it, and easily force the cloning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason not to Object.freeze it, and easily force the cloning?
I don't see why not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A frozen options object goes a long way toward mitigating my concerns (many of which, yes, no program can fix entirely).
BREAKING CHANGE: this removes figgy-pudding, and drops several option aliases. Defaults and behavior are all the same, and this module is now using the canonical camelCase option names that npm v7 will provide to all its deps. Related to: npm/rfcs#102
BREAKING CHANGE: this removes figgy-pudding, and drops several option aliases. Defaults and behavior are all the same, and this module is now using the canonical camelCase option names that npm v7 will provide to all its deps. Related to: npm/rfcs#102
On the documentation angle, the plan that we've adopted as a team is:
At every point, when updating a dep to use pojo options instead of fp:
|
BREAKING CHANGE: this removes figgy-pudding, and drops several option aliases. Defaults and behavior are all the same, and this module is now using the canonical camelCase option names that npm v7 will provide to all its deps. Related to: npm/rfcs#102 PR-URL: #22 Credit: @isaacs Close: #22 Reviewed-by: @claudiahdz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ LGTM
accepted/0000-npm-option-handling.md
Outdated
In all of the CLI's dependencies, remove `figgy-pudding`, and replace with | ||
an options object that uses the canonical names for npm config values. | ||
|
||
In the npm CLI, create n options object with these canonically named |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a typo slipped through (ie. ...create "an" options...
unless you mean n
in terms of Big O notation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"an" == "n" where n === 1
. Which it does in this case. (I'll fix the typo, thanks :)
3ba4fb8
to
b44000b
Compare
See RFC