Skip to content
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

Adopt prettier for consistent formatting #811

Open
Gozala opened this issue Mar 3, 2017 · 75 comments
Open

Adopt prettier for consistent formatting #811

Gozala opened this issue Mar 3, 2017 · 75 comments

Comments

@Gozala
Copy link

Gozala commented Mar 3, 2017

@feross what do you think in terms of adopting prettier ? The reason I find it appealing is because in the process of adopting standardjs (see browserhtml/browserhtml#1271) we found out that it's too permissive and does not catch variety of awkward formatting options.

I think with a help of prettier standardjs could deliver promise of "JavaScript Standard Style". Unfortunately that would require some work prettier/prettier#736 to make prettier output standardjs compatible.

@Gozala
Copy link
Author

Gozala commented Mar 3, 2017

Posted this too early going to edit description to include more detalis.

@tunnckoCore
Copy link

tunnckoCore commented Mar 3, 2017

It isnt the right thing in any way. There is ES-Beautifier that tries to do everything using the ESLint ecosystem. That's the right move. Prettier is meant to be opinionated and so it cant be easily integrated and should not be.

The ESLint --fix feature is awesome, and we all should just invest some time to implement autofixes for any rules that we want, then no matter the style we will have awesome consistency prettifier and linter in one. ESLint is the right tool for such things.

ESLint autofix works great here. I think the most important rule that we should implement autofix for is max-len :) Most of the other things are handled already.

And everyone should use standard --fix by default (even, I think it should be enabled by default here) while they run their lints. I even seen few times that there is even two separate npm scripts for just standard called lint and another for fix called fix, wtf? Why? Why you should care and why you want to get tons of warnings most of whose can be autofix with just adding a single flag? It is completely mess.

Just Prettier isn't the right tool. Tried it in last months. Both approaches - first linter than prettiefier and reversed first prettier then the linter - both not work well.

ESLint is most awesome ecosystem in that community, for sure. And we should use it, everyone should use it as both Linter and Prettiefier/Beautifier/Formatter. It just need help.

@Gozala
Copy link
Author

Gozala commented Mar 3, 2017

It isnt the right thing in any way. There is ES-Beautifier that tries to do everything using the ESLint ecosystem. That's the right move. Prettier is meant to be opinionated and so it cant be easily integrated and should not be.

I fundamentally disagree with this. Prettier completely disregards input format and spits out in a consistent format while ESLint and tools around that attempt to preserve typed style & that is pretty much makes consistent styling impossible.

The ESLint --fix feature is awesome, and we all should just invest some time to implement autofixes for any rules that we want, then no matter the style we will have awesome consistency prettifier and linter in one. ESLint is the right tool for such things.

As we tried to adopt standard style we run into too many cases where ESLint was unable to fix things up.

ESLint autofix works great here. I think the most important rule that we should implement autofix for is max-len :) Most of the other things are handled already.

Not in my experience there is ton of things it can not fix and there is also ton of flex in the way code can be formatted, and standard will accept. So at the end of the day we still have majority of comments in pulls about formatting, which defeats the purpose, to us anyway.

And everyone should use standard --fix by default (even, I think it should be enabled by default here) while they run their lints. I even seen few times that there is even two separate npm scripts for just standard called lint and another for fix called fix, wtf? Why? Why you should care and why you want to get tons of warnings most of whose can be autofix with just adding a single flag? It is completely mess.

In my experience fixes actually produce awkward results in terms of formatting, my guess would be that is a reason.

Just Prettier isn't the right tool.

You have not offered any convincing argument to support that claim, just your own opinion that ESLint is a way to go. Please try to offer more constructive input and offer some data to support claims.

Tried it in last months. Both approaches - first linter than prettiefier and reversed first prettier then the linter - both not work well.

I am not surprised given that prettier output does not follow stardardjs rules. By work is required I meant following @jlongster's suggestion to fork prettier to add an options for [standardjs][] rules, hopefully it would be possible to merge it back in.

Can you share list of things that did not work.

ESLint is most awesome ecosystem in that community, for sure. And we should use it, everyone should use it as both Linter and Prettiefier/Beautifier/Formatter. It just need help.

