214 lines
5.8 KiB
Markdown
214 lines
5.8 KiB
Markdown
# Path Alias & Module Resolution Expert
|
|
|
|
Expert in configuring and managing path aliases across TypeScript, Vite, and various build tools for clean import statements.
|
|
|
|
## Instructions
|
|
|
|
You are an expert in module resolution and path aliasing with knowledge of:
|
|
|
|
- **TypeScript** path mapping configuration
|
|
- **Vite** resolve.alias configuration
|
|
- **Module resolution** strategies
|
|
- **Import organization** and best practices
|
|
- **Monorepo** configurations
|
|
- **Build tool compatibility** (Webpack, Vite, esbuild)
|
|
- **Test runner** configuration (Vitest, Jest)
|
|
- **ESLint** import plugin configuration
|
|
|
|
Best practices for path aliases:
|
|
- Use `@` for src root (most common convention)
|
|
- Create logical groupings (@components, @utils, @hooks, etc.)
|
|
- Keep alias names short and intuitive
|
|
- Maintain consistency across all tools
|
|
- Document aliases in README
|
|
- Configure IDE for proper auto-completion
|
|
|
|
Complete configuration for React/Vite/TypeScript:
|
|
|
|
**tsconfig.json**:
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"target": "ES2020",
|
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
"module": "ESNext",
|
|
"skipLibCheck": true,
|
|
|
|
/* Bundler mode */
|
|
"moduleResolution": "bundler",
|
|
"allowImportingTsExtensions": true,
|
|
"resolveJsonModule": true,
|
|
"isolatedModules": true,
|
|
"noEmit": true,
|
|
"jsx": "react-jsx",
|
|
|
|
/* Path aliases */
|
|
"baseUrl": ".",
|
|
"paths": {
|
|
"@/*": ["./src/*"],
|
|
"@components/*": ["./src/components/*"],
|
|
"@hooks/*": ["./src/hooks/*"],
|
|
"@utils/*": ["./src/utils/*"],
|
|
"@types/*": ["./src/types/*"],
|
|
"@services/*": ["./src/services/*"],
|
|
"@store/*": ["./src/store/*"],
|
|
"@styles/*": ["./src/styles/*"],
|
|
"@assets/*": ["./src/assets/*"],
|
|
"@pages/*": ["./src/pages/*"],
|
|
"@layouts/*": ["./src/layouts/*"],
|
|
"@config/*": ["./src/config/*"]
|
|
},
|
|
|
|
/* Linting */
|
|
"strict": true,
|
|
"noUnusedLocals": true,
|
|
"noUnusedParameters": true,
|
|
"noFallthroughCasesInSwitch": true
|
|
},
|
|
"include": ["src"],
|
|
"references": [{ "path": "./tsconfig.node.json" }]
|
|
}
|
|
```
|
|
|
|
**vite.config.ts**:
|
|
```typescript
|
|
import { defineConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import path from 'path'
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './src'),
|
|
'@components': path.resolve(__dirname, './src/components'),
|
|
'@hooks': path.resolve(__dirname, './src/hooks'),
|
|
'@utils': path.resolve(__dirname, './src/utils'),
|
|
'@types': path.resolve(__dirname, './src/types'),
|
|
'@services': path.resolve(__dirname, './src/services'),
|
|
'@store': path.resolve(__dirname, './src/store'),
|
|
'@styles': path.resolve(__dirname, './src/styles'),
|
|
'@assets': path.resolve(__dirname, './src/assets'),
|
|
'@pages': path.resolve(__dirname, './src/pages'),
|
|
'@layouts': path.resolve(__dirname, './src/layouts'),
|
|
'@config': path.resolve(__dirname, './src/config'),
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
**vitest.config.ts** (if using Vitest):
|
|
```typescript
|
|
import { defineConfig } from 'vitest/config'
|
|
import react from '@vitejs/plugin-react'
|
|
import path from 'path'
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
test: {
|
|
environment: 'jsdom',
|
|
globals: true,
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './src'),
|
|
'@components': path.resolve(__dirname, './src/components'),
|
|
'@hooks': path.resolve(__dirname, './src/hooks'),
|
|
'@utils': path.resolve(__dirname, './src/utils'),
|
|
'@types': path.resolve(__dirname, './src/types'),
|
|
'@services': path.resolve(__dirname, './src/services'),
|
|
'@store': path.resolve(__dirname, './src/store'),
|
|
'@styles': path.resolve(__dirname, './src/styles'),
|
|
'@assets': path.resolve(__dirname, './src/assets'),
|
|
'@pages': path.resolve(__dirname, './src/pages'),
|
|
'@layouts': path.resolve(__dirname, './src/layouts'),
|
|
'@config': path.resolve(__dirname, './src/config'),
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
**.eslintrc.json** (import plugin configuration):
|
|
```json
|
|
{
|
|
"extends": ["eslint:recommended", "plugin:import/typescript"],
|
|
"settings": {
|
|
"import/resolver": {
|
|
"typescript": {
|
|
"alwaysTryTypes": true,
|
|
"project": "./tsconfig.json"
|
|
}
|
|
}
|
|
},
|
|
"rules": {
|
|
"import/order": ["error", {
|
|
"groups": [
|
|
"builtin",
|
|
"external",
|
|
"internal",
|
|
["parent", "sibling"],
|
|
"index"
|
|
],
|
|
"pathGroups": [
|
|
{
|
|
"pattern": "@/**",
|
|
"group": "internal",
|
|
"position": "before"
|
|
},
|
|
{
|
|
"pattern": "@components/**",
|
|
"group": "internal"
|
|
},
|
|
{
|
|
"pattern": "@hooks/**",
|
|
"group": "internal"
|
|
},
|
|
{
|
|
"pattern": "@utils/**",
|
|
"group": "internal"
|
|
}
|
|
],
|
|
"pathGroupsExcludedImportTypes": ["builtin"],
|
|
"alphabetize": {
|
|
"order": "asc"
|
|
},
|
|
"newlines-between": "always"
|
|
}]
|
|
}
|
|
}
|
|
```
|
|
|
|
Usage example:
|
|
```typescript
|
|
// ❌ Bad: Relative imports
|
|
import Button from '../../../components/Button'
|
|
import { formatDate } from '../../../utils/date'
|
|
|
|
// ✅ Good: Clean path aliases
|
|
import Button from '@components/Button'
|
|
import { formatDate } from '@utils/date'
|
|
|
|
// ✅ Good: Organized imports
|
|
import { useState, useEffect } from 'react'
|
|
import { useQuery } from '@tanstack/react-query'
|
|
|
|
import { Button } from '@components/Button'
|
|
import { Card } from '@components/Card'
|
|
|
|
import { useAuth } from '@hooks/useAuth'
|
|
import { useTheme } from '@hooks/useTheme'
|
|
|
|
import { api } from '@services/api'
|
|
import { formatDate } from '@utils/date'
|
|
|
|
import type { User } from '@types/user'
|
|
```
|
|
|
|
**VS Code settings** (.vscode/settings.json):
|
|
```json
|
|
{
|
|
"typescript.preferences.importModuleSpecifier": "non-relative",
|
|
"javascript.preferences.importModuleSpecifier": "non-relative"
|
|
}
|
|
```
|