Skip to content

搭配 Babel 和 JSX 搭配 Babel 和 Flow 使用 搭配 BabelJS 和 Gulp 使用 BabelJs - 示例

JSX 是一种类似 XML 的 JavaScript 语法扩展,常用于 React 等库中描述 UI 结构。浏览器原生不理解 JSX,因此它需要被转译成常规的 JavaScript 函数调用。Babel 是进行这种转换的标准工具。

JSX 允许你直接在 JavaScript 代码中编写看起来类似于 HTML 的标记。例如:

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

Babel,配合适当的预设(如 @babel/preset-react),会将此 JSX 转换为类似以下代码:

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

使用 JSX 的好处(通常在 React 的语境中提及):

  • 可读性:UI 结构比嵌套函数调用更直观易懂。
  • 熟悉度:熟悉 HTML 的开发者可以快速掌握 JSX。
  • 错误检测:Babel 可以在编译期间捕获 JSX 中的语法错误。
  • 基于组件:与基于组件的架构自然契合。

我们将演示如何设置一个项目,使用 Babel 转译 JSX,这通常与 Webpack 结合使用来打包 React 应用。

创建一个新项目并初始化 npm:

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

安装 React, ReactDOM, Babel 包以及 Webpack 相关包:

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

关键包:

  • react、react-dom:React 库本身。
  • @babel/core:Babel 的核心引擎。
  • @babel/preset-env:用于转译现代 JavaScript (ES2015+) 特性。
  • @babel/preset-react:用于转译 JSX 和其他 React 特定语法。
  • babel-loader:Webpack 加载器,用于将 Babel 集成到构建流程中。
  • webpack、webpack-cli:模块打包器。
  • webpack-dev-server:提供本地开发服务器,支持实时重载。
  • html-webpack-plugin:简化 HTML 文件创建,用于提供 Webpack 打包文件的服务。

在你的项目根目录中创建 babel.config.json:

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

@babel/preset-react 中的 "runtime": "automatic" 选项启用了 React 17 引入的新的 JSX 转换,它会自动从 React 导入必要的函数,并且不再需要在每个 JSX 文件中显式 import React from 'react'(尽管为了清晰起见,这仍然通常是好的做法)。对于旧版本的 React,你可能需要使用 "runtime": "classic" 或省略 runtime 选项。

在你的项目根目录中创建 webpack.config.js:

// 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)$/, // 处理 .js 和 .jsx 文件
exclude: /node_modules/,
use: {
loader: 'babel-loader',
// Babel 选项从 babel.config.json 读取
},
},
{
test: /\.css$/i, // 示例:用于处理 CSS 文件
use: ['style-loader', 'css-loader'],
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 你的源 HTML 文件
}),
],
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true, // 自动在浏览器中打开
},
resolve: {
extensions: ['.js', '.jsx'], // 允许导入 .jsx 文件时省略扩展名
},
};

创建一个 src 目录。在其中添加 index.html、App.jsx(或 App.js)和 index.js。

src/index.html (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 将在这里挂载 -->
</body>
</html>

src/App.jsx (一个简单的 React 组件):

// src/App.jsx
// import React from 'react'; // 在 "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 (React 应用入口文件):

src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client'; // React 18+ 使用 createRoot
import App from './App'; // Webpack 会解析 .jsx 扩展名
const rootElement = document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

在你的 package.json 文件中,添加运行 Webpack 的脚本:

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

启动开发服务器:

npm start

这将在浏览器中打开你的应用(通常在 http://localhost:9000)。当你修改源文件时,Webpack Dev Server 将自动重新构建并刷新浏览器。

创建生产版本构建:

npm run build

这会在 dist 目录中生成优化后的文件。

  • React 开发:这是 JSX 和 Babel 最常见的用例。所有 React 项目都高度依赖此设置。
  • 其他 UI 库:一些其他 UI 库或框架也可能支持 JSX 或类似的语法扩展,需要 Babel 进行转译(例如 Preact,带有 JSX 插件的 Vue)。
  • 静态网站生成器:像 Gatsby 或 Next.js(它们都使用 React)这样的工具在底层大量使用了 Babel 和 JSX。

Babel 转译 JSX 的能力,结合 @babel/preset-react,是现代 React 开发的基础,使开发者能够使用与 HTML 高度相似的语法编写声明式和基于组件的 UI。

关于新的 JSX 转换的更多信息:https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html