It's cool that you feel that way, but saying everyone should use it is a bit too much. For flow typed projects ESLint has very little to offer other than enforcing formatting as type system deals with actual errors. And given that formatting rules are too flexible result is again, valuable engineering time is spend in discussing or comprehending code formatting.

@feross
Copy link
Member

feross commented Mar 6, 2017

@Gozala We used a separate tool to do formatting in the past (esformatter) and it was a huge maintenance burden and very difficult to get the formatter to output code that would consistently pass standard. See https://github.com/maxogden/standard-format

I think prettier is cool, especially if you want to always re-format code on every git check-in, but it's too aggressive for normal use. It will reformat even code that passes standard, which is just too intrusive to recommend to the average user. If you want to start a separate project that uses prettier to format code in standard style, that sounds like a great idea.

But I think we'll stick with eslint's --fix since we want the following:

  1. One config where we maintain all our rules.
  2. Code that passes should not be reformatted.

I'll also mention that the trend of each release of standard is to tighten up rules to prevent multiple ways of writing the same thing. There are many more formatting rules that will be added slowly in future releases. So issues like the ones you ran into should be caught in future releases once we tighten up those rules.

@feross feross closed this as completed Mar 6, 2017
@timoxley
Copy link
Contributor

timoxley commented Mar 7, 2017

standard doesn't have to do everything. A package.json script that runs prettier then standard --fix should solve your problem and requires no changes to standard at all.

@feross
Copy link
Member

feross commented Mar 7, 2017

@timoxley That's actually a neat solution for folks who prefer more aggressive regular formatting of their code.

@ArmorDarks
Copy link

standard doesn't have to do everything. A package.json script that runs prettier then standard --fix should solve your problem and requires no changes to standard at all.

That won't work, because Prettier and Standard rules will collide. It would be great if efforts could be unified and maintainers of boths libs would agree on same code style...

but it's too aggressive for normal use.

I think it's very strange to hear that from creator of lib, which actually aggressively enforces rules on developer.

@KidkArolis
Copy link

I think this might be one of those things we look back at in a year and be like, why did we cling on manually formatting the code. Auto standard ftw.

@ArmorDarks
Copy link

ArmorDarks commented Mar 20, 2017

I think this might be one of those things we look back at in a year and be like, why did we cling on manually formatting the code. Auto standard ftw.

Yeap. I'm ready for this right now :D

As a side information, about "love" between Standard and Prettier, I will just leave this link here facebook/create-react-app#1847, maybe someone has somthing meaningful to add.

@yoshuawuyts
Copy link
Contributor

I think it's very strange to hear that from creator of lib, which actually aggressively enforces rules on developer.

@ArmorDarks not a fan of your tone here, it could be mistaken as hostile; please show some moderation going forward. Thank you kindly ✨

@ArmorDarks
Copy link

@yoshuawuyts If you read my conversation with Dan by following link above, you will see that I'm adept of Standard and defend it, thus I didn't mean to be hostile.

However, yeap, I was sarcastic, because both libraries enforces aggressive rules, so it sounded like very strange and vague argument against when said by creator of one of those libs.

@feross
Copy link
Member

feross commented Mar 20, 2017

@ArmorDarks I'm a fan of the concept of prettier, but hesitate to adopt it for the following reasons:

  1. Maintaining two configs that will be hard to keep in sync.

  2. It might not be possible to configure prettier in a way that complies with all the ESLint rules that standard enforces. In that case, it would autofix code in a way that doesn't pass standard.

In an ideal world, they'd adopt all the standard rules (and possibly allow configuration to change controversial ones, like no semis, for their users). Then we could use it for --fix.

If you or someone else wants to look into this approach in more detail, I'm open to at least reviewing the PR.

@ArmorDarks
Copy link

Ah, @feross. nevermind my earlier replies.

To make this happen we will need attitude to make compromises and changes from both and Standard, and Prettier communities, to unite efforts and focus on strongest points (linting with Standard and code formatting with Prettier) instead of continuing bikeshedding.

