Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

configuring esbuild with react (replacing create-react-app)

I have a bunch of files with the extension js instead of jsx. (This is a react project).

I setup my package.json for build with such script:

"build": "esbuild src/App.js --bundle --minify --sourcemap --outfile=public/bundle.js",

Upon running it, I have tons of errors all complaining about js syntax such as:

const App = () => {
 return (
  <>
   // some code
  </>
 )
}

where:

> src/App.js:16:2: error: Unexpected "<"
    16 │     <>
       ╵     ^

This is a similar error for many files that have basic div's as return: <div> // content </div> stating that the < in the begging of the div is unexpected. I assume this is because it's not viewing these files as jsx. Is there some sort of flags I can set that will solve this? Changing every single file to a jsx is going to be a mission.

like image 821
Robolisk Avatar asked Aug 28 '26 13:08

Robolisk


2 Answers

I'm migrating a create-react-app full system to Vite. And had this problem, i cannot just rename the extension of hundreds of files at once.

On Vite 4. It's possible to override some eslint rules. You can see the full discussion and solutions evolution on github. https://github.com/vitejs/vite/discussions/3448

The solution i'm using is just reconfigure the vite.config.js file. The solution is setting to optimize all files equally without differentiate plain js from jsx. The best solution will be on the future rename all files to correct extensions, this way the optimizer generate the best results.

The clean file with the workaround solution:

import { defineConfig, transformWithEsbuild } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),

    // Workaround
    {
      name: 'load+transform-js-files-as-jsx',
      async transform(code, id) {
        if (!id.match(/src\/.*\.js$/)) {
          return null;
        }

        // Use the exposed transform from vite, instead of directly
        // transforming with esbuild
        return transformWithEsbuild(code, id, {
          loader: 'jsx',
          jsx: 'automatic', // 👈 this is important
        });
      },
    },
    // End workaround

  ],

  // Workaround before renaming .js to .jsx
  optimizeDeps: {
    esbuildOptions: {
      loader: {
        '.js': 'jsx',
      },
    },
  },
  // End workaround



})

PS: If you are adding the code to your existing vite.config. There is an extra import from vite for the workaround.

like image 194
Gustavo Garcia Avatar answered Aug 31 '26 04:08

Gustavo Garcia


It looks like there is a statement in the esbuild docs: (bottom of the linked block)

esbuild app.js --bundle --loader:.js=jsx

the --loader:.js=jsx statement will use the jsx loader on js files


So your script may look something like:

"build": "esbuild src/App.js --bundle --minify --sourcemap --outfile=public/bundle.js --loader:.js=jsx",

The docs state you can also do this within a config script and not the CLI:

require('esbuild').buildSync({
  entryPoints: ['app.js'],
  bundle: true,
  loader: { '.js': 'jsx' },
  outfile: 'out.js',
})
like image 35
Mike Abeln Avatar answered Aug 31 '26 03:08

Mike Abeln