Skip to Content
Course content

59: Path Aliases and Module Resolution

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I once spent an entire Friday afternoon refactoring a folder structure in a large e-commerce dashboard. I moved a few shared UI components into a new common folder, and suddenly my IDE was screaming. I had about forty files with imports like ../../../../components/Button that all needed to be updated. It's tedious, error-prone work that adds zero value to the product, and it's a sign that the project has outgrown relative imports.

When your project grows, you start seeing these "staircases of dots" at the top of your files. Not only are they hard to read, but they make moving files a nightmare. This is where path aliases come in. They allow you to define a shorthand—like @components—that always points to a specific directory, regardless of where the file you're currently editing is located in the folder hierarchy.

Mapping the Project Landscape

To set this up, we head into the tsconfig.json. There are two keys you need to care about: baseUrl and paths. The baseUrl acts as the root for non-relative module names. Usually, you'll set this to . (the current directory) or ./src.

Once the base is set, you can define the paths object. This is essentially a dictionary where the key is the alias and the value is an array of paths where TypeScript should look for those modules. Here is how I typically set up a professional project:

{
  "compilerOptions": {
    "baseUrl": ".", 
    "paths": {
      "@models/*": ["src/core/models/*"],
      "@services/*": ["src/core/services/*"],
      "@ui/*": ["src/components/ui/*"],
      "@utils/*": ["src/lib/utils/*"]
    }
  }
}

Now, instead of typing import { User } from "../../../core/models/user.model", you can simply write import { User } from "@models/user.model". It's cleaner, it's more intentional, and if you move the consuming file to a completely different folder, the import doesn't break.

Bridging the Gap to Runtime

Here is the "gotcha" that trips up almost everyone the first time they do this: TypeScript does not rewrite these paths when it compiles your code to JavaScript. TS is a type-checker; it's happy as long as it can find the file to verify the types. However, when the resulting JS runs in Node or a browser, the environment has no idea what @models means. It will throw a "Module not found" error.

Depending on your stack, you have to tell your runtime how to resolve these aliases too. If you're using Vite or Webpack, you'll add a corresponding alias section to their config files. If you're running raw Node with ts-node, you'll likely need the tsconfig-paths package. I usually recommend keeping your tsconfig and your bundler config in sync—if you add an alias to one, add it to the other immediately so you don't spend an hour debugging a runtime crash that the compiler told you was perfectly fine.




📋 Practical Task

Exercise: Flattening the Nested Import Structure of a User Dashboard

You have been handed a legacy TypeScript project with a messy directory structure. You need to implement path aliases to clean up the imports in a deeply nested component.

Current Structure:
/src
/core
/api
api-client.ts
/features
/dashboard
/components
/widgets
UserStats.tsx

The Goal:
In UserStats.tsx, the current import is:
import { apiClient } from "../../../../core/api/api-client";

Your Tasks:

  1. Modify the tsconfig.json to establish a baseUrl of ".".
  2. Create a path alias called @api/* that maps to src/core/api/*.
  3. Rewrite the import statement in UserStats.tsx to use the new alias.

Deliverable: Provide the compilerOptions block of your tsconfig.json and the updated import line from UserStats.tsx.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.