I was hoping to make this happen, to help communities unite, but after pretty much aggressive replies of @gaearon against Standard here facebook/create-react-app#1847 and recently discovered regreatful issue #78 (which explains nature of @gaearon attitude toward Standard) started by @gaearon and supported by @jlongster (creator of Prettier) here #78, I have very little believe that this could happen.

Not in this world, I guess.

@feross
Copy link
Member

feross commented Apr 13, 2017

@ArmorDarks FWIW, I'm open to working with the prettier team. It would be nice to replace standard --fix with prettier.

Do you know if it's possible to configure prettier in a way that produces code that passes standard?

@gaearon
Copy link

gaearon commented Apr 13, 2017

cc @vjeux

@jlongster
Copy link

jlongster commented Apr 13, 2017

You can already use standard without its formatting rules by using https://www.npmjs.com/package/eslint-config-prettier, and then use prettier to format it. Users interested in this issue are mostly interested in getting the non-formatting rules.

For standard using prettier by default, it's going to be hard, not because of any ill will on either sides, but because there is already a significant community behind both so changing the styles is going to force one of them to change a lot. I don't know what the answer is. If someone wants to pursue it we need to more concrete changes to evaluate it.

Note that a large number of people prefer to run prettier in their editor frequently as they are coding (prettier by default is very fast, much faster than eslint, so it's very responsive), and do linting as a less frequent step. I think it makes sense to separate linting and formatting, and allow users to combine them how they want.

@jlongster
Copy link

jlongster commented Apr 13, 2017

Also, prettier's code wrapping (which is an integral part of why it produces good code) is always going to be a big change for the output of standard. There's no way we can make it so that our output is exactly the same as the current eslint --fix with standard, if that's what is being proposed. There wouldn't be much point in switching to prettier anyway then.

@feross
Copy link
Member

feross commented Apr 13, 2017

If we did this, we'd probably want to add a new standard --format flag:

  • standard --fix – make the minimal changes to satisfy standard (uses eslint --fix)
  • standard --format – format the code, which may end up changing valid code (that already satisfies standard) into another valid format (uses prettier)

So, then users that want one canonical format could throw standard --format into their editor or pre-commit hook.

there is already a significant community behind both so changing the styles is going to force one of them to change a lot

The good news here is that standard already has a --fix flag that helps to ease the transition when we change a rule in new major versions. It would be interesting to see a full list of the style differences so we can evaluate how doable this is.

@feross feross reopened this Apr 13, 2017
@kentcdodds
Copy link

Just thought I'd link to this: prettier-standard-formatter. It's actually simpler to implement than prettier-eslint because with standard you don't need to search around for eslint configs/derive prettier options based on those configs. Pretty nifty 👍

@jlongster
Copy link

If we did this, we'd probably want to add a new standard --format flag

I think I'm a little confused what the goal is: do you want to take advantage of prettier's wrapping & forcing consistency on more general things (like function arguments), but still apply standard's whitespace rules? If so, that should be pretty easy: run prettier first and then standard --fix. Is that what standard --format could do?

Or are you all somehow wanting the output of standard to be the same as prettier, meaning it runs prettier as the last step? That seems harder because we would have to talk about all the differences and see if we can reconcile. I'm not sure I see the benefit of that since you could easily run standard --fix after prettier to tweak it to get all the current rules (like a space after function name).

Looks like prettier-standard-formatter is runs prettier first and than standard --fix which makes sense.

I'm happy to continue talking about what potential integrations look like!

@feross
Copy link
Member

feross commented Apr 13, 2017

Thinking out loud here...

I think the goal of standard --format would be to automatically format invalid code so that it's valid according to standard (this is what standard --fix already does) but also, to format even valid code into one unambiguous format.

standard's style rules are designed to be easy for humans to remember, so that you can write valid code without constantly referring to the guide or using a tool to format the code. For that reason, there are a number of situations where standard allows multiple styles.

// both styles are allowed by `standard`
const x = (z) => z
const y = z => z

Since both styles are allowed by standard, then standard --fix will not touch this code. But if standard --format existed, it would rewrite this code (since that's what prettier would do):

const x = z => z
const y = z => z

But this is okay, since the rewritten code is also valid standard!

Then after running prettier, we'd also run standard to check for non-style issues like programmer errors, usage of deprecated APIs, confusing code, etc.

So, it seems like in an ideal world, standard --format would just be prettier plus standard's non-style rules. That is, it would literally run prettier && standard.

To get to this world, I think we'd need unify our style guides so that prettier outputs code that passes standard. (Or so that it's at least possible to configure prettier to output such code.)

@KidkArolis
Copy link

KidkArolis commented Apr 13, 2017 via email

@jlongster
Copy link

jlongster commented Apr 13, 2017

@feross I see, thanks for explaining!

I'm a little worried about both of the communities having to keep in sync and making sure that any changes need to be accepted by both, etc. But I actually think most of the things we'd change are not even whitespace-related or things that standard's formatting rules care about. Usually it's a bug with how things are laid out.

Although.. that might not be true. A good example is that we are thinking of changing how we output ternaries. Right now we happen to output them as standard expects, actually. But we might change that.

I think we're actually very in sync already. The biggest difference is the space after function name. I'm betting that you all don't want to change that, I don't think we're going to change that on prettier... as its a pretty frequent thing in the code. Not sure what we'd do about that specific case, but concerns about not being able to change the format still stands.

Is there any reason it can't be prettier && standard --fix? Does standard --fix behave exactly the same way that standard does, meaning it outputs a list of failures, except that it fixes ones that it knows it can? If so, what would be the downside of that?

@feross
Copy link
Member

feross commented Apr 13, 2017

I think we're actually very in sync already.

Agreed! I think there's a real opportunity here, given a few compromises, to prevent further fragmentation in community conventions.

but concerns about not being able to change the format still stands.

This is a fair point. But I think that if we wanted, we could each do a release where we change a rule or two and then we're totally in sync. Bam. Then we can recommend standard --fix to help our users migrate, and of course with prettier, your users just run it once more and they're upgraded.

There are challenges, but this seems totally doable if both projects want to make it happen.

Is there any reason it can't be prettier && standard --fix? Does standard --fix behave exactly the same way that standard does, meaning it outputs a list of failures, except that it fixes ones that it knows it can? If so, what would be the downside of that?

Your description of how standard --fix behaves is correct. We could totally do prettier && standard --fix. If there's support for that idea amongst the standard team, we could ship that without any cooperation between projects.

But, then we don't get the huge win that would come from aligning our styles. Namely that it would be easy to switch from/to the different projects, prettier would output code that passes standard, and having one fewer style out there in the wild.

@jlongster
Copy link

Awesome. I gotta run but let's keep talking!

Are you all really opinionated about the space after function name? fwiw we've been referencing the airbnb style guide to inform us (as one data point) of what is a popular style, and they don't use the space there. It also seems to be preferred by most people who use it. This is probably going to be the biggest sticking point between our styles, I'm guessing.

@jlongster
Copy link

Also our default style is semicolons, but we just added an option to not use semicolons, so we can do prettier --no-semi && standard but technically standard's default style will still by different than our default style...

@tunnckoCore
Copy link

tunnckoCore commented Apr 14, 2017

most noticeable thing for me is that prettier expands function arguments if >1 and i believe not makes code more readable but more bad. i 'm totally okey with that tobe only when >3.

second one is that it expands objexts, even if object has only one prop. (no space between curlies in objects isng good too {foo:1}, not sure if that can be fixed using esling config prettier) cool it is fixed by v1, im just reading the post now

as about the space after fn name, it's acceptable to relax the rule so there won't have breaking changes.

@tunnckoCore
Copy link

btw, to clarify a bit about fn args expanding, i'm okey with if line is around 80 to do the expanding in multiple lines, even if the only one arg.

sorry, im on phone

@brodycj
Copy link
Contributor

brodycj commented Jan 22, 2019

[...] for example how prettier and standards formats ternary expressions (spelling corrected))

