Babel 与主流构建工具集成
1. Webpack + Babel
安装依赖
bashnpm install --save-dev babel-loader @babel/core @babel/preset-env
基础配置
javascript// webpack.config.js module.exports = { module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { cacheDirectory: true, // 启用缓存 presets: [ '@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript' ] } } } ] } };
高级配置
javascript// webpack.config.js module.exports = { module: { rules: [ { test: /\.(js|ts)x?$/, include: [ path.resolve(__dirname, 'src'), // 包含需要编译的第三方库 path.resolve(__dirname, 'node_modules/some-es6-lib') ], use: [ { loader: 'thread-loader', // 多线程 options: { workers: 2 } }, { loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } } ] } ] } };
2. Vite + Babel
Vite 默认使用 esbuild,但可以通过插件使用 Babel。
安装依赖
bashnpm install --save-dev vite-plugin-babel
配置
javascript// vite.config.js import { defineConfig } from 'vite'; import babel from 'vite-plugin-babel'; export default defineConfig({ plugins: [ babel({ babelConfig: { babelrc: false, configFile: false, presets: ['@babel/preset-env'] } }) ] });
使用 @vitejs/plugin-react
javascript// vite.config.js import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [ react({ // 使用 Babel 替代默认的 esbuild babel: { plugins: [ ['@babel/plugin-proposal-decorators', { legacy: true }] ] } }) ] });
3. Rollup + Babel
安装依赖
bashnpm install --save-dev @rollup/plugin-babel
基础配置
javascript// rollup.config.js import babel from '@rollup/plugin-babel'; import resolve from '@rollup/plugin-node-resolve'; export default { input: 'src/index.js', output: { file: 'dist/bundle.js', format: 'esm' }, plugins: [ resolve(), babel({ babelHelpers: 'bundled', // 或 'runtime' exclude: 'node_modules/**', presets: ['@babel/preset-env'] }) ] };
库开发配置
javascript// rollup.config.js import babel from '@rollup/plugin-babel'; export default { input: 'src/index.js', output: [ { file: 'dist/index.cjs.js', format: 'cjs' }, { file: 'dist/index.esm.js', format: 'esm' } ], plugins: [ babel({ babelHelpers: 'runtime', // 库开发推荐 plugins: ['@babel/plugin-transform-runtime'] }) ], external: [/@babel\/runtime/] // 不打包 runtime };
4. Parcel + Babel
Parcel 内置 Babel 支持,自动识别 .babelrc 或 babel.config.js。
javascript// babel.config.js module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'] };
5. Gulp + Babel
javascript// gulpfile.js const gulp = require('gulp'); const babel = require('gulp-babel'); function transpile() { return gulp.src('src/**/*.js') .pipe(babel({ presets: ['@babel/preset-env'] })) .pipe(gulp.dest('dist')); } exports.default = transpile;
各构建工具对比
| 特性 | Webpack | Vite | Rollup | Parcel |
|---|---|---|---|---|
| 默认转译器 | babel-loader | esbuild | @rollup/plugin-babel | 内置 Babel |
| 配置复杂度 | 高 | 低 | 中 | 极低 |
| 开发速度 | 中 | 极快 | 快 | 快 |
| 生产优化 | 强 | 强 | 强 | 中 |
| 适用场景 | 大型应用 | 现代应用 | 库开发 | 快速原型 |
最佳实践
1. 共享 Babel 配置
javascript// babel.config.js - 所有工具共享 module.exports = { presets: ['@babel/preset-env'], env: { test: { presets: [['@babel/preset-env', { targets: { node: 'current' } }]] } } };
2. 条件配置
javascript// babel.config.js module.exports = (api) => { const isWebpack = api.caller((caller) => caller?.name === 'babel-loader'); const isTest = api.env('test'); return { presets: [ ['@babel/preset-env', { modules: isWebpack ? false : 'auto', targets: isTest ? { node: 'current' } : { browsers: ['> 1%'] } }] ] }; };
3. Monorepo 配置
javascript// babel.config.js (根目录) module.exports = { presets: ['@babel/preset-env'], overrides: [ { test: /packages\/app-a/, presets: ['@babel/preset-react'] }, { test: /packages\/app-b/, presets: ['@babel/preset-typescript'] } ] };
常见问题
1. Webpack 中 Babel 不生效
javascript// 确保正确配置 resolve resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] }
2. Vite 中 JSX 转换问题
javascript// 使用 @vitejs/plugin-react 替代手动配置 import react from '@vitejs/plugin-react'; export default { plugins: [react()] };
3. Rollup 库开发的 helpers 问题
javascript// 使用 runtime helpers 避免重复代码 babel({ babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'] })