Module Resolution Strategies in TypeScript

Learn via video courses
Topics Covered

Overview

A module is a way to create a group of related variables, classes, interfaces, functions, etc. It is executed in the local scope, not in the global scope. A module is created by using the export keyword and can be used in other modules by using the import keyword. A module can be imported by another module using the module loader. Module loader is responsible for finding and executing all the dependencies of a module before executing the loader.

What are Module Resolution Techniques in TypeScript?

Module Resolution is a process the compiler uses to figure out what an import refers to. If we consider an import statement like import { x } from "moduleX", as we need to check the use of x, the compiler needs to know the representation, and then the compiler checks the definition moduleX. The moduleX could be defined in one of the .ts/.tsx files, or in a .d.ts that depends on our code.

The compiler will try to locate the file that represents the imported module. To do this, the compiler follows two different strategies: Classic and Node. These strategies help the compiler to figure out the path of moduleX.

If the strategies didn't work, then the compiler will try to locate an ambient modular declaration. If the compiler could not resolve the module, an error will be thrown and the error will look like this: error TS2307: Cannot find module 'moduleX'.

Transform Your Career

Choose from our industry-leading programs designed for career success

NSDC Certified

Modern Software and AI Engineering Program

Master full-stack development with AI integration

12 MonthsDuration
AI-LedCurriculum
Career SupportSupport
GoogleAmazonPaytm+1000 more
Go to Program
NSDC Certified

Modern Data Science and ML with specialisation in AI

Advanced data science techniques with AI specialization

12 MonthsDuration
AI-LedCurriculum
Career SupportSupport
GoogleAmazonPaytm+1000 more
Go to Program
NSDC Certified

Advanced AIML with Specialisation in Agentic AI

Deep dive into AIML with focus on Agentic systems

12 MonthsDuration
AI-LedCurriculum
Career SupportSupport
GoogleAmazonPaytm+1000 more
Go to Program
NSDC Certified

DevOps, Cloud & AI Platform Engineering

Build and manage AI-powered cloud infrastructure

12 MonthsDuration
AI-LedCurriculum
Career SupportSupport
GoogleAmazonPaytm+1000 more
Go to Program
NSDC Certified

AI Engineering Advanced Certification by IIT-Roorkee

Premier AI engineering certification from IIT-Roorkee

3 MonthsDuration
AI-LedCurriculum
Career SupportSupport
Program highlights
Go to Program

Types of Module Resolution Techniques in TypeScript?

Module Imports are resolved differently depending on whether the module reference is relative or non-relative. So, there are two types of module resolution techniques: Relative Imports and Non-Relative Imports.

  • Relative Imports:

    A relative import is defined as resolved relative to the importing file and cannot resolve to an ambient modular declaration. We should use the relative modules for our modules that guarantee to maintain their relative location at the runtime.

    A relative import is one that starts with /, ./ or ../. Here is the syntax to declare a relative import:

  • Non-Relative Imports:

    A non-relative import is defined as resolved relative to the baseUrl, or through path mapping. They can also resolve to ambient modular declarations. We can use non-relative paths when we import any of our external dependencies.

    The imports that are not relative will be considered non-relative imports. Here is the syntax to declare a non-relative import:

Classic

When It is Used?

The classic strategy is used to be TypeScript's default resolution strategy. This strategy is majorly used for backward compatibility.

Free Courses by top Scaler instructors
Python Course for Beginners With Certification: Mastering the Essentials
Java Course - Mastering the Fundamentals
DBMS Course - Master the Fundamentals and Advanced Concepts
JavaScript Course With Certification: Unlocking the Power of JavaScript
C++ Course: Learn the Essentials
Python and SQL for Data Science
Python Course for Beginners With Certification: Mastering the Essentials
Java Course - Mastering the Fundamentals
DBMS Course - Master the Fundamentals and Advanced Concepts
JavaScript Course With Certification: Unlocking the Power of JavaScript
C++ Course: Learn the Essentials
Python and SQL for Data Science

Classic Strategy for Relative Imports

