Prerequisites
- Understanding of TypeScript module resolution basics ๐
- Knowledge of tsconfig.json configuration options โก
- Experience with relative and absolute import statements ๐ป
What you'll learn
- Master TypeScript's path mapping configuration and syntax ๐ฏ
- Create clean, maintainable import statements with custom aliases ๐๏ธ
- Implement advanced path mapping patterns for complex projects ๐
- Optimize development workflow with intelligent path resolution โจ
๐ฏ Introduction
Welcome to the cartographerโs world of path mapping! ๐บ๏ธ If long, messy import statements like ../../../components/ui/Button
are tangled jungle paths, then TypeScriptโs path mapping is your GPS system - it transforms those confusing relative routes into clean, intuitive shortcuts like @/components/ui/Button
!
Path mapping is one of TypeScriptโs most powerful features for improving code maintainability and developer experience. It allows you to define custom aliases for module paths, making imports shorter, more readable, and less brittle when you restructure your project. Whether youโre building a small application or managing a massive enterprise codebase, mastering path mapping will dramatically improve your development workflow.
By the end of this tutorial, youโll be a path mapping expert, capable of creating sophisticated import alias systems that make your code cleaner, more maintainable, and a joy to work with. Letโs navigate the world of custom module paths! ๐
๐ Understanding Path Mapping
๐ค What Is Path Mapping?
Path mapping allows you to define custom aliases for module paths in your TypeScript configuration. Instead of using relative paths that can become unwieldy as your project grows, you can create meaningful shortcuts that remain consistent regardless of where the importing file is located.
// ๐ Before path mapping - relative import hell
import { UserService } from '../../../services/user/UserService';
import { Button } from '../../../../components/ui/Button/Button';
import { ValidationUtils } from '../../../utils/validation/ValidationUtils';
import { ApiTypes } from '../../../../types/api/ApiTypes';
import { Constants } from '../../../config/constants/Constants';
// โจ After path mapping - clean and intuitive
import { UserService } from '@services/user/UserService';
import { Button } from '@components/ui/Button/Button';
import { ValidationUtils } from '@utils/validation/ValidationUtils';
import { ApiTypes } from '@types/api/ApiTypes';
import { Constants } from '@config/constants/Constants';
// ๐ฏ Even better with organized aliases
import { UserService } from '@/services/user/UserService';
import { Button } from '@/components/ui/Button';
import { ValidationUtils } from '@/utils/validation';
import type { ApiTypes } from '@/types/api';
import { Constants } from '@/config/constants';
// ๐ง Path mapping configuration in tsconfig.json
interface PathMappingConfig {
compilerOptions: {
baseUrl: string; // Base directory for path resolution
paths: Record<string, string[]>; // Path mapping patterns
rootDirs?: string[]; // Additional root directories
};
}
// ๐ Comprehensive path mapping example
const comprehensivePathMapping: PathMappingConfig = {
compilerOptions: {
baseUrl: "./src", // All paths relative to src/
paths: {
// ๐ฏ Root alias - map @ to src root
"@/*": ["*"],
// ๐ฆ Feature-based aliases
"@components/*": ["components/*"],
"@services/*": ["services/*"],
"@utils/*": ["utils/*"],
"@hooks/*": ["hooks/*"],
"@pages/*": ["pages/*"],
"@layouts/*": ["layouts/*"],
// ๐จ Asset and style aliases
"@assets/*": ["assets/*"],
"@styles/*": ["styles/*"],
"@images/*": ["assets/images/*"],
"@icons/*": ["assets/icons/*"],
// ๐ง Configuration and types
"@config/*": ["config/*"],
"@types/*": ["types/*"],
"@constants/*": ["constants/*"],
// ๐งช Testing utilities
"@test-utils/*": ["../test-utils/*"],
"@mocks/*": ["../test/mocks/*"],
// ๐ Environment-specific paths
"@env": ["config/environments/production"],
"@env/*": ["config/environments/*"],
// ๐ External library aliases
"react": ["../node_modules/@types/react"],
"lodash": ["../node_modules/@types/lodash"],
// ๐ฏ Specific module aliases
"api": ["services/api/index"],
"database": ["services/database/index"],
"auth": ["services/auth/index"]
},
// ๐๏ธ Multiple root directories for complex projects
rootDirs: [
"./src",
"./generated",
"./shared"
]
}
};
// ๐๏ธ Advanced path mapping manager
class PathMappingManager {
private mappings: Map<string, string[]> = new Map();
private baseUrl: string = '.';
private resolutionCache: Map<string, string> = new Map();
constructor(config: { baseUrl?: string; paths?: Record<string, string[]> }) {
this.baseUrl = config.baseUrl || '.';
if (config.paths) {
Object.entries(config.paths).forEach(([pattern, substitutions]) => {
this.mappings.set(pattern, substitutions);
});
}
console.log('๐บ๏ธ Path Mapping Manager initialized');
console.log(`๐ Base URL: ${this.baseUrl}`);
console.log(`๐ Mappings: ${this.mappings.size} patterns configured`);
}
// ๐ Resolve import specifier using path mappings
resolveImport(importSpecifier: string, fromFile?: string): {
resolved: string | null;
usedPattern: string | null;
substitution: string | null;
steps: string[];
} {
const steps: string[] = [];
steps.push(`๐ Resolving import: "${importSpecifier}"`);
// ๐งฒ Check cache first
const cacheKey = `${importSpecifier}:${fromFile || 'global'}`;
if (this.resolutionCache.has(cacheKey)) {
const cached = this.resolutionCache.get(cacheKey)!;
steps.push(`๐พ Found in cache: ${cached}`);
return {
resolved: cached,
usedPattern: null,
substitution: null,
steps
};
}
// ๐บ๏ธ Try each path mapping pattern
for (const [pattern, substitutions] of this.mappings) {
steps.push(`๐ Trying pattern: ${pattern}`);
const match = this.matchPattern(pattern, importSpecifier);
if (match) {
steps.push(`โ
Pattern matched with groups: [${match.groups.join(', ')}]`);
// ๐ Try each substitution
for (const substitution of substitutions) {
const resolvedPath = this.applySubstitution(substitution, match.groups);
const fullPath = this.resolveRelativeToBase(resolvedPath);
steps.push(`๐ Trying substitution: ${substitution} -> ${fullPath}`);
// ๐พ Cache successful resolution
this.resolutionCache.set(cacheKey, fullPath);
return {
resolved: fullPath,
usedPattern: pattern,
substitution,
steps
};
}
}
}
steps.push(`โ No pattern matched for: ${importSpecifier}`);
return {
resolved: null,
usedPattern: null,
substitution: null,
steps
};
}
// ๐ฏ Match import specifier against pattern
private matchPattern(pattern: string, importSpecifier: string): { groups: string[] } | null {
// Convert TypeScript path pattern to regex
const regexPattern = pattern
.replace(/\*\*/g, '__DOUBLE_WILDCARD__') // Temporarily replace **
.replace(/\*/g, '([^/]*)') // Single * matches within path segment
.replace(/__DOUBLE_WILDCARD__/g, '(.*)') // ** matches across path segments
.replace(/\//g, '\\/'); // Escape forward slashes
const regex = new RegExp(`^${regexPattern}$`);
const match = importSpecifier.match(regex);
if (match) {
console.log(`๐ฏ Pattern "${pattern}" matched "${importSpecifier}"`);
console.log(`๐ Captured groups:`, match.slice(1));
return { groups: match.slice(1) };
}
return null;
}
// ๐ Apply substitution with captured groups
private applySubstitution(substitution: string, groups: string[]): string {
let result = substitution;
// Replace wildcards with captured groups
groups.forEach((group, index) => {
const singleWildcard = /\*/;
const doubleWildcard = /\*\*/;
if (doubleWildcard.test(result)) {
result = result.replace(doubleWildcard, group);
} else if (singleWildcard.test(result)) {
result = result.replace(singleWildcard, group);
}
});
return result;
}
// ๐ Resolve path relative to base URL
private resolveRelativeToBase(path: string): string {
if (path.startsWith('/')) {
return path; // Absolute path
}
if (this.baseUrl === '.') {
return path;
}
return `${this.baseUrl}/${path}`.replace(/\/+/g, '/'); // Normalize slashes
}
// โ Add new path mapping
addMapping(pattern: string, substitutions: string[]): void {
this.mappings.set(pattern, substitutions);
this.clearCache(); // Clear cache when mappings change
console.log(`โ Added mapping: ${pattern} -> [${substitutions.join(', ')}]`);
}
// ๐๏ธ Remove path mapping
removeMapping(pattern: string): boolean {
const removed = this.mappings.delete(pattern);
if (removed) {
this.clearCache();
console.log(`๐๏ธ Removed mapping: ${pattern}`);
}
return removed;
}
// ๐ Update existing mapping
updateMapping(pattern: string, substitutions: string[]): boolean {
if (this.mappings.has(pattern)) {
this.mappings.set(pattern, substitutions);
this.clearCache();
console.log(`๐ Updated mapping: ${pattern} -> [${substitutions.join(', ')}]`);
return true;
}
return false;
}
// ๐งน Clear resolution cache
clearCache(): void {
this.resolutionCache.clear();
console.log('๐งน Resolution cache cleared');
}
// ๐ Get mapping statistics
getStatistics(): {
totalMappings: number;
cacheSize: number;
mostUsedPatterns: Array<{ pattern: string; usage: number }>;
resolutionSuccess: number;
} {
// Simple statistics (in real implementation, track usage)
return {
totalMappings: this.mappings.size,
cacheSize: this.resolutionCache.size,
mostUsedPatterns: Array.from(this.mappings.keys()).map(pattern => ({
pattern,
usage: Math.floor(Math.random() * 100) // Mock usage data
})),
resolutionSuccess: 0.95 // Mock success rate
};
}
// ๐ Validate path mapping configuration
validateConfiguration(): {
isValid: boolean;
issues: string[];
warnings: string[];
suggestions: string[];
} {
const issues: string[] = [];
const warnings: string[] = [];
const suggestions: string[] = [];
// โ
Check for baseUrl requirement
if (this.mappings.size > 0 && !this.baseUrl) {
issues.push('baseUrl is required when using path mappings');
}
// โ
Check for overlapping patterns
const patterns = Array.from(this.mappings.keys());
for (let i = 0; i < patterns.length; i++) {
for (let j = i + 1; j < patterns.length; j++) {
if (this.patternsOverlap(patterns[i], patterns[j])) {
warnings.push(`Patterns may overlap: "${patterns[i]}" and "${patterns[j]}"`);
}
}
}
// โ
Check for performance issues
if (this.mappings.size > 50) {
warnings.push('Large number of path mappings may impact compilation performance');
suggestions.push('Consider consolidating similar patterns');
}
// โ
Check for common anti-patterns
for (const pattern of patterns) {
if (pattern.includes('node_modules')) {
warnings.push(`Mapping to node_modules (${pattern}) may cause issues`);
}
if (pattern.split('*').length > 3) {
warnings.push(`Complex pattern with multiple wildcards: ${pattern}`);
suggestions.push('Simplify pattern for better maintainability');
}
}
return {
isValid: issues.length === 0,
issues,
warnings,
suggestions
};
}
// ๐ Check if patterns overlap
private patternsOverlap(pattern1: string, pattern2: string): boolean {
// Simplified overlap detection
const p1Base = pattern1.replace(/\*/g, '');
const p2Base = pattern2.replace(/\*/g, '');
return p1Base.startsWith(p2Base) || p2Base.startsWith(p1Base);
}
// ๐ List all configured mappings
listMappings(): Array<{ pattern: string; substitutions: string[] }> {
return Array.from(this.mappings.entries()).map(([pattern, substitutions]) => ({
pattern,
substitutions
}));
}
// ๐ฏ Find best matching pattern for a given import
findBestMatch(importSpecifier: string): {
pattern: string;
substitutions: string[];
specificity: number;
} | null {
let bestMatch: { pattern: string; substitutions: string[]; specificity: number } | null = null;
for (const [pattern, substitutions] of this.mappings) {
if (this.matchPattern(pattern, importSpecifier)) {
const specificity = this.calculateSpecificity(pattern);
if (!bestMatch || specificity > bestMatch.specificity) {
bestMatch = { pattern, substitutions, specificity };
}
}
}
return bestMatch;
}
// ๐ Calculate pattern specificity (more specific patterns win)
private calculateSpecificity(pattern: string): number {
let specificity = 0;
// More characters = more specific
specificity += pattern.length;
// Fewer wildcards = more specific
const wildcardCount = (pattern.match(/\*/g) || []).length;
specificity -= wildcardCount * 10;
// Exact matches are most specific
if (!pattern.includes('*')) {
specificity += 1000;
}
return specificity;
}
}
// ๐ฎ Advanced usage examples
const pathMappingDemo = async (): Promise<void> => {
console.log('๐บ๏ธ Path Mapping Demonstration');
// ๐๏ธ Initialize path mapping manager
const pathMapper = new PathMappingManager({
baseUrl: './src',
paths: {
'@/*': ['*'],
'@components/*': ['components/*'],
'@services/*': ['services/*'],
'@utils/*': ['utils/*'],
'@types/*': ['../types/*'],
'@api': ['services/api/index'],
'react-*': ['../node_modules/@types/react-*'],
'@env': ['config/environments/production']
}
});
// ๐ Test various import resolutions
const testImports = [
'@/components/Button',
'@components/ui/Modal',
'@services/user/UserService',
'@utils/validation/emailValidator',
'@types/User',
'@api',
'react-dom',
'@env'
];
console.log('\n๐ Testing Import Resolutions:');
for (const importSpec of testImports) {
const result = pathMapper.resolveImport(importSpec);
console.log(`\n๐ Import: ${importSpec}`);
console.log(` โ
Resolved: ${result.resolved}`);
console.log(` ๐ฏ Pattern: ${result.usedPattern}`);
console.log(` ๐ Substitution: ${result.substitution}`);
}
// ๐ Display statistics
console.log('\n๐ Path Mapping Statistics:');
const stats = pathMapper.getStatistics();
console.log(` Total mappings: ${stats.totalMappings}`);
console.log(` Cache size: ${stats.cacheSize}`);
console.log(` Success rate: ${(stats.resolutionSuccess * 100).toFixed(1)}%`);
// โ
Validate configuration
console.log('\nโ
Configuration Validation:');
const validation = pathMapper.validateConfiguration();
console.log(` Valid: ${validation.isValid}`);
console.log(` Issues: ${validation.issues.length}`);
console.log(` Warnings: ${validation.warnings.length}`);
validation.warnings.forEach(warning => {
console.log(` โ ๏ธ ${warning}`);
});
validation.suggestions.forEach(suggestion => {
console.log(` ๐ก ${suggestion}`);
});
};
๐ก Advanced Path Mapping Patterns
Letโs explore sophisticated path mapping patterns for different project architectures:
// ๐ Advanced path mapping configurations for different project types
// ๐ข Enterprise monorepo configuration
const enterpriseMonorepoConfig = {
compilerOptions: {
baseUrl: "./",
paths: {
// ๐ฆ Package-based aliases
"@core/*": ["packages/core/src/*"],
"@ui/*": ["packages/ui/src/*"],
"@api/*": ["packages/api/src/*"],
"@shared/*": ["packages/shared/src/*"],
"@utils/*": ["packages/utils/src/*"],
// ๐ฏ App-specific aliases
"@admin/*": ["apps/admin/src/*"],
"@client/*": ["apps/client/src/*"],
"@mobile/*": ["apps/mobile/src/*"],
// ๐ง Development and testing
"@test/*": ["test/*"],
"@fixtures/*": ["test/fixtures/*"],
"@mocks/*": ["test/mocks/*"],
// ๐ Documentation and examples
"@docs/*": ["docs/*"],
"@examples/*": ["examples/*"],
// ๐ Environment configurations
"@env": ["config/environment"],
"@config/*": ["config/*"],
// ๐จ Assets and resources
"@assets/*": ["assets/*"],
"@public/*": ["public/*"],
// ๐ Internal package references
"core": ["packages/core/src/index"],
"ui": ["packages/ui/src/index"],
"api": ["packages/api/src/index"]
},
rootDirs: [
"./packages/core/src",
"./packages/ui/src",
"./packages/api/src",
"./packages/shared/src",
"./apps/admin/src",
"./apps/client/src"
]
}
};
// โ๏ธ React application configuration
const reactAppConfig = {
compilerOptions: {
baseUrl: "./src",
paths: {
// ๐ฏ Feature-based organization
"@/*": ["*"],
"@components/*": ["components/*"],
"@pages/*": ["pages/*"],
"@layouts/*": ["layouts/*"],
"@features/*": ["features/*"],
// ๐ฃ React-specific patterns
"@hooks/*": ["hooks/*"],
"@contexts/*": ["contexts/*"],
"@providers/*": ["providers/*"],
"@hoc/*": ["components/hoc/*"],
// ๐ ๏ธ Services and utilities
"@services/*": ["services/*"],
"@utils/*": ["utils/*"],
"@api/*": ["services/api/*"],
"@helpers/*": ["utils/helpers/*"],
// ๐จ Styling and assets
"@styles/*": ["styles/*"],
"@assets/*": ["assets/*"],
"@images/*": ["assets/images/*"],
"@icons/*": ["assets/icons/*"],
"@fonts/*": ["assets/fonts/*"],
// ๐งช Testing
"@test-utils/*": ["../test/utils/*"],
"@test-components/*": ["../test/components/*"],
// ๐ Types and constants
"@types/*": ["types/*"],
"@constants/*": ["constants/*"],
"@enums/*": ["enums/*"],
// ๐ฏ Specific service aliases
"api": ["services/api/index"],
"auth": ["services/auth/index"],
"storage": ["services/storage/index"],
"analytics": ["services/analytics/index"]
}
}
};
// ๐ Full-stack application configuration
const fullStackConfig = {
compilerOptions: {
baseUrl: "./",
paths: {
// ๐ฏ Frontend aliases
"@client/*": ["client/src/*"],
"@client-components/*": ["client/src/components/*"],
"@client-pages/*": ["client/src/pages/*"],
"@client-utils/*": ["client/src/utils/*"],
// ๐ ๏ธ Backend aliases
"@server/*": ["server/src/*"],
"@controllers/*": ["server/src/controllers/*"],
"@models/*": ["server/src/models/*"],
"@services/*": ["server/src/services/*"],
"@middleware/*": ["server/src/middleware/*"],
"@routes/*": ["server/src/routes/*"],
// ๐ Database and ORM
"@db/*": ["server/src/database/*"],
"@entities/*": ["server/src/entities/*"],
"@migrations/*": ["server/src/migrations/*"],
"@seeds/*": ["server/src/seeds/*"],
// ๐ Authentication and security
"@auth/*": ["server/src/auth/*"],
"@guards/*": ["server/src/guards/*"],
"@decorators/*": ["server/src/decorators/*"],
// ๐ Shared code
"@shared/*": ["shared/*"],
"@shared-types/*": ["shared/types/*"],
"@shared-utils/*": ["shared/utils/*"],
"@shared-constants/*": ["shared/constants/*"],
// ๐งช Testing
"@test/*": ["test/*"],
"@client-tests/*": ["client/test/*"],
"@server-tests/*": ["server/test/*"],
// ๐ Configuration
"@config/*": ["config/*"],
"@env": ["config/environment"]
},
rootDirs: [
"./client/src",
"./server/src",
"./shared"
]
}
};
// ๐จ Design system and component library configuration
const designSystemConfig = {
compilerOptions: {
baseUrl: "./src",
paths: {
// ๐จ Component organization
"@/*": ["*"],
"@atoms/*": ["components/atoms/*"],
"@molecules/*": ["components/molecules/*"],
"@organisms/*": ["components/organisms/*"],
"@templates/*": ["components/templates/*"],
"@pages/*": ["components/pages/*"],
// ๐ฏ Component utilities
"@component-utils/*": ["utils/components/*"],
"@component-types/*": ["types/components/*"],
"@component-hooks/*": ["hooks/components/*"],
// ๐จ Design tokens and theming
"@tokens/*": ["design-tokens/*"],
"@themes/*": ["themes/*"],
"@styles/*": ["styles/*"],
"@mixins/*": ["styles/mixins/*"],
"@variables/*": ["styles/variables/*"],
// ๐ง System utilities
"@system/*": ["system/*"],
"@foundations/*": ["foundations/*"],
"@patterns/*": ["patterns/*"],
// ๐ Documentation and examples
"@stories/*": ["../stories/*"],
"@examples/*": ["../examples/*"],
"@docs/*": ["../docs/*"],
// ๐งช Testing and development
"@test-utils/*": ["../test/utils/*"],
"@visual-tests/*": ["../test/visual/*"],
"@a11y-tests/*": ["../test/accessibility/*"],
// ๐ฆ Build and distribution
"@build/*": ["../build/*"],
"@dist/*": ["../dist/*"]
}
}
};
// ๐ง Advanced path mapping utilities
class AdvancedPathMappingUtilities {
// ๐ฏ Generate path mapping for micro-frontend architecture
static generateMicrofrontendPaths(
microfrontends: Array<{ name: string; port: number; routes: string[] }>,
sharedLibraries: string[]
): Record<string, string[]> {
const paths: Record<string, string[]> = {};
// ๐๏ธ Microfrontend aliases
microfrontends.forEach(mf => {
paths[`@${mf.name}/*`] = [`microfrontends/${mf.name}/src/*`];
paths[`@${mf.name}`] = [`microfrontends/${mf.name}/src/index`];
// Route-specific aliases
mf.routes.forEach(route => {
paths[`@${mf.name}/${route}`] = [`microfrontends/${mf.name}/src/routes/${route}`];
});
});
// ๐ Shared library aliases
sharedLibraries.forEach(lib => {
paths[`@shared/${lib}`] = [`shared/${lib}/src/index`];
paths[`@shared/${lib}/*`] = [`shared/${lib}/src/*`];
});
// ๐ Shell application aliases
paths['@shell/*'] = ['shell/src/*'];
paths['@shell'] = ['shell/src/index'];
return paths;
}
// ๐ฏ Generate environment-specific path mappings
static generateEnvironmentPaths(
environments: string[],
configs: Record<string, string[]>
): Record<string, string[]> {
const paths: Record<string, string[]> = {};
environments.forEach(env => {
// Environment-specific configuration
paths[`@config/${env}`] = [`config/environments/${env}`];
paths[`@env/${env}/*`] = [`config/environments/${env}/*`];
// Environment-specific services
if (configs.services) {
paths[`@services/${env}/*`] = [`services/${env}/*`];
}
// Environment-specific assets
if (configs.assets) {
paths[`@assets/${env}/*`] = [`assets/${env}/*`];
}
});
// Default environment (usually production)
const defaultEnv = environments[0] || 'production';
paths['@env'] = [`config/environments/${defaultEnv}`];
return paths;
}
// ๐ฏ Generate feature-based path mappings
static generateFeaturePaths(
features: Array<{
name: string;
hasComponents?: boolean;
hasServices?: boolean;
hasPages?: boolean;
hasUtils?: boolean;
}>
): Record<string, string[]> {
const paths: Record<string, string[]> = {};
features.forEach(feature => {
const featureName = feature.name;
// Main feature alias
paths[`@${featureName}`] = [`features/${featureName}/index`];
paths[`@${featureName}/*`] = [`features/${featureName}/*`];
// Feature-specific sub-paths
if (feature.hasComponents) {
paths[`@${featureName}/components/*`] = [`features/${featureName}/components/*`];
}
if (feature.hasServices) {
paths[`@${featureName}/services/*`] = [`features/${featureName}/services/*`];
}
if (feature.hasPages) {
paths[`@${featureName}/pages/*`] = [`features/${featureName}/pages/*`];
}
if (feature.hasUtils) {
paths[`@${featureName}/utils/*`] = [`features/${featureName}/utils/*`];
}
});
return paths;
}
// ๐ง Optimize path mappings for performance
static optimizePathMappings(
paths: Record<string, string[]>
): {
optimized: Record<string, string[]>;
optimizations: string[];
warnings: string[];
} {
const optimized: Record<string, string[]> = {};
const optimizations: string[] = [];
const warnings: string[] = [];
Object.entries(paths).forEach(([pattern, substitutions]) => {
// โ
Remove duplicate substitutions
const uniqueSubstitutions = [...new Set(substitutions)];
if (uniqueSubstitutions.length !== substitutions.length) {
optimizations.push(`Removed duplicate substitutions from ${pattern}`);
}
// โ
Sort substitutions by specificity (most specific first)
const sortedSubstitutions = uniqueSubstitutions.sort((a, b) => {
return b.length - a.length; // Longer paths are usually more specific
});
// โ ๏ธ Check for potentially problematic patterns
if (pattern.includes('**')) {
warnings.push(`Double wildcard in pattern ${pattern} may impact performance`);
}
if (substitutions.length > 5) {
warnings.push(`Many substitutions for pattern ${pattern} may slow resolution`);
}
optimized[pattern] = sortedSubstitutions;
});
return { optimized, optimizations, warnings };
}
// ๐ Analyze path mapping usage and suggest improvements
static analyzePathMappingUsage(
paths: Record<string, string[]>,
actualImports: string[]
): {
utilization: Record<string, number>;
suggestions: string[];
unusedPatterns: string[];
} {
const utilization: Record<string, number> = {};
const suggestions: string[] = [];
const unusedPatterns: string[] = [];
// Initialize utilization counters
Object.keys(paths).forEach(pattern => {
utilization[pattern] = 0;
});
// Count usage of each pattern
actualImports.forEach(importSpec => {
Object.keys(paths).forEach(pattern => {
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
if (regex.test(importSpec)) {
utilization[pattern]++;
}
});
});
// Identify unused patterns
Object.entries(utilization).forEach(([pattern, count]) => {
if (count === 0) {
unusedPatterns.push(pattern);
}
});
// Generate suggestions
if (unusedPatterns.length > 0) {
suggestions.push(`Consider removing ${unusedPatterns.length} unused path mappings`);
}
const highUsagePatterns = Object.entries(utilization)
.filter(([, count]) => count > actualImports.length * 0.1)
.map(([pattern]) => pattern);
if (highUsagePatterns.length > 0) {
suggestions.push(`High-usage patterns should be optimized: ${highUsagePatterns.join(', ')}`);
}
return { utilization, suggestions, unusedPatterns };
}
// ๐ฏ Generate IDE-friendly path mappings
static generateIDEConfig(
tsconfigPaths: Record<string, string[]>,
baseUrl: string
): {
vscode: any;
webstorm: any;
eslint: any;
} {
// ๐ฏ VS Code configuration
const vscode = {
"typescript.preferences.useAliasesForRenames": false,
"typescript.preferences.includePackageJsonAutoImports": "auto",
"typescript.suggest.autoImports": true,
"typescript.suggest.paths": true
};
// ๐ฏ WebStorm configuration
const webstorm = {
"mark_directory_as": "sources_root",
"resource_patterns": Object.keys(tsconfigPaths).map(pattern =>
pattern.replace(/\*/g, '*')
)
};
// ๐ฏ ESLint configuration
const eslint = {
"settings": {
"import/resolver": {
"typescript": {
"alwaysTryTypes": true,
"project": "./tsconfig.json"
}
}
},
"rules": {
"import/no-unresolved": ["error", {
"ignore": Object.keys(tsconfigPaths).map(pattern =>
`^${pattern.replace(/\*/g, '.*')}$`
)
}]
}
};
return { vscode, webstorm, eslint };
}
}
// ๐ฎ Advanced usage demonstration
const advancedPathMappingDemo = async (): Promise<void> => {
console.log('๐ Advanced Path Mapping Demonstration');
// ๐๏ธ Generate microfrontend paths
const microfrontendPaths = AdvancedPathMappingUtilities.generateMicrofrontendPaths(
[
{ name: 'dashboard', port: 3001, routes: ['overview', 'analytics'] },
{ name: 'users', port: 3002, routes: ['list', 'profile', 'settings'] },
{ name: 'billing', port: 3003, routes: ['invoices', 'payments'] }
],
['ui-components', 'utils', 'api-client']
);
console.log('๐๏ธ Microfrontend paths:', microfrontendPaths);
// ๐ Generate environment paths
const envPaths = AdvancedPathMappingUtilities.generateEnvironmentPaths(
['production', 'staging', 'development'],
{ services: ['api'], assets: ['images'] }
);
console.log('๐ Environment paths:', envPaths);
// ๐ฏ Generate feature paths
const featurePaths = AdvancedPathMappingUtilities.generateFeaturePaths([
{ name: 'auth', hasComponents: true, hasServices: true, hasUtils: true },
{ name: 'dashboard', hasComponents: true, hasPages: true },
{ name: 'profile', hasComponents: true, hasServices: true, hasPages: true }
]);
console.log('๐ฏ Feature paths:', featurePaths);
// ๐ง Optimize combined paths
const allPaths = { ...microfrontendPaths, ...envPaths, ...featurePaths };
const optimization = AdvancedPathMappingUtilities.optimizePathMappings(allPaths);
console.log('๐ง Optimization results:');
console.log(' Optimizations:', optimization.optimizations);
console.log(' Warnings:', optimization.warnings);
// ๐ Analyze usage
const mockImports = [
'@dashboard/components/Chart',
'@shared/ui-components/Button',
'@auth/services/AuthService',
'@env/api',
'@users/pages/UserList'
];
const analysis = AdvancedPathMappingUtilities.analyzePathMappingUsage(
optimization.optimized,
mockImports
);
console.log('๐ Usage analysis:');
console.log(' Utilization:', analysis.utilization);
console.log(' Suggestions:', analysis.suggestions);
console.log(' Unused patterns:', analysis.unusedPatterns);
};
๐ Conclusion
Congratulations! Youโve mastered the art of TypeScript path mapping! ๐บ๏ธ
๐ฏ What Youโve Learned
- ๐บ๏ธ Path Mapping Fundamentals: Understanding baseUrl, paths, and resolution patterns
- ๐ฏ Advanced Patterns: Complex mapping strategies for different project architectures
- ๐ง Configuration Optimization: Performance tuning and best practices
- ๐๏ธ Project Architecture: Organizing large codebases with intelligent path mapping
- ๐ ๏ธ Development Workflow: IDE integration and tooling optimization
๐ Key Benefits
- ๐ Clean Imports: Replace messy relative paths with intuitive aliases
- ๐ง Maintainable Code: Easy refactoring without breaking imports
- โก Better DX: Improved developer experience with autocomplete and navigation
- ๐ฆ Scalable Architecture: Organize complex projects with logical path structure
- ๐ฏ Team Productivity: Consistent import patterns across the entire team
๐ฅ Best Practices Recap
- ๐ Logical Organization: Use meaningful aliases that reflect your project structure
- ๐ฏ Consistent Patterns: Establish team conventions for path mapping usage
- โก Performance Awareness: Avoid overly complex patterns that slow compilation
- ๐ง IDE Integration: Configure your development environment for optimal support
- ๐ Regular Review: Analyze and optimize path mappings as your project evolves
Youโre now equipped to create sophisticated, maintainable import systems that will make your TypeScript projects a joy to work with! ๐
Happy coding, and may your imports always be clean and your paths well-mapped! ๐บ๏ธโจ