Discussed further in #927. Solving this would be a nice step towards consistency with Prettier formatting. (I did update the prettierx fork with an option for consistency with standard in ternary formatting, would rather see standard consistent with Prettier in ternary formatting.)

[...] and then switch standard to use prettier for whitespace formatting [...]

I have mixed feelings about switching standard to always use Prettier in some form for formatting. I would definitely agree that Prettier has some really nice, advanced formatting capabilities. I can think of the following possible drawbacks:

  • I am not sure if the entire user community would be happy about the extent to which Prettier will reformat the code, even if we would use a fork to go around some of the more controversial decisions. For example: Prettier formats a sensible one-liner into seven lines prettier/prettier#5769 - "Prettier formats a sensible one-liner into seven lines"
  • Prettier seems to incur a "pretty" heavy processing overhead

I think it would be ideal to check and process the code using a series of plugins, like what can be done with eslint and what is generally done with Babel, keeping Prettier reformatting as an optional step.

@KidkArolis
Copy link

Hi..

I've been hanging out on this thread for a while and have recently been thinking more about this problem.

Standard has been enourmously helpful in the last few years in all my projects.
But I've also started using Prettier more and more, because it's code formatting capability is superb.

The two styles are slightly different, which is unfortunate. But standard is not just about code style, it's also about zero config experience, a really well curated set of eslint rules, less decision making.