A relative import in TypeScript can be resolved relative to the importing file.

Implementation and Example

The import { x } from "./moduleX" in the source file /root/src/folder/X.ts will result in the following lookups:

  • /root/src/folder/moduleX.ts
  • /root/src/folder/moduleX.d.ts

Scaler Placement Report and Statistics

₹23L
AVG CTC
SCALER PLACEMENT PROOF

Scaler learners achieved 2.5x salary growth with average post-Scaler CTC reaching ₹23L.

11,000+placements
650+companies
Verified data
Hiring Partners:
GoogleGoogleAmazonAmazonMicrosoftMicrosoftFlipkartFlipkartAdobeAdobe1200+ more

Classic Strategy for Non-Relative Imports

For non-relative imports, the compiler walks through the directory tree starting with the directory containing the importing file, which tries to locate a matching definition file.

Implementation and Example

A non-relative import to moduleX such as import { x } from "moduleX" in a source file /root/src/folder/Y.ts will result in attempting the following locations to locate "moduleX":

  • /root/src/folder/moduleX.ts
  • /root/src/folder/moduleX.d.ts
  • /root/src/moduleX.ts
  • /root/src/moduleX.d.ts
  • /root/moduleX.ts
  • /root/moduleX.d.ts
  • /moduleX.ts
  • moduleX.d.ts

Node

Turn Learning into Career Growth

1200+Hiring Partners
89%Placement Rate
11,000+Placements
147%Avg Salary Increment
2.5XCareer Growth
₹23 LPAAvg Post-Scaler Salary
1200+Hiring Partners
89%Placement Rate
11,000+Placements
147%Avg Salary Increment
2.5XCareer Growth
₹23 LPAAvg Post-Scaler Salary

When It is Used?

This resolution strategy attempts to take off the Node.js module resolution mechanism at runtime.

Node Strategy for Relative Imports

Imports in Node.js are performed by calling a function named require. Relative paths are considered straightforward paths.

Implementation and Example

let's consider a file located at /root/src/moduleX.js, that contains the import var x = require("./moduleY");, Node.js resolves that import in the following order:

  • Search the file named /root/src/moduleY.js if the file exists.
  • Search the folder /root/src/moduleY if the folder contains a file named package.json that specifies a "main" module. If Node.js found the file /root/src/moduleY/package.json that contains {"main": "lib:/mainModule.js"}, then Node.js refers to /root/src/moduleY/lib/mainModule.js.
  • Search the folder /root/src/moduleY if the folder contains a file named index.js that file is implicitly considered that folder's "main" module.

Node Strategy for Non-Relative Imports

In this, Node will search for modules in special folders named node_modules. A node_modules folder can be of the same level as the current file, or higher up in the directory chain. The node will walk up the directory chain, and look through each node_modules until the node finds the module we tried to load.

Implementation and Example

Now, consider if root/src/moduleX.js instead used a non-relative path and had the import var x = require("moduleY");, Node will try to resolve moduleY to each of the locations until one worked.

  • /root/src/node_modules/moduleY.js
  • /root/src/node_modules/moduleY/index.js
  • /root/node_modules/moduleY.js
  • /root/node_modules/moduleY/index.js
  • /node_modules/moduleY.js
  • /node_modules/moduleY/index.js

When we specify a main property, the below paths are used:

  • /root/src/node_modules/moduleY/package.json
  • /root/node_modules/moduleY/package.json
  • /node_modules/moduleY/package.json

Conclusion

  • Modules, variables, classes, interfaces, etc. run on their scope, not on the global scope.
  • TypeScript has the same module concept as the ES6 module. Modules can have both declarations and code.
  • A module can be imported by another module using the module loader.
  • We can use the import statement to access exports from other modules and the export statement to export variables, functions, classes, and interfaces from a module.
  • The node module resolution is the most common process recommended to handle large TypeScript projects.
  • If there are resolution problems with import s and export s in TypeScript, we can try setting the moduleResolution: "node" to fix this problem.
  • We can use the noResolve compiler options to instruct the compiler not to add any files to the compilation that were passed onto the command line.