How do Rollup plugins collaborate with external tools (like Babel, TypeScript)?
考察点:插件与工具集成。
答案:
Rollup 插件通过标准化的钩子接口与外部工具协作,形成完整的构建工具链。这种协作机制让不同的专业工具能够在 Rollup 的统一框架下协同工作。
协作原理:
1. 插件桥接机制
插件作为 Rollup 和外部工具之间的桥梁:
Rollup Core ↔ Plugin ↔ External Tool (Babel/TypeScript/PostCSS)
2. 配置文件共享
插件读取外部工具的配置文件,保持配置一致性:
import babel from '@rollup/plugin-babel'
export default {
plugins: [
babel({
configFile: './babel.config.js',
babelHelpers: 'bundled'
})
]
}
与 Babel 的协作:
1. 基础集成
import babel from '@rollup/plugin-babel'
export default {
plugins: [
babel({
babelrc: true,
configFile: true,
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx'],
babelHelpers: 'runtime'
})
]
}
module.exports = {
presets: [
['@babel/preset-env', {
targets: { browsers: 'defaults' },
modules: false
}],
'@babel/preset-react'
],
plugins: [
'@babel/plugin-proposal-class-properties'
]
}
2. 高级 Babel 集成
import babel from '@rollup/plugin-babel'
export default {
plugins: [
babel({
presets: [
['@babel/preset-env', {
targets: process.env.NODE_ENV === 'test'
? { node: 'current' }
: { browsers: 'defaults' }
}]
],
plugins: [
process.env.NODE_ENV === 'development' && 'react-refresh/babel'
].filter(Boolean),
babelHelpers: 'runtime',
skipPreflightCheck: true
})
]
}
与 TypeScript 的协作:
1. 使用官方 TypeScript 插件
import typescript from '@rollup/plugin-typescript'
export default {
plugins: [
typescript({
tsconfig: './tsconfig.build.json',
target: 'es2018',
module: 'esnext',
declaration: true,
declarationDir: './dist/types',
exclude: ['**/*.spec.ts', '**/*.test.ts']
})
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["**/*.spec.ts", "node_modules"]
}
2. TypeScript + Babel 协作
export default {
plugins: [
typescript({
target: 'es2018',
declaration: false,
noEmitOnError: true
}),
babel({
extensions: ['.js', '.ts'],
presets: [
['@babel/preset-env', { targets: 'defaults' }]
]
})
]
}
与 PostCSS 的协作:
import postcss from 'rollup-plugin-postcss'
export default {
plugins: [
postcss({
config: {
path: './postcss.config.js'
},
extract: true,
minimize: process.env.NODE_ENV === 'production',
sourceMap: true,
inject: {
insertAt: 'top'
}
})
]
}
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({
preset: 'default'
})
]
}
多工具链协作示例:
React + TypeScript + CSS Modules
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
import babel from '@rollup/plugin-babel'
import postcss from 'rollup-plugin-postcss'
import { terser } from 'rollup-plugin-terser'
export default {
input: 'src/index.tsx',
plugins: [
resolve({
browser: true,
extensions: ['.tsx', '.ts', '.js']
}),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
jsx: 'preserve'
}),
babel({
extensions: ['.js', '.jsx', '.ts', '.tsx'],
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }]
],
babelHelpers: 'bundled'
}),
postcss({
modules: {
generateScopedName: '[name]__[local]___[hash:base64:5]'
},
extract: 'styles.css'
}),
process.env.NODE_ENV === 'production' && terser()
].filter(Boolean)
}
配置同步策略:
1. 共享配置文件
export const babelConfig = {
presets: [['@babel/preset-env', { modules: false }]],
plugins: ['@babel/plugin-proposal-class-properties']
}
export const tsConfig = {
target: 'es2018',
module: 'esnext',
strict: true
}
import { babelConfig, tsConfig } from './shared.config.js'
export default {
plugins: [
typescript(tsConfig),
babel(babelConfig)
]
}
2. 环境变量驱动配置
const isDev = process.env.NODE_ENV === 'development'
const isProd = process.env.NODE_ENV === 'production'
export default {
plugins: [
typescript({
sourceMap: isDev,
declaration: isProd,
removeComments: isProd
}),
babel({
presets: [
['@babel/preset-env', {
targets: isProd ? 'defaults' : { node: 'current' }
}]
]
})
]
}
故障排除和调试:
1. 工具版本兼容性
{
"devDependencies": {
"@rollup/plugin-babel": "^5.3.0",
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.0"
}
}
2. 配置验证
export default {
plugins: [
{
name: 'config-validator',
buildStart() {
const babelConfig = require('./babel.config.js')
if (!babelConfig.presets.length) {
throw new Error('Babel presets not configured')
}
}
},
babel(),
typescript()
]
}
性能优化技巧:
1. 缓存配置
babel({
babelrc: false,
configFile: false,
cacheDirectory: true,
include: ['src/**'],
exclude: ['node_modules/**']
})
2. 并行处理
import esbuild from 'rollup-plugin-esbuild'
export default {
plugins: [
esbuild({
target: 'es2018',
jsx: 'transform',
jsxFactory: 'React.createElement'
})
]
}
Rollup 插件与外部工具的协作核心在于:配置统一、版本兼容、顺序正确、功能互补。正确的协作配置能让整个构建工具链发挥最佳效果。