如何在项目中配置 Babel 以支持 TypeScript 和 React?
配置方案1. 安装必要的依赖# 核心依赖npm install --save-dev @babel/core @babel/cli @babel/preset-env# TypeScript 支持npm install --save-dev @babel/preset-typescript# React 支持npm install --save-dev @babel/preset-react# 运行时支持(可选但推荐)npm install --save @babel/runtimenpm install --save-dev @babel/plugin-transform-runtime2. 基础配置(babel.config.js)module.exports = { presets: [ // 根据目标环境自动选择转换 ['@babel/preset-env', { targets: { browsers: ['> 1%', 'last 2 versions', 'not ie <= 8'] }, useBuiltIns: 'usage', corejs: 3 }], // TypeScript 支持 '@babel/preset-typescript', // React 支持(包含 JSX 转换) ['@babel/preset-react', { runtime: 'automatic', // React 17+ 新 JSX 转换 development: process.env.NODE_ENV === 'development' }] ], plugins: [ // 运行时优化 ['@babel/plugin-transform-runtime', { corejs: 3, helpers: true, regenerator: true }] ]};3. 配合 Webpack 使用// webpack.config.jsmodule.exports = { module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react' ] } } } ] }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] }};4. TypeScript 配置(tsconfig.json){ "compilerOptions": { "target": "ESNext", "module": "ESNext", "jsx": "preserve", // 保留 JSX,让 Babel 处理 "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, // Babel 需要 "noEmit": true // Babel 负责编译,TS 只负责类型检查 }, "include": ["src/**/*"], "exclude": ["node_modules"]}高级配置1. 环境特定配置// babel.config.jsmodule.exports = { presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'], env: { development: { plugins: [ 'react-refresh/babel' // React Fast Refresh ] }, production: { plugins: [ 'transform-remove-console' // 移除 console ] }, test: { presets: [ ['@babel/preset-env', { targets: { node: 'current' } }] ] } }};2. 装饰器支持npm install --save-dev @babel/plugin-proposal-decoratorsmodule.exports = { presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'], plugins: [ ['@babel/plugin-proposal-decorators', { legacy: true }], '@babel/plugin-proposal-class-properties' ]};3. 路径别名配置// babel.config.jsmodule.exports = { presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react'], plugins: [ ['module-resolver', { root: ['./src'], alias: { '@': './src', '@components': './src/components', '@utils': './src/utils' } }] ]};// tsconfig.json{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"], "@components/*": ["src/components/*"], "@utils/*": ["src/utils/*"] } }}常见问题1. 类型检查与编译分离// package.json{ "scripts": { "type-check": "tsc --noEmit", "build": "npm run type-check && babel src --out-dir dist --extensions '.ts,.tsx'" }}2. 处理 CSS/SCSS 导入// 在 TypeScript 中声明模块declare module '*.scss' { const content: { [className: string]: string }; export default content;}3. 热更新配置// webpack.config.jsconst ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');module.exports = { module: { rules: [{ test: /\.(ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { plugins: [ process.env.NODE_ENV === 'development' && 'react-refresh/babel' ].filter(Boolean) } } }] }, plugins: [ process.env.NODE_ENV === 'development' && new ReactRefreshWebpackPlugin() ].filter(Boolean)};