How to compile JSX with Babel

How to compile JSX with Babel

Install Babel’s compiler, command-line interface, and React preset as development dependencies:

npm install --save-dev @babel/core @babel/cli @babel/preset-react

The React preset teaches Babel how to transform JSX. Put the configuration in babel.config.json at the project root:

{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}

The automatic runtime emits imports for the JSX helpers when needed, so components do not need to import React solely to use JSX. If your project relies on the older runtime, configure "runtime": "classic" instead; that mode transforms JSX into calls to React.createElement and requires React in scope.

Compile JSX into JavaScript

Save a component in a source directory, for example src/App.jsx:

import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}

Run Babel with an input directory, an output directory, and the extensions to process:

npx babel src --out-dir lib --extensions ".js,.jsx"

Babel reads the JSX files under src, applies the configuration, and writes transformed files under lib. The output is ordinary JavaScript; JSX syntax is gone, though imports and exports may remain for a later tool to resolve.

For a single file, specify both paths directly:

npx babel src/App.jsx --out-file lib/App.js

With the automatic runtime, the transformed component uses helper imports from react/jsx-runtime. Babel does not bundle those imports, resolve packages, or produce a complete browser-ready application. A bundler or another module-aware build step must handle that work; treating Babel’s output as a bundle is a common source of missing-module errors.

To inspect the transformation without writing an output file, send the result to standard output:

npx babel src/App.jsx

Integrate the build peek into your workflow

Make the transformation repeatable by putting it in package.json. The script below compiles every JavaScript and JSX file under src into lib:

{
  "scripts": {
    "build": "babel src --out-dir lib --extensions .js,.jsx",
    "build:watch": "babel src --out-dir lib --extensions .js,.jsx --watch"
  }
}

Now npm run build performs the same operation as the direct command, while npm run build:watch recompiles files as they change. Keep generated files out of the source tree; otherwise a broad input path can cause Babel to process its own output on a later run.

If another tool consumes the compiled files, make the dependency explicit in its command. For example, a bundler can read from lib after Babel finishes:

{
  "scripts": {
    "build:jsx": "babel src --out-dir lib --extensions .js,.jsx",
    "bundle": "npm run build:jsx && webpack lib/index.js --output-path dist"
  }
}

Use a bundler only when the application needs bundling, asset handling, or browser-targeted output; Babel alone neither resolves module imports nor copies HTML, stylesheets, or images. If the application is served directly as modules, point the server at the compiled directory and ensure the browser can resolve every import, including the JSX runtime package.

Keep lib and other generated directories out of version control when they are reproducible build artifacts:

{
  "gitignore": [
    "lib/",
    "dist/"
  ]
}

For an actual .gitignore file, write the directory patterns directly rather than storing them in package.json:

lib/
dist/

When debugging the compiled output, enable source maps so browser or runtime errors can refer back to the JSX source:

npx babel src --out-dir lib --extensions .js,.jsx --source-maps

Source: https://www.jsfaq.com/how-to-compile-jsx-with-babel/


You might also like this video

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply