关于 turbopack-bundler
面向 JavaScript 和 TypeScript 项目开发者的 Turbopack 技能,尤其适用于 Next.js。内容介绍配置、内置资源支持、增量缓存、代码拆分及从 webpack 迁移。
主要功能
- 01配置 Next.js Turbopack
- 02支持 TypeScript 和 JSX
- 03处理 CSS 与静态资源
- 04配置别名和自定义加载器
- 05增量缓存与代码拆分
适用场景
- 01在 Next.js 开发中启用 Turbopack
- 02配置别名和资源规则
- 03组织代码以支持增量构建
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill turbopack-bundler安装后在 Claude Code 中输入/turbopack-bundler确认已加载。
详细介绍
Turbopack 打包器
你是 Turbopack 方面的专家。Turbopack 是一款针对 JavaScript 和 TypeScript 优化的增量打包器,使用 Rust 编写并内置于 Next.js 中。使用 Turbopack 时,请遵循以下指南。
核心原则
- Turbopack 专为增量计算和缓存而设计
- 通过 Turbo 引擎实现函数级缓存
- 利用 Rust 原生性能实现快速构建
- 内置支持 TypeScript 和 JSX
- 针对 Next.js 集成进行了优化
- 抽象掉 webpack 配置
项目结构
project/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── globals.css
│ ├── components/ # Shared components
│ └── lib/ # Utility functions
├── public/ # Static assets
├── next.config.js # Next.js configuration
├── tsconfig.json # TypeScript config
└── package.json
启用 Turbopack
开发模式
# Next.js 13.4+
next dev --turbo
# Or in package.json
{
"scripts": {
"dev": "next dev --turbo"
}
}
Next.js 配置
// next.config.js
module.exports = {
experimental: {
turbo: {
// Turbopack-specific configuration
}
}
};
配置选项
自定义 Loader
// next.config.js
module.exports = {
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js'
},
'*.mdx': {
loaders: ['@mdx-js/loader']
}
}
}
};
解析别名
// next.config.js
module.exports = {
turbopack: {
resolveAlias: {
'@components': './src/components',
'@lib': './src/lib',
'@styles': './src/styles'
}
}
};
解析扩展名
// next.config.js
module.exports = {
turbopack: {
resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json']
}
};
内置支持
Turbopack 内置支持:
- TypeScript:无需配置
- JSX/TSX:自动转换
- CSS:原生 CSS 支持
- CSS Modules:
.module.css文件 - PostCSS:自动处理
- 静态资源:图像、字体等
无需使用以下 Loader:
css-loaderpostcss-loaderbabel-loader(用于@babel/preset-env)
TypeScript 配置
推荐的 tsconfig.json
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
路径别名
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@lib/*": ["src/lib/*"],
"@styles/*": ["src/styles/*"]
}
}
}
代码组织
原子设计模式
src/
├── components/
│ ├── atoms/ # Basic building blocks
│ │ ├── Button/
│ │ └── Input/
│ ├── molecules/ # Combinations of atoms
│ │ ├── SearchBar/
│ │ └── NavItem/
│ ├── organisms/ # Complex components
│ │ ├── Header/
│ │ └── Footer/
│ └── templates/ # Page layouts
│ └── MainLayout/
├── app/
│ └── page.tsx
└── lib/
└── utils.ts
组件结构
Button/
├── Button.tsx
├── Button.module.css
├── Button.test.tsx
└── index.ts
代码拆分
动态导入
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <p>Loading...</p>,
ssr: false // Disable server-side rendering if needed
});
基于路由的拆分
Next.js 会自动按 app/ 目录中的路由拆分代码。
手动拆分
// Split large components
const ChartComponent = dynamic(() => import('./ChartComponent'));
const EditorComponent = dynamic(() => import('./EditorComponent'));
缓存策略
Turbo 引擎缓存
- 为增量构建提供函数级缓存
- 仅重新计算发生变化的部分
- 在多次构建之间保留缓存
优化缓存
// Keep modules focused and small
// Changes to one module don't invalidate others
// Good: Separate concerns
export function formatDate(date: Date) { /* ... */ }
export function formatCurrency(amount: number) { /* ... */ }
// Avoid: Large utility files that change frequently
性能最佳实践
模块组织
- 保持模块小巧且专注
- 尽量减少跨模块依赖
- 谨慎使用 barrel 导出
导入优化
// Prefer specific imports
import { Button } from '@/components/Button';
// Avoid importing entire libraries
// Bad: import _ from 'lodash';
// Good: import debounce from 'lodash/debounce';
静态分析
// Use const assertions for better tree-shaking
const ROUTES = {
home: '/',
about: '/about',
contact: '/contact'
} as const;
CSS 处理
CSS Modules
import styles from './Component.module.css';
function Component() {
return <div className={styles.container}>Content</div>;
}
全局 CSS
// app/layout.tsx
import './globals.css';
Tailwind CSS
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}'
]
};
环境变量
Next.js 环境变量
# .env.local
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgresql://...
// Client-side (must have NEXT_PUBLIC_ prefix)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// Server-side only
const dbUrl = process.env.DATABASE_URL;
测试
测试组织
src/
├── components/
│ └── Button/
│ ├── Button.tsx
│ └── Button.test.tsx # Co-located test
└── __tests__/ # Integration tests
└── pages/
└── home.test.tsx
测试最佳实践
- 为工具函数编写单元测试
- 对组件使用 React Testing Library
- 使用 Cypress 或 Playwright 进行端到端测试
- 将测试放在靠近被测代码的位置
常见问题
配置问题
// Ensure correct tsconfig.json paths
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"] // Must match actual structure
}
}
}
缓存问题
# Clear Turbopack cache if issues arise
rm -rf .next
兼容性
- 检查依赖项与 Turbopack 的兼容性
- 部分 webpack 插件可能无法直接使用
- 使用 Next.js 配置,而不是 webpack 配置
从 Webpack 迁移
发生的变化
- 不再直接使用 webpack.config.js
- 使用 next.config.js 进行自定义
- 部分 Loader 需要使用 Turbopack 对应方案
保持不变的内容
- 导入语法
- 动态导入
- CSS Modules
- TypeScript 支持
最佳实践摘要
推荐做法
- 使用 Next.js 配置进行自定义
- 利用内置的 TypeScript 和 JSX 支持
- 以利于增量计算的方式组织代码
- 使用动态导入拆分代码
- 保持模块专注且小巧
避免做法
- 直接配置 webpack
- 使用经常变化的大型 barrel 文件
- 违背 Next.js 约定
- 忽略 TypeScript 路径配置
调试
详细日志
NEXT_DEBUG_TURBOPACK=1 next dev --turbo
构建分析
# Check build output
ANALYZE=true next build
常见问题
- 初始构建缓慢:这是正常的,后续构建会很快
- 找不到模块:检查 tsconfig.json 中的路径别名
- CSS 未加载:确保导入语法正确
- 类型错误:单独运行
tsc --noEmit
评论
支持 Markdown