Skip to content

Working with Babel and JSX Working with Babel and Flow Working with BabelJS and Gulp BabelJs - Examples

JSX is an XML-like syntax extension to JavaScript, commonly used with libraries like React to describe UI structures. Browsers don’t understand JSX natively, so it needs to be transpiled into regular JavaScript function calls. Babel is the standard tool for this transformation.

JSX allows you to write markup that looks similar to HTML directly within your JavaScript code. For example:

const element = <h1 className="greeting">Hello, world!</h1>;

Babel, with the appropriate preset (like @babel/preset-react), transforms this JSX into something like:

const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);

Benefits of using JSX (often cited in the context of React):

  • Readability: UI structure is more visually intuitive than nested function calls.
  • Familiarity: Developers familiar with HTML can quickly grasp JSX.
  • Error Detection: Babel can catch syntax errors in JSX during compilation.
  • Component-Based: Works naturally with component-based architectures.

We’ll demonstrate setting up a project to transpile JSX using Babel, typically in conjunction with Webpack for bundling a React application.

Create a new project and initialize npm:

mkdir babel-jsx-example
cd babel-jsx-example
npm init -y

Install React, ReactDOM, Babel packages, and Webpack related packages:

npm install --save react react-dom
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader webpack webpack-cli webpack-dev-server html-webpack-plugin

Key packages:

  • react, react-dom: The React library itself.
  • @babel/core: Babel’s core engine.
  • @babel/preset-env: For transpiling modern JavaScript (ES2015+) features.
  • @babel/preset-react: For transpiling JSX and other React-specific syntax.
  • babel-loader: Webpack loader to integrate Babel into the build process.
  • webpack, webpack-cli: The module bundler.
  • webpack-dev-server: For a local development server with live reloading.
  • html-webpack-plugin: Simplifies creation of HTML files to serve your webpack bundles.

Create babel.config.json in your project root:

babel.config.json
{
"presets": [
"@babel/preset-env",
["@babel/preset-react", {
"runtime": "automatic" // For React 17+ new JSX transform
}]
]
}

The "runtime": "automatic" option for @babel/preset-react enables the new JSX transform introduced in React 17, which automatically imports necessary functions from React and doesn’t require import React from 'react' in every JSX file (though it’s often still good practice for clarity). For older React versions, you might use "runtime": "classic" or omit the runtime option.

Create webpack.config.js in your project root:

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // Process both .js and .jsx files
exclude: /node_modules/,
use: {
loader: 'babel-loader',
// Babel options are taken from babel.config.json
},
},
{
test: /\.css$/i, // Example: for CSS files
use: ['style-loader', 'css-loader'],
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // Your source HTML file
}),
],
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true, // Automatically open in browser
},
resolve: {
extensions: ['.js', '.jsx'], // Allow importing .jsx files without extension
},
};

Create a src directory. Inside it, add index.html, App.jsx (or App.js), and index.js.

src/index.html (template for HtmlWebpackPlugin):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React with Babel and JSX</title>
</head>
<body>
<div id="root"></div> <!-- React will mount here -->
</body>
</html>

src/App.jsx (A simple React component):

// src/App.jsx
// import React from 'react'; // Not strictly needed with "runtime": "automatic"
function App() {
const appName = "My Awesome React App";
const user = {
name: "Chris",
isLoggedIn: true
};
const styles = {
padding: '20px',
border: '1px solid #ccc',
borderRadius: '5px',
backgroundColor: user.isLoggedIn ? 'lightgreen' : 'lightcoral'
};
return (
<div style={styles}>
<h1>Welcome to {appName}!</h1>
{user.isLoggedIn ? (
<p>Hello, {user.name}! You are logged in.</p>
) : (
<p>Please log in.</p>
)}
<button onClick={() => alert('Button clicked!')}>Click Me</button>
</div>
);
}
export default App;

src/index.js (Entry point for React application):

src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client'; // Use createRoot for React 18+
import App from './App'; // Webpack will resolve .jsx extension
const rootElement = document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

In your package.json, add scripts to run Webpack:

// package.json (scripts section)
"scripts": {
"start": "webpack serve",
"build": "webpack --mode production"
}

To start the development server:

npm start

This will open your application in a browser (usually at http://localhost:9000). Webpack Dev Server will automatically rebuild and refresh the browser when you make changes to your source files.

To create a production build:

npm run build

This will generate optimized files in the dist directory.

  • React Development: This is the most common use case for JSX and Babel. All React projects heavily rely on this setup.
  • Other UI Libraries: Some other UI libraries or frameworks might also support JSX or similar syntax extensions, requiring Babel for transpilation (e.g., Preact, Vue with a JSX plugin).
  • Static Site Generators: Tools like Gatsby or Next.js (which use React) leverage Babel and JSX extensively under the hood.

Babel’s ability to transpile JSX, combined with @babel/preset-react, is fundamental to modern React development, enabling developers to write declarative and component-based UIs with a syntax that closely resembles HTML.

For more on the new JSX Transform: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html