Add an option to modify when Prettier quotes object properties#5934
Add an option to modify when Prettier quotes object properties#5934azz merged 7 commits intoprettier:masterfrom
Conversation
src/language-js/printer-estree.js
Outdated
| parent.properties || | ||
| parent.body || | ||
| parent.members | ||
| ).some( |
There was a problem hiding this comment.
This .some() call causes printPropertyKey to be O(n^2) in number of props because for each property being printed we look at all other properties, this may cause perf issues for very large objects. Thinking of memoizing the result with mem. Thoughts?
There was a problem hiding this comment.
(We also only need to compute this if quoteProps === 'consistent' but I left it like this during development so all the tests hit this code path.)
There was a problem hiding this comment.
You could do this check in the parent node. I’m not sure in how many contexts object keys can appear but hopefully it’s a small set.
There was a problem hiding this comment.
There are 6 calls to this function, but they're called from property levels of the AST, so I'd need to go one level up the AST again to get the parent node, difficult to figure out all the possible cases, and if we did we'd have to mutate the AST to store the info required.
There was a problem hiding this comment.
What is the mem thing you are talking about, I wasn't aware that we had a way to memoize computation within prettier infra. If we have it, then that would be a great fit.
If it doesn't exist, we can mutate the object for now, it's not ideal but not the end of the world either. I don't think that we're able to reuse ast right now.
There was a problem hiding this comment.
mem is a memoization library, we use it to cache configuration with cosmiconfig.
Thinking more though, we could probably just use a WeakMap where the key is the parent AST node, and the value is whether the object/class/whatever has quoted properties. We'd just create a fresh map for every top-level print call.
There was a problem hiding this comment.
Just implemented WeakMap. I took the simplest approach of using one module-local WeakMap instance, and never clearing it. If my understanding of WeakMap is correct, we should never have to clear it, because as soon as the AST goes out of scope, the keys will get garbage collected and automatically removed from the map. If anyone more experienced with WeakMap thinks otherwise, let me know. 👍
|
Could this option be removed in v2 in favour of |
|
It won't be removed, we still need |
|
@azz what about just making Just trying to play the role of the option philosophy advocate 😉 UPD. Ah, I misunderstood |
|
git diff? |
|
🤔 I thought v2 would be somewhat git-diff heavy by definition. E.g. if #3806 is implemented without becoming an option. |
That's not the vibes I've been picking up. |
|
We need console.log({
'foo': 'foo',
baz: 'baz'
});
// compiles to this:
console.log({foo:"foo",a:"baz"}); |
|
I want to make sure that the O(n^2) behavior is resolved and we don't run the computation unless the proper option is passed. When that's addressed, I'm happy to merge. Thanks @azz for working on it so quickly! It's going to unlock the usage of prettier for all the people using Google Closure Advanced Mode! |
Please don't change the default to one that will generate huge diffs for small changes for some projects. My thoughts on that: #838 (comment) |
vjeux
left a comment
There was a problem hiding this comment.
Great, the WeakMap solution is very elegant and should work well :)
|
🎊🎉 |
|
Maybe we could have a release soon, because of this option. |
|
@kachkaev Just to make it clear, the If it wasn't for the Google Closure Compiler issue, we probably wouldn't add this option at all. |
|
You can use |
|
Ideally, we'd like to use a released version, since we lock down versions in our |
|
It's great to have it. Still as I look ES3 compatibility is still not preserved with Prettier e.g. ESLint for that provides additional It'll be good to have an option to write ES3 compliant code with Prettier |
|
@medikoo This feature has not been released yet. |
|
Then what is your point? |
I think my comment was quite clear, still let me put same message with other words: I'm happy this feature landed in master (although it's not yet released), still it looks incomplete, as Prettier still produces ES3 incompliant output for ES3 compliant input. |
|
Thanks. I didn't see before that most of the second line was a link (to the playground for this PR). I think that ES3 compliance is really niche. If you really need that, I'd say go with |
Indeed that should work, thanks |
This PR introduces a new option to Prettier:
--quote-props <as-needed|preserve|consistent>as-needed(default) - Only add quotes around object properties where required. Current behaviour.preserve- Respect the input (#4327)consistent- If at least one property in an object requires quotes, quote all properties (#838) - this is like ESLint'sconsistent-as-neededoptionRationale
The primary motivation to add an option was to unblock users of the Google Closure Compiler's advanced mode. Removing quotes was actually breaking code, so it was a complete blocker to adopting Prettier. This is detailed in #4327.
While we were adding this option it made sense to also support a popular preference of quoting all keys in an object if one key requires it. e.g.:
Fixes #838
Fixes #4327
docs/directory)CHANGELOG.unreleased.mdfile following the template.✨Try the playground for this PR✨