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

Thoughts about using prettier #1548

Closed
aboyton opened this Issue Sep 4, 2017 · 11 comments

Comments

Projects
None yet
3 participants
@aboyton

aboyton commented Sep 4, 2017

Many of us have been using prettier for a while now and have found it wonderful for formatting code.

Prettier obviously doesn't replace most of the lint rules in Airbnb's style guide (c.f. #1307), but it can definitely compliment it by freeing up a developer to not have to worry about code style (where should line breaks happen, how much should this be indented) and instead worry about more important things (like not using for-of #1122). The prettier website has a bunch of other people's reasons why they like prettier.

Obviously people can use prettier with Airbnb's style guide currently (as many of us have been), but I was wondering if Airbnb had considered making this the default.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Sep 4, 2017

Member
  1. prettier only deals with code formatting, and there's a large number of things that eslint handles that prettier can't, so a linter will still always be required when developing (this isn't something you're claiming, but it's something i've seen many prettier users try to argue)
  2. All code style, including all formatting, is something developers should worry about - the more you lean on autocorrect to fix your spelling, the less you understand about the language you're writing - this is true both in prose and in code. The goal should be to get you to write code that is compliant with the linter on your first try - something that comes from habit and repetition - not to let you mash your keyboard and hope the computer fixes it.
  3. I've still not yet seen a concrete example of something prettier can do, that eslint could not be made to do - there probably are a number of things prettier can do that eslint currently can't, but that time should have been spent writing autofix PRs for eslint instead of developing a different tool.
  4. Nobody's yet taken the time to concretely map out the differences between airbnb's guide, and prettier's formatting (with any necessary prettier options enabled, ofc)

While I'd be quite interested to read the research from the last item above, and would be very interested in hearing a concrete example from the third item — at this time Airbnb does not use prettier, and does not recommend its use.

Member

ljharb commented Sep 4, 2017

  1. prettier only deals with code formatting, and there's a large number of things that eslint handles that prettier can't, so a linter will still always be required when developing (this isn't something you're claiming, but it's something i've seen many prettier users try to argue)
  2. All code style, including all formatting, is something developers should worry about - the more you lean on autocorrect to fix your spelling, the less you understand about the language you're writing - this is true both in prose and in code. The goal should be to get you to write code that is compliant with the linter on your first try - something that comes from habit and repetition - not to let you mash your keyboard and hope the computer fixes it.
  3. I've still not yet seen a concrete example of something prettier can do, that eslint could not be made to do - there probably are a number of things prettier can do that eslint currently can't, but that time should have been spent writing autofix PRs for eslint instead of developing a different tool.
  4. Nobody's yet taken the time to concretely map out the differences between airbnb's guide, and prettier's formatting (with any necessary prettier options enabled, ofc)

While I'd be quite interested to read the research from the last item above, and would be very interested in hearing a concrete example from the third item — at this time Airbnb does not use prettier, and does not recommend its use.

@ljharb ljharb closed this Sep 4, 2017

@ljharb ljharb added the question label Sep 4, 2017

@aboyton

This comment has been minimized.

Show comment
Hide comment
@aboyton

aboyton Sep 4, 2017

Thanks for the quick reply. Unfortunately this reply is not nearly so short 😢

  1. I definitely wasn't suggesting prettier would replace airbnb's style guide (as others have claimed and you realised that I wasn't), but that you could allow prettier be part of it. To quote from the How does it compare to ESLint section of their website:

Linters have two categories of rules:

Formatting rules: eg: max-len, no-mixed-spaces-and-tabs, keyword-spacing, comma-style...

Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it's not possible for the programmer to make a mistake there anymore :)

Code-quality rules: eg no-unused-vars, no-extra-bind, no-implicit-globals, prefer-promise-reject-errors...

Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code!

Instead I'm simply recommending extending eslint-plugin-prettier and either manually disabling all the rules which conflict (or by using the list from eslint-config-prettier but I'm guessing you'd prefer to be explicit rather than depending on another list).


  1. We've found using Airbnb's style guide freed us as a company from having the internal arguments about style which was great. No longer did we need to waste brain power arguing about if we should object-shorthand or dot-notation, we could let you worry about that for us.

We've been using Airbnb's style guide with eslint-plugin-prettier and eslint-config-prettier for a couple of months now on a few hundred thousands of code in our codebase and have found it to be a very similar experience of freeing the mind to worry about more important things. It's hard to describe, but not needing to worry about whitespace (which is really all prettier does) has allowed me to concentrate better on the actual code that I'm writing. I'd highly encourage you to try it. Many in the company were highly dubious at first but were quickly won over.


  1. Technically there's absolutely nothing that prettier can do that you can't do with ESLint, precisely because the lint rule eslint-plugin-prettier does exactly that. You can simply consider prettier as a souped up indentation and line break lint rule (it does a couple of extra things with parens).

That said, that's a bit of a cheats argument and I'm guessing not what you were after.

The indentation rule in ESLint has gone through massive rewrites in ESLint 4. That said, it still won't say that

// good
foo(arg1, arg2, arg3, arg4);

// bad
foo(
  arg1,
  arg2,
  arg3,
  arg4,
);

// bad
foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());

// good
foo(
  reallyLongArg(),
  omgSoManyParameters(),
  IShouldRefactorThis(),
  isThereSeriouslyAnotherOne()
);

This is the trivial example often cited, but it goes much further, how do you break up ternaries on multiple lines, how do you indent arrow functions in big promise chains, etc. With prettier I don't need to remember, I just hit save and it reformats it in a way that looks pretty good.

I used to think that developers should worry about all aspects of code style, but having tried prettier for a few months now I'm glad to now have to worry about it.


  1. Let me try my best. Prettier tries really hard to have as few options as possible (there's a fork that adds more, but I'd argue that's missing a lot of the point of not worrying about style).

The only two options you'd need for prettier are --single-quote and --trailing-comma all.

It's hard for me to know exactly what is different between using prettier to manage "style" and airbnb's rules. One way to see the differences would be to study the source code of eslint-config-prettier.

Another way (what I've done below) is see the practical differences we have on our codebase between the two. Please note that we don't use JSX and so I can't speak of any differences there.

Running prettier over our codebase for the first time reformatted a lot of whitespace changes that Airbnb's style guide didn't enforce. As for actual differences (as in places where the two disagree), the main one we found in our codebase (by number of lines) is:

// airbnb (kinda)
const foo = function (arg, arg2) {

// prettier
const foo = function(arg, arg2) {

That said, 7.1 of the airbnb style guide forbids function declarations like this, we just haven't cleaned all of ours up yet 😰.

As for the actual differences, these are all that I have found:

/// space-in-parens
// airbnb
for (let i = 0; i < foo.length;) {

// prettier (note extra space after the last `;`
for (let i = 0; i < foo.length; ) {
// wrap-iife
// airbnb
(function init() {
  // Body
}());

// prettier
(function init() {
  // Body
})();
// indent
// airbnb
const foo = bar
  ? ''
  : {
    property,
    anotherProperty,
  };

// prettier
const foo = bar
  ? ""
  : {
      property,
      anotherProperty
    };
// indent
// airbnb
this.foo
  .getStuff(
  {
    bar
  },
    {},
  )
  .then()

// prettier
this.foo
  .getStuff(
    {
      bar
    },
    {}
  )
  .then();

One more that I will add is that is seems that using eslint-config-prettier means that the following seems to be enforced. I haven't worked out exactly where that's coming from as it's not prettier as you can see from the playground

// no-confusing-arrow
// airbnb
foobar = someList.reduce(
  (foo, bar) => { return bar === '' ? foo : bar; },
  '',
);

// prettier with eslint-config-prettier?
foobar = someList.reduce(
  (foo, bar) => (bar === '' ? foo : bar),
  '',
);

So to summarise, the conflicts between the two style guides all seem very minor and I do think that adding prettier as an ESLint rule would actually work really well as part of Airbnb's style guide. That said, it's not my guide, so all I can do is ask you to consider it.

aboyton commented Sep 4, 2017

Thanks for the quick reply. Unfortunately this reply is not nearly so short 😢

  1. I definitely wasn't suggesting prettier would replace airbnb's style guide (as others have claimed and you realised that I wasn't), but that you could allow prettier be part of it. To quote from the How does it compare to ESLint section of their website:

Linters have two categories of rules:

Formatting rules: eg: max-len, no-mixed-spaces-and-tabs, keyword-spacing, comma-style...

Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it's not possible for the programmer to make a mistake there anymore :)

Code-quality rules: eg no-unused-vars, no-extra-bind, no-implicit-globals, prefer-promise-reject-errors...

Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code!

Instead I'm simply recommending extending eslint-plugin-prettier and either manually disabling all the rules which conflict (or by using the list from eslint-config-prettier but I'm guessing you'd prefer to be explicit rather than depending on another list).


  1. We've found using Airbnb's style guide freed us as a company from having the internal arguments about style which was great. No longer did we need to waste brain power arguing about if we should object-shorthand or dot-notation, we could let you worry about that for us.

We've been using Airbnb's style guide with eslint-plugin-prettier and eslint-config-prettier for a couple of months now on a few hundred thousands of code in our codebase and have found it to be a very similar experience of freeing the mind to worry about more important things. It's hard to describe, but not needing to worry about whitespace (which is really all prettier does) has allowed me to concentrate better on the actual code that I'm writing. I'd highly encourage you to try it. Many in the company were highly dubious at first but were quickly won over.


  1. Technically there's absolutely nothing that prettier can do that you can't do with ESLint, precisely because the lint rule eslint-plugin-prettier does exactly that. You can simply consider prettier as a souped up indentation and line break lint rule (it does a couple of extra things with parens).

That said, that's a bit of a cheats argument and I'm guessing not what you were after.

The indentation rule in ESLint has gone through massive rewrites in ESLint 4. That said, it still won't say that

// good
foo(arg1, arg2, arg3, arg4);

// bad
foo(
  arg1,
  arg2,
  arg3,
  arg4,
);

// bad
foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());

// good
foo(
  reallyLongArg(),
  omgSoManyParameters(),
  IShouldRefactorThis(),
  isThereSeriouslyAnotherOne()
);

This is the trivial example often cited, but it goes much further, how do you break up ternaries on multiple lines, how do you indent arrow functions in big promise chains, etc. With prettier I don't need to remember, I just hit save and it reformats it in a way that looks pretty good.

I used to think that developers should worry about all aspects of code style, but having tried prettier for a few months now I'm glad to now have to worry about it.


  1. Let me try my best. Prettier tries really hard to have as few options as possible (there's a fork that adds more, but I'd argue that's missing a lot of the point of not worrying about style).

The only two options you'd need for prettier are --single-quote and --trailing-comma all.

It's hard for me to know exactly what is different between using prettier to manage "style" and airbnb's rules. One way to see the differences would be to study the source code of eslint-config-prettier.

Another way (what I've done below) is see the practical differences we have on our codebase between the two. Please note that we don't use JSX and so I can't speak of any differences there.

Running prettier over our codebase for the first time reformatted a lot of whitespace changes that Airbnb's style guide didn't enforce. As for actual differences (as in places where the two disagree), the main one we found in our codebase (by number of lines) is:

// airbnb (kinda)
const foo = function (arg, arg2) {

// prettier
const foo = function(arg, arg2) {

That said, 7.1 of the airbnb style guide forbids function declarations like this, we just haven't cleaned all of ours up yet 😰.

As for the actual differences, these are all that I have found:

/// space-in-parens
// airbnb
for (let i = 0; i < foo.length;) {

// prettier (note extra space after the last `;`
for (let i = 0; i < foo.length; ) {
// wrap-iife
// airbnb
(function init() {
  // Body
}());

// prettier
(function init() {
  // Body
})();
// indent
// airbnb
const foo = bar
  ? ''
  : {
    property,
    anotherProperty,
  };

// prettier
const foo = bar
  ? ""
  : {
      property,
      anotherProperty
    };
// indent
// airbnb
this.foo
  .getStuff(
  {
    bar
  },
    {},
  )
  .then()

// prettier
this.foo
  .getStuff(
    {
      bar
    },
    {}
  )
  .then();

One more that I will add is that is seems that using eslint-config-prettier means that the following seems to be enforced. I haven't worked out exactly where that's coming from as it's not prettier as you can see from the playground

// no-confusing-arrow
// airbnb
foobar = someList.reduce(
  (foo, bar) => { return bar === '' ? foo : bar; },
  '',
);

// prettier with eslint-config-prettier?
foobar = someList.reduce(
  (foo, bar) => (bar === '' ? foo : bar),
  '',
);

So to summarise, the conflicts between the two style guides all seem very minor and I do think that adding prettier as an ESLint rule would actually work really well as part of Airbnb's style guide. That said, it's not my guide, so all I can do is ask you to consider it.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Sep 5, 2017

Member

I'd say the best use of anyone's time would be to PR any "missing" autofixes into eslint - with those, prettier serves no purpose, and there'd be no need to add it.

Member

ljharb commented Sep 5, 2017

I'd say the best use of anyone's time would be to PR any "missing" autofixes into eslint - with those, prettier serves no purpose, and there'd be no need to add it.

@rattrayalex

This comment has been minimized.

Show comment
Hide comment
@rattrayalex

rattrayalex Oct 4, 2017

@ljharb is that feasible with the current eslint autofix primitives? See eg this comment from the eslint repo owner.

Given the core functionality of prettier - line length - I'm not sure that any eslint fix could be made in a form other than "run prettier and use it as an eslint rule", which is what eslint-plugin-prettier accomplishes.

It might be worth your time to experiment with the tool; I think you may find it interesting.

Perhaps Airbnb could fork prettier, and align its output with your own style. I imagine it would be popular.

rattrayalex commented Oct 4, 2017

@ljharb is that feasible with the current eslint autofix primitives? See eg this comment from the eslint repo owner.

Given the core functionality of prettier - line length - I'm not sure that any eslint fix could be made in a form other than "run prettier and use it as an eslint rule", which is what eslint-plugin-prettier accomplishes.

It might be worth your time to experiment with the tool; I think you may find it interesting.

Perhaps Airbnb could fork prettier, and align its output with your own style. I imagine it would be popular.

@rattrayalex

This comment has been minimized.

Show comment
Hide comment
@rattrayalex

rattrayalex Oct 4, 2017

@ljharb if you haven't read the Haskell paper which outlined the core technique prettier uses, you might enjoy it. It's actually not terribly involved.

rattrayalex commented Oct 4, 2017

@ljharb if you haven't read the Haskell paper which outlined the core technique prettier uses, you might enjoy it. It's actually not terribly involved.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Oct 4, 2017

Member

Forking without intent to upstream, nor without intent to make a significantly different product, isn't particularly good for the ecosystem.

That comment is from one (of the many) eslint maintainers (not an "owner"). Nothing about that comment suggests these things are impossible; on the contrary, it suggests that making those changes would be a much better use of time and effort than reinventing the wheel with a new tool.

If improving eslint beyond a certain point isn't feasible, so be it - but we're a) nowhere near that point, and b) a better tool would use eslint configs, the defacto standard for declaring code style, and not just impose a minimally configurable and arbitrary style rubric.

Member

ljharb commented Oct 4, 2017

Forking without intent to upstream, nor without intent to make a significantly different product, isn't particularly good for the ecosystem.

That comment is from one (of the many) eslint maintainers (not an "owner"). Nothing about that comment suggests these things are impossible; on the contrary, it suggests that making those changes would be a much better use of time and effort than reinventing the wheel with a new tool.

If improving eslint beyond a certain point isn't feasible, so be it - but we're a) nowhere near that point, and b) a better tool would use eslint configs, the defacto standard for declaring code style, and not just impose a minimally configurable and arbitrary style rubric.

@rattrayalex

This comment has been minimized.

Show comment
Hide comment
@rattrayalex

rattrayalex Oct 5, 2017

I think a lot of people would love to see a tool with the power of prettier, the configurability of eslint, and the opinions of Airbnb. I know I would.

You might do a little more research into the nature of prettier before claiming that its core functionality is possible with existing eslint tools, however.

rattrayalex commented Oct 5, 2017

I think a lot of people would love to see a tool with the power of prettier, the configurability of eslint, and the opinions of Airbnb. I know I would.

You might do a little more research into the nature of prettier before claiming that its core functionality is possible with existing eslint tools, however.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Oct 5, 2017

Member

I believe all the research you're referring to is about what's possible, not what's impossible. I've yet to see any examples of something with prettier that's never possible with eslint; and if someone can provide one, then that'd be a great motivation to change eslint itself to have a similar approach as prettier does.

Member

ljharb commented Oct 5, 2017

I believe all the research you're referring to is about what's possible, not what's impossible. I've yet to see any examples of something with prettier that's never possible with eslint; and if someone can provide one, then that'd be a great motivation to change eslint itself to have a similar approach as prettier does.

@rattrayalex

This comment has been minimized.

Show comment
Hide comment
@rattrayalex

rattrayalex Oct 5, 2017

Mostly I meant its implementation, not its capabilities. Any program can be built with any Turing-complete tool, but elegant architectures can get the job done better.

I think you'd enjoy a read of its guts if you haven't given them a gander (I know you're busy, so this would go in the "optional pleasure reading" bucket). I'm sure you'd find the source approachable.

As @aboyton mentioned above, the key breakthrough of prettier is expanding/collapsing long expressions across lines based ~purely on AST. I think many people in the industry would be quite impressed if you were able to solve this problem without primitives like those prettier uses.

rattrayalex commented Oct 5, 2017

Mostly I meant its implementation, not its capabilities. Any program can be built with any Turing-complete tool, but elegant architectures can get the job done better.

I think you'd enjoy a read of its guts if you haven't given them a gander (I know you're busy, so this would go in the "optional pleasure reading" bucket). I'm sure you'd find the source approachable.

As @aboyton mentioned above, the key breakthrough of prettier is expanding/collapsing long expressions across lines based ~purely on AST. I think many people in the industry would be quite impressed if you were able to solve this problem without primitives like those prettier uses.

@rattrayalex

This comment has been minimized.

Show comment
Hide comment
@rattrayalex

rattrayalex Oct 5, 2017

To be clear, I do agree with you that it'd be possible to use those primitives as individual eslint rules, and in some ways preferable.

Iit'd just be very difficult to build.

(It'd also be too slow for a formatOnSave editor integration (which, while not something you recommend, is a very popular feature)).

rattrayalex commented Oct 5, 2017

To be clear, I do agree with you that it'd be possible to use those primitives as individual eslint rules, and in some ways preferable.

Iit'd just be very difficult to build.

(It'd also be too slow for a formatOnSave editor integration (which, while not something you recommend, is a very popular feature)).

@aboyton

This comment has been minimized.

Show comment
Hide comment
@aboyton

aboyton Oct 29, 2017

Sorry for the delay, I've been away and a busy with work.

It's 100% possible to make ESLint rules format code like prettier does, but the only real way to do so is to reimplement prettier, or to use prettier as an ESLint rule (which is what eslint-plugin-prettier does).

To demo how much stricter prettier is with styles compared to standard ESLint rules I've run prettier on react-dates as a PoC. airbnb/react-dates#809 As you can see it changed a lot of code to be much more consistent with styling.

aboyton commented Oct 29, 2017

Sorry for the delay, I've been away and a busy with work.

It's 100% possible to make ESLint rules format code like prettier does, but the only real way to do so is to reimplement prettier, or to use prettier as an ESLint rule (which is what eslint-plugin-prettier does).

To demo how much stricter prettier is with styles compared to standard ESLint rules I've run prettier on react-dates as a PoC. airbnb/react-dates#809 As you can see it changed a lot of code to be much more consistent with styling.

@airbnb airbnb locked and limited conversation to collaborators Oct 29, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.