Search code examples
reactjsvisual-studio-codejsxprettier

Prevent vscode prettier wrap jsx attributes which has template literals in it


I found that prettier will wrap my jsx attributes which has more than one template literal to new line.

For examples in my jsx file:

// before formatted and expected result
<DemoFrame html={`${demoPath}/frame1/index.html`} css={`${demoPath}/frame1/index.min.css`} />

// formatted
<DemoFrame
  html={`${demoPath}/frame1/index.html`}
  css={`
    ${demoPath}/frame1/index.min.css
  `}
/>

But these were not changed

<CodeChunk path={`${demoPath}/frame1/index.html`} lang="html" />
<DemoFrame html={`${demoPath}/frame1/index.html`} css={`/frame1/index.min.css`} />
<DemoFrame html={`${demoPath}/frame1/index.html`} css={demoPath + `/frame1/index.min.css`} />

I had tried adding these two lines to settings.json but not working.

"prettier.printWidth": 2000,
"prettier.singleAttributePerLine": false,

Solution

  • In your example for the ones that didn't get formatted, try swapping the usage of template literals in html and css values, for example:

    // Your example (doesn't get formatted)
    <DemoFrame html={`${demoPath}/frame1/index.html`} css={`/frame1/index.min.css`} />
    
    // Swapped usage of template literals (before formatting)
    <DemoFrame html={`/frame1/index.min.css`} css={`${demoPath}/frame1/index.html`} />
    
    // Swapped usage of template literals (after formatting, breaks inside css value)
    <DemoFrame
      html={`/frame1/index.html`}
      css={`
        ${demoPath}/frame1/index.min.css
      `}
    />
    
    // Renamed css attribute to cssHref (doesn't get formatted)
    <DemoFrame html={`/frame1/index.html`} cssHref={`${demoPath}/frame1/index.min.css`} />
    

    If you rename attribute from css to any other name (for example cssHref), it doesn't get broken into multiple lines (doesn't matter how many of your attribute values use template literals). I couldn't find why this behaviour is baked into prettier, but hope this helps anyway.