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

Inconsistent whitespace handling in JSX between vite dev and vite build #360

Closed
7 tasks done
vinodgubbala opened this issue Aug 27, 2024 · 7 comments
Closed
7 tasks done
Labels
bug: upstream Bug in a dependency of Vite

Comments

@vinodgubbala
Copy link

Describe the bug

Description of the Issue:

After migrating from Create React App (CRA) to Vite, I've encountered an inconsistency in how whitespace is handled in JSX between the development vite dev and production vite build. Specifically, JSX strings that are expected to have spaces between them in the rendered output are concatenated without spaces when running the development server (vite dev). However, when building the project using vite build, the whitespace is preserved correctly.

Dev vs Build
image image

Expected Behavior:

The rendered output in both vite dev and vite build should be consistent and should correctly include the space, i.e., "Lorem ispum".

Additional Context:

This issue might be related to how the Vite development server handles JSX parsing differently from the production build process. Ensuring consistency between development and production builds is important for a smooth developer experience.

Having recently moved from Create React App (CRA), this inconsistency is particularly troubling, as it was not an issue with CRA. Achieving consistent behavior across development and production is crucial to our development workflow.

Minimum reproducible project

whitespace-vite.zip

Note

The reproduction URL is working fine, but when I download the same project and run it in local, it causes the issues.

Reproduction

https://stackblitz.com/edit/vitejs-vite-luvdvh?file=index.html

Steps to reproduce

  1. Create a simple React component with JSX that includes a space between two strings:
root.render(<div>{
   "Lorem"
} ispum</div>);
  1. Run the project using vite dev.
  2. Observe that the rendered output is "Loremispum" instead of "Lorem ispum".
  3. Now build the project using vite build and serve the built files.
  4. Observe that the output correctly includes the space, rendering "Lorem ispum".

System Info

System:
    OS: macOS 14.6.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 373.08 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.12.2/bin/yarn
    npm: 10.5.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
    Watchman: 2023.06.12.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 128.0.6613.85
    Chrome Canary: 130.0.6680.0
    Edge: 128.0.2739.42
    Safari: 17.6
  npmPackages:
    @vitejs/plugin-react: ^4.3.1 => 4.3.1 
    vite: ^5.4.2 => 5.4.2

Used Package Manager

yarn

Logs

No response

Validations

Copy link

stackblitz bot commented Aug 27, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@hi-ogawa hi-ogawa transferred this issue from vitejs/vite Aug 27, 2024
@hyrious
Copy link

hyrious commented Aug 27, 2024

This is because the react plugin enables retainLines and transforms your jsx code to:

root.render(<div>{
  "Lorem"}
   ispum </div>);
//^ this is interpreted as no space here.

So it maybe an issue of babel which should preserve leading spaces (using {" "}) in jsx texts.

@vinodgubbala
Copy link
Author

@hyrious thanks for your response. Is there a workaround to get development work as production without having to change the code at all places.

@hi-ogawa
Copy link
Collaborator

I was checking the transform using https://github.com/antfu-collective/vite-plugin-inspect/ and as @hyrious pointed out, the transform got broken by babel's retainLines: true.

console.log(<div>{
  "Lorem"
} ispum </div>)

// ⇓ vite:react-babel

console.log(<div>{
  "Lorem"}
   ispum </div>);

// ⇓ vite:esbuild

console.log(/* @__PURE__ */ jsxDEV("div", { children: [
  "Lorem",
  "ispum "
] }, void 0, true, {
  fileName: "/home/hiroshi/code/others/vite-plugin-react/playground/react/App.jsx",
  lineNumber: 9,
  columnNumber: 13
}, this));

As a workaround, you can lower JSX during babel transform using @babel/plugin-transform-react-jsx-development, which is also what's currently recommended for react-compiler integration.

export default defineConfig(({ command }) => {
const babelPlugins = [['babel-plugin-react-compiler', {}]]
if (command === 'serve') {
babelPlugins.push(['@babel/plugin-transform-react-jsx-development', {}])
}
return {
server: { port: 8900 /* Should be unique */ },
plugins: [react({ babel: { plugins: babelPlugins } })],
}
})

@hi-ogawa hi-ogawa added bug: upstream Bug in a dependency of Vite and removed pending triage labels Aug 27, 2024
@vinodgubbala
Copy link
Author

After little bit of struggle, realised compiler is not required. It is also giving me error.
So I had to use this instead and it working as expected for this scenario.

const babelPlugins = [];
if (command === 'serve') { 
    babelPlugins.push(['@babel/plugin-transform-react-jsx-development', {}]) 
} 

I will give it more testing and let you know if this workaround has a problem.
Thanks for the suggestion.

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Aug 27, 2024

Ah, sorry it was probably confusing. Right, what I meant is to only include @babel/plugin-transform-react-jsx-development when command === 'serve'.

FYI, I also submitted an issue on babel babel/babel#16774

@ArnaudBarre
Copy link
Member

ArnaudBarre commented Aug 29, 2024

I'm closing this as this as been fixed in Babel and released as v7.25.6. Thanks @hi-ogawa for reporting the issue!

@github-actions github-actions bot locked and limited conversation to collaborators Sep 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug: upstream Bug in a dependency of Vite
Projects
None yet
Development

No branches or pull requests

4 participants