-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
A better Prettier CLI and config file #7073
Comments
Prettier's CLI seems to be inspired by ESLint's CLI, which has the exact same problems. I suspect that it's confounded by a reality that nobody uses the CLI in real life. People generally invoke Prettier via an editor extension or a Git hook driver like In #6280 when I tried to use the CLI to "fix all the files," I found that the
Whereas when you use the CLI to "fix all files," it becomes awkward to specify them. As you pointed out, the CLI glob is really only suitable for manually prettifying specific files (and probably it should bypass How would you address this? Here's a few possible approaches:
|
+1 I'll mention that in a large monorepo, we generally prefer for each project to have its own local tooling config files. In most cases the config will be a single line that At least, this was certainly the case for files like Just something to think about in your design discussion. |
Love the idea of explicitness. I'm always for that, for years.
There's
Not meaningful questions. All of this is handled and I don't see any problems with them.
Agreed. Prettier should allow executing without globs, since for example you have
I like that requirement for subcommands.
Totally against. Globs are the best thing. Better cross platformability, easier to control what to pass to tool (Prettier) and etc. Good example for "on top of globs" thing is glob-cache - run first time and cache, run second time and execute a handler hook (passed with full filepath) only if there is a diff between the actual file and the cache file.
Agree. I'm already lost in options.
Not entirely agreeing with that. This can be accomplished with better defaults. For example,
Agree. No shareable configs, no overrides and etc. ESLint has RFC#9 for that too - just single
Agree 💯
Agree 💯
Not entirely agree. Gitignore isn't the best thing, definitely. You clearly can see from above how I have duplicate lines just because the way gitignore works. Here the "file extension mappings" could help too. Just ignore everything by default, except those that are in mappings.
👍
👍 💯
Yup, we don't.
Totally agree 💯
Agree.
True
True. I'm fan of that idea. |
Thanks! Didn’t know about that!
In what situation would you use globs with the CLI described in this issue? |
True. I can't think of now. But it doesn't change the fact that they should be supported. |
Hello @lydell I am interested in designing a new, better configuration structure I think about things like:
|
What do you mean?
I’d say we should strive for making Prettier configs so simple that a more advanced language than JSON isn’t needed.
No. We discussed this when adding support for using config from an npm package, and I haven’t seen this requested. Keep it simple.
Yes. That’s what I call “global” options in the OP.
Combining useTabs and tabWidth sounds good to me.
Yes. There will be a lot of questions and decisions to make if doing this. |
Structure
Is yaml easier than json? Is json easier than yaml? And why?
👍
👍
👍 |
Sorry, I’m not sure what you mean :) Could you elaborate and provide an example?
There is very little JSON syntax to learn. I use yaml every now and then, and I’m always unsure about how to indent, what |
Ok, so we have your example {
"useTabs": true,
"javascript": {
"singleQuote": true,
"parser": "babel-flow"
},
"fileExtensions": {
".foo": "javascript"
},
"ignore": [
"*.html",
"/legacy/",
{ "include": "./.gitignore" },
"!*.config.js"
]
} Modified/brainstorming: {
"indent": ["spaces", 2],
"printWidth": 120,
"javascript": { // Is this a good idea? What if I want to use the same settings for js and ts? What's with jsx and tsx?
"parser": "babel-flow",
"preferredQuotes": "single"
},
"fileExtensions": { // Is this solving a problem? Or does it only flatten `overrides` 🤔
".foo": "javascript"
},
"ignore": [
"*.html",
"/legacy/",
{ "include": "./.gitignore" },
"!*.config.js"
]
} In vscode settings I'm seeing something like We should support json5!!! (comments) We should use readable keys like Should we have a Could we allow custom defined objects/structures for plugins? ... Some more ideas I currently dont know :D
👍 |
Want the same settings for ts as js? Duplicate js. jsx and tsx – are you thinking about jsxSingleQuote and jsxBracketSameLine? Maybe they should be separate languages as well.
We support setting
If you need comments in your Prettier config you are doing your config wrong, IMO. I really like editing JSON with VSCode by the way when there’s a schema for it. Then you don’t need to type the quotes (they are autocompleted) and you get help will all keys and get documentation inline.
Could be worth exploring.
Sounds like a good idea to me. |
mhhh but isn't this ... duplicated 😅
Havn't thought about
I suggest this currently to support different quotes in pug along with js: https://github.com/prettier/plugin-pug#prettier-options
👍
What if someone want to add a TODO comment in the config? IMO: It wont hurt it to support it.
👍 -> Schema is a must have today for a good tool
👍
👍 |
Wait, what? How so? You maybe pass one or two option flags if you don't like the defaults, you specify if you want to overwrite files or print to stdout, and you name the files you want to format. Am I missing some complexity here?
I am pretty strongly opposed to this, fwiw. I very regularly run |
I’m referring to that we support a hundred different file names and languages and .editorconfig and whatnot. And that you have to use globs if you want different settings for some language.
I do, too, sometimes. That’s why I wrote this sketch in the OP:
|
Sure, I suppose it can be complicated if you're running prettier against a whole project with multiple file types all at once, though most of the complexity is in specifying which files to run on and from interactions between languages. For my part, I'm accustomed to using prettier in projects where I am just formatting everything in
Sure but... why? What's the point of the flag? Why not just continue to work correctly without it? And why limit it so much, so that people have to create a config file if they just want to tweak one setting for printing one file? That's the part I really don't get. The CLI works simply and well right now if you are not trying to fuss with multiple file types in the same directory structure; I don't understand where the desire to restrict it comes from. Yes, if people are having trouble with configuration for complicated projects we should look into improving our file-based config, but for the many people for whom |
Edit: moved to #9271 |
WRT module.exports = {
trailingComma: true,
whateverElse: true,
plugins: [
require.resolve("prettier-plugin-xyz"),
require.resolve("@prettier/prettier-xyz"),
]
} I'm happy to explore this further in a separate issue if there is a chance we can add // .prettierrc.js
module.exports = require.resolve("@my-company/prettier-config"); // @my-company/prettier-config/package.json
{
"dependencies": {
"@prettier/prettier-xyz": "^4.2.0",
"prettier-plugin-xyz": "^0.4.2"
},
"main": "index.js"
} // @my-company/prettier-config/index.js
module.exports = {
optionA: true,
optionB: 42,
plugins: [
require.resolve("prettier-plugin-xyz"),
require.resolve("@prettier/prettier-xyz"),
]
} My experiments with Yarn Berry and Prettier so far have failed for Prettier plugins. Even if I add the plugins to project deps (i.e. not via |
@kachkaev Feel free to explore something outside of this proposal, too! I’m afraid this proposal is too ambitious. Since Prettier 2.0 shipped with such good |
@kachkaev |
Really? I thought it's only supported in |
Yep, I checked. |
Wow! Perhaps, we could improve docs to help Yarn PnP / v2 Berry folks with their shared config? Lack of |
Autodiscovery based on |
@kachkaev - I'm curious, do you also use Visual Studio Code and the "Prettier - Code formatter" extension as well? I'm trying to get a similar thing working with the @prettier/plugin-pug package, where I can install said plugin as a devDependency in my NPM config library without also having to explicitly install it as a dependency in every other repository that consumes said NPM config library. Currently when I use Obviously I'm happy that my // .prettierrc.js
module.exports = {
// ... prettier-specific config trimmed ...
plugins: [require('@prettier/plugin-pug')]
// ... pug-specific config trimmed ...
} (Also tagging @Shinigami92 because they are the author of the @prettier/plugin-pug package.) |
@dustin-ruetz thanks for tagging Do other plugins work with autoformat? Like e.g. https://github.com/simonhaenisch/prettier-plugin-organize-imports If not it's a problem of VSCode or an extension. |
@dustin-ruetz, given that you’ve mentioned Most of my projects still have a good old |
I would like to present a completely new take on Prettier’s CLI. Let’s restart from scratch. This isn’t a complete spec or even fully thought through yet. But I’ve been having this on my mind for a long time and wanted to get something out there for discussion.
Goal: Make it easy to do the right thing, and hard to do the wrong thing. Simplify everything! No magic! More explicitness! But still easy to use.
This is a bad thing:
Why?
--check
for CI?prettier
on a couple of files from the command line for a one-off task?Globs and
--foo
-style options for formatting are anti-patterns. I suggest we get rid of them!Instead, imagine having this:
Nice, huh?
prettier
A subcommand is required. Print help.
prettier format [PATH]...
Format files and overwrite them on disk. Like today’s
--write
, more or less.Passing no paths is a shortcut for
prettier format .
.If a PATH points to a file, that file is formatted. If the file is ignored a note about that is printed. (We could have a
--force
flag to override.) If the file type isn’t something that Prettier handles, an error is printed.If a PATH points to a directory, Prettier will automatically find all files to work deeply and format them. Which files exactly? More on that later.
Regarding the output, I think we can take inspiration from black. Let’s be minimal and print stuff like “✨All files formatted with Prettier!” and “✨Formatted 5 files.”
Who will use this?
prettier format
to fix everything.src/components
you can runprettier format src/components
to fix formatting (without having to run on the entire project).Note: I think we should ditch built-in support for globs altogether. They’re not needed! If you need globs for a one-off command, then it’s up to you to get a good shell for yourself and use its globs.
prettier check [PATH]...
Like
prettier format
, but only checks if files are already formatted or not. Like today’s--check
.Who will use this?
prettier format
.prettier stdio FILE
Run Prettier over stdin and stdout.
The FILE argument is required, so that Prettier knows what file type the content is, and if the file should be ignored or not.
If FILE exists,
prettier stdio some/file.js
is a shortcut forprettier stdio some/file.js < some/file.js
.If FILE is ignored, or isn’t supported by Prettier we should use exit codes and stuff to let the caller know.
Who will use this?
prettier stdio tmp/index.min.js | grep foo
.prettier.json
Prettier advocates for few options, but our configuration is super complicated! I think we should take a step back and re-think here.
Let’s have one config file to rule them all – prettier.json. A prettier.json should be required for Prettier to run – this makes Prettier opt-in. For every file Prettier formats, there must be a prettier.json next to it or up the file tree. Only the first found prettier.json is used – there’s no cascade.
Making Prettier opt-in would make it super clear that a project is using Prettier. For example, it would help editor integrations. I hate it when my editor changes an entire file on save when I just wanted to make a quick edit in somebody else’s non-Prettier project.
A
--force
flag could be used for one-off formatting of files with no prettier.json. That would use the default options.--config ~/foo/prettier.json
could use a specified one.prettier.json should specify:
<script>
tags in HTML. Some options can only be set per language and not globally – such as which parser to use..foo
to be handled as JSON, for example. When runningprettier format .
, Prettier looks for all files with known file extensions.*.html
to opt out of HTML formatting, for example.We should continue supporting
"@company/prettier-config"
and similar to load the config from an npm package.prettier init
could be an interactive command to help create a prettier.json. For most people, it will just contain{}
(an empty object), though. For example, it could ask which languages your are/aren’t interested in formatting (based on what files we find on disk) and help set up ignore patterns. And we could detect .gitignore and .eslintignore and ask if we should link to them.Not sure if we need
overrides
.Some options could take a
"editorconfig"
as a value. If so, we’ll look for .editorconfig to figure out what value to use. No magic!What about YAML or TOML or whatever instead of JSON? Keep it simple, I’d say! prettier.json should ideally be so short and simple that we don’t need a fancy language to write it.
Open questions
--range-start
,--range-end
and--cursor-offset
. Not sure how they fit in yet.--insert-pragma
and--require-pragma
. I’ve never used these myself so I’m not sure.--file-info
and--support-info
. Not sure these are going to be needed anymore.The text was updated successfully, but these errors were encountered: