Prettier kills non-breaking spaces in JSX
See original GitHub issuePrettier 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:
- Created 5 years ago
- Comments:14 (11 by maintainers)
For the record, I meant a
{" "}
where there’s an actual non-breaking space between the quotes.They are legal: https://tc39.github.io/ecma262/#prod-WhiteSpace
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?
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):
This is the output when forcing everything to break (there’s a non-breaking space before the “a”, but the one after is missing):
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
in JSX:So the issue couldn’t occur.
Since then, the
s went away in #1165. However, that PR accidentally converted non-breaking spaces to regular spaces.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:
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?