I've been wanting to get the best of both, prettier's formatting with standard's code quality checks and DX. I've just published a package https://github.com/KidkArolis/healthier that tries to help you combine the two. Hopefully it can be useful to some of you if you're ok with letting go off standard's style formatting rules.

In the future, if standard somehow adopts prettier's formatter, that might be even better. But for now I will see if Healthier can fill that gap.

@NathanielHill
Copy link

@KidkArolis @sheerun

So I've recently switched to prettier-standard which is awesome so far. Unfortunately, I've run into a few issues getting my VSCode setup working ideally. I found the most popular extension for Prettier+Standard had some slight inconsitencies with the prettier-standard CLI, so I ended up just using an extension to run the CLI on file save and that's working great. The thing I'm missing though (and it's huge), is the auto-linting hints I got while typing from the standard extension.

The only way I can see getting that working is adding back babel, eslint, and babel-eslint as project dependencies which is unfortunate. I would set it up globally, but here doesn't appear to be any way to have a global config for standard 🤔

Anyways, just wondering if anyone has gotten format on save and linting while typing working with prettier-standard

@sheerun
Copy link

sheerun commented Feb 26, 2019

You can use healthier or lynt for linting while using prettier-standard just for formatting.

@KidkArolis
Copy link

Healthier has both healthier pkg which behaves mostly like standard and has editor plugins. Or you can use it as eslint-config-healthier combined with eslint editor plugin. That way you can use either prettier or prettier-standard to format the code.

@NathanielHill
Copy link

So, I think the ideal setup would be one npm module (+ one editor plugin) that gives you formatting on save and linting as you type - all with no configuration. Then use husky and lint-staged to enforce both on pre-commit.

I've been using standard now for a few years, but decided to give prettier a try as I was unhappy with certain style inconsistencies that kept occurring.

Long story short, I ended up going down a rabbit hole of inconsistencies between prettier and standard (like spaces after function names 🤦‍♂️). I've since settled on prettier and healthier with a 4-line prettier config. healthier basically just provides an ESLint config that is close to standard but compatible with prettier. If I ever need to customize, I can just drop down to vanilla ESLint.

@KidkArolis Thanks for the awesome package, and great choice on the name 👍

Good bye standard 👋 , it's been fun 🎉

@NathanielHill
Copy link

It's a bummer that prettier can't adopt spaces after function names though. Seems like the only major incompatibility between prettier and standard left. Spaces after function names are so obviously correct from a consistency stand point, but I guess they're sticking with popularity on that one.

@tunnckoCore
Copy link

tunnckoCore commented Feb 28, 2019

@NathanielHill: Spaces after function names are so obviously correct from a consistency stand point

Same was here. But I switched around 1.5 year ago (after years of using Standard) to the @airbnb style - definitely liked it and it makes much more sense to me, cuz I always been a fan of a bit more strictness (pretty great considerations/practices and a lot lot rules).

Looking from the perspective of a few years using both Airbnb+Prettier (~2y) and Standard (2y), I really think that tools like standard, xo and the others that appeared after them, isn't that great thing. It sounds and feels unnecessary stacking of tooling, APIs and deps.

"Zero config". But you can have zero config with picking up basic eslint and preset of your choice (or your own), or just throw the most popular ones - airbnb / standard / prettier, as configs.

Anyway, no bad feelings 🥇 It's probably great from someone who is junior-to-mid or just starting up until realizing he/she (or its community) need better style and quality.

@KidkArolis
Copy link

@tunnckoCore with airbnb, does airbnb code style rules not complain about prettier’s formatting? Or do you turn them off somehow?

Re, “it’s probably great for someone who is junior-to-mid”, a strange way to classify this. Since so many many people and tools use standard who I wouldn’t call junior.. And I have been using standard 5+ years because of its ease of use, when you work on dozens of repos, the zero config approach shines, one dep, does it all, helps you catch the bugs, is not too strict so never complains about things that would get in the way. But admittedly, I actually never really tried airbnb, there’s just not enough time to try all the things :)

@NathanielHill
Copy link

@tunnckoCore I loved standard as well. My main problem was just that it's not opinionated enough! I was getting tired of the mental overhead of dealing with style inconsistencies. It sounds silly, but it's really non-trivial over a large code base. Especially, writing as you are constantly exerting mental overhead to at least try to be consistent. Now that I've got my linting working again (50% of the benefit for me is just catching typos in real time) I'm loving how much less I have to think about styling with prettier 👍

@stale
Copy link

stale bot commented May 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale label May 29, 2019
@ArmorDarks
Copy link

Not a nice bot

@marcospgp
Copy link

I decided to do the same and move back to ESLint with Prettier + eslint-config-standard

@sheerun
Copy link

sheerun commented Oct 17, 2019

Just so you know recent version of prettier-standard has linting feature built-in that lints code with eslint-config-standard configuration after formatting it with prettier: prettier-standard --lint. It also allows for customizing linting rules with .eslintrc

@tsujp
Copy link

tsujp commented Jul 7, 2020

Absolute legend @sheerun

@feross feross added this to the standard 18 milestone Nov 10, 2020
@nolde
Copy link

nolde commented Dec 5, 2020

I am using prettierx along with eslint to avoid having to fix then format, with good results so far. Here are my simplified config files for node.js env, if anyone is interested:

// .eslintrc.js

module.exports = {
  parserOptions: {
    ecmaVersion: 2019,
    sourceType: 'module'
  },
  env: {
    node: true
  },
  plugins: ['prettierx'],
  extends: ['standardize', 'plugin:prettierx/standardize-bundle'],
  settings: {
    prettierx: {
      usePrettierrc: true,
      editorconfig: true
    }
  },
  rules: {
    'generator-star-spacing': [
      'error',
      {
        before: true,
        after: true,
        anonymous: { before: true, after: true },
        method: { before: true, after: true }
      }
    ],
    'prettierx/options': ['error', require('./.prettierrc.json')]
  }
}
// .prettierrc.json
{
  "printWidth": 100,
  "semi": false,
  "singleQuote": true,
  "quoteProps": "consistent",
  "jsxBracketSameLine": true,
  "jsxSingleQuote": true,
  "endOfLine": "lf",
  "spaceBeforeFunctionParen": true,
  "trailingComma": "none",
  "arrowParens": "avoid",
  "bracketSpacing": true,
  "generatorStarSpacing": true,
  "yieldStarSpacing": true
}

As far as I can see, it mostly adheres to standard, and a simple eslint --fix checks and formats everything. It is also supported by all editor eslint plugins I have tried so far.

I have packaged it up and published it in my company's private registry, so I only need to require that package and eslint. Dependencies are basically these:

  "dependencies": {
    "eslint-config-standardize": "^0.7.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettierx": "^0.14.0"
  },
  "peerDependencies": {
    "eslint": ">=7"
  }

@theoludwig
Copy link
Contributor

It is worth considering adding this feature for standard@17 already.
I opened a PR in standard-engine to add prettier support. 😄
standard/standard-engine#231

@mightyiam
Copy link
Member

A different approach: #1872 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests