question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Prettier kills non-breaking spaces in JSX

See original GitHub issue

Prettier 1.14.2 Playground link

--parser babylon

Input:

function OhMyWhitespace() {
  return (
    <Dialog
      actions={actions}
      onRequestClose={onCancel}
      open={open}
      title="Supprimer un objectif"
    >
      <p>
        Supprimer l’objectif « {goal.name} » ?
      </p>
    </Dialog>
  )
}

Output:

function OhMyWhitespace() {
  return (
    <Dialog
      actions={actions}
      onRequestClose={onCancel}
      open={open}
      title="Supprimer un objectif"
    >
      <p>
        Supprimer l’objectif «
        {goal.name}
         » ?
      </p>
    </Dialog>
  );
}

BTW, the output above is what I get on the playground (still unacceptable), but not what I get in VSCode with the Prettier extension in ESLint integration mode, where I get the opening French quote mark glued to the opening JSX expr curly. Perhaps because I use the babel-eslint parser?

Expected behavior:

If I have literal unbreakable whitespace in my contents, it’s for a reason. Proper French typesetting, for instance, mandates such whitespace inside French quotation marks, or before double punctuation marks (?!:;).

I used Prettier 1.13.5 so far and all was dandy. Now it strips content from my code! Not just regular ASCII space, no! Special whitespacing too! It changes the resulting display/contents my code produces, which Prettier should never ever do.

Version info

  • VSCode 1.27.1
  • Prettier extension 1.6.1
  • Prettier 1.14.2
  • ESLint 5.5.0
  • ESLint-Config-Prettier 3.0.1
  • ESLint-Plugin-Prettier 2.6.2
  • ESLint-Plugin-React 7.11.1

Prettier config in package.json :

  "eslintConfig": {
    "extends": [
      "standard",
      "prettier",
      "plugin:react/recommended",
      "plugin:jsx-a11y/recommended",
      "plugin:import/errors"
    ],
    "plugins": [
      "prettier",
      "react",
      "jsx-a11y",
      "import"
    ],
    "parser": "babel-eslint",
    "rules": {
      "prettier/prettier": [
        "error",
        {
          "arrowParens": "always",
          "semi": false,
          "singleQuote": true,
          "trailingComma": "es5"
        }
      ],
      "no-irregular-whitespace": 0
    },
    "settings": {
      "react": {
        "version": "16.5.0"
      }
    },
    "env": {
      "browser": true,
      "commonjs": true,
      "es6": true,
      "jest": true,
      "node": true
    }
  },

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:14 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
lydellcommented, Sep 29, 2018

This is not correct, we want to output a &nbsp; if one was inputted in the first place, not a normal space.

For the record, I meant a {" "} where there’s an actual non-breaking space between the quotes.

I don’t believe that non breaking space is a legal space in JavaScript.

They are legal: https://tc39.github.io/ecma262/#prod-WhiteSpace

WhiteSpace::
  <TAB> <VT> <FF> <SP> <NBSP> <ZWNBSP> <USP>

change the doc printer regex to only trim space and \t.

I guess that makes sense anyway, since the doc printer only trims spaces that we added (not spaces from the original source)? And we only ever add spaces and tabs?

1reaction
lydellcommented, Sep 29, 2018

When bisecting, it at first appears as if #4717 broke things. But when looking closer, I think that PR made legit changes that just exposed another bug in more cases.

As far as I can tell, the issue is that when there is a break after some JSX text that ends with whitespace (including non-breaking spaces, which are considered insignificant in JS but significant in JSX), the doc printer trims that whitespace away.

Here’s some test code (there’s non-breaking spaces before and after the “a”, but beware that GitHub might normalize them away):

x = <p> a </p>

This is the output when forcing everything to break (there’s a non-breaking space before the “a”, but the one after is missing):

$ ./bin/prettier.js test.js --print-width 1
x = (
  <p>
     a
  </p>
);

Here’s the doc printer code that trims whitespace (commenting it out makes the missing non-breaking space after the “a” appear):

https://github.com/prettier/prettier/blob/cc83a27a3edb6fcad6da114336761adbebf9b276/src/doc/doc-printer.js#L476-L482

That code was added in #1259 by @vjeux on 2017-04-13. Back then, non-breaking spaces where converted into &nbsp; in JSX:

// Normal print-width.
x = <p>&nbsp;a&nbsp;</p>;
// Short print-width.
x = (
  <p
  >
    &nbsp;a&nbsp;
  </p>
);

So the issue couldn’t occur.

Since then, the &nbsp;s went away in #1165. However, that PR accidentally converted non-breaking spaces to regular spaces.

// Normal print-width (bug: regular spaces instead of non-breaking).
x = <p> a </p>;
// Short print-width (bug: regular spaces instead of non-breaking).
x = (
  <p
  >
    {" "}
    a
    {" "}
  </p>
);

So the spaces were kind of preserved when breaking by turning them into {" "}.

After that, #1658 by @karl fixed the issue with non-breaking spaces being converted into regular spaces. And now when can observe the issue for the first time:

// Normal print-width.
x = <p> a </p>;
// Short print-width (missing non-breaking space after the "a").
x = (
  <p
  >
     a
  </p>
);

So I think this bug has more or less always been there, but concealed in different ways.

How do we solve this? One way would be to turn trailing significant whitespace in JSX into {" "} (containing a non-breaking-space or what have you). But I wonder if the doc printer can safely assume that it can trim whitespace like that? Is that language agnostic?

@vjeux Since you added the the whitespace trimming in the doc printer, what do you think?

@karl, master of JSX in Prettier, do you have any ideas?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Prettier in VS Code is adding {" "} everywhere - Stack Overflow
JSX removes whitespace at the beginning and ending of a line. It also removes blank lines. New lines adjacent to tags are removed; ......
Read more >
prettierx | Yarn - Package Manager
Fast, reliable, and secure dependency management.
Read more >
prettier ignore specific rule | The AI Search Engine You Control
Prettier can be turned off in several different ways. You can: ignore single lines in a file; ignore several lines in a file;...
Read more >
What's New in Emacs 27.1?
It is used for displaying file sizes and disk space in some cases. ... With a prefix arg 'C-u', also kills the buffer...
Read more >
Spacemacs layers list
Support for beautiful HTML mails generated from any org buffer. ... Tildify Mode automatically inserts non-breaking spaces where required ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found