Blog / Typescript

TypeScript Modules and Module Resolution Strategies

TypeScript Modules and Module Resolution Strategies

In this post find out about typeScript Modules and Module Resolution Strategies

Will MaygerWill Mayger
May 27, 2023
Article

TypeScript provides a powerful module system that allows you to organize and encapsulate your code into reusable and maintainable units. Modules in TypeScript help you break down your application into smaller, modular pieces, making it easier to manage dependencies, share code between files, and promote code reusability. In this article, we’ll explore TypeScript modules and delve into different module resolution strategies.

Understanding TypeScript Modules

A module in TypeScript is a self-contained unit of code that encapsulates related functionality. It can be a single file or a collection of files organized within a directory. Modules provide a way to structure and isolate code, preventing naming conflicts and promoting code organization.

To define a module in TypeScript, you can use the export keyword. This allows you to expose specific parts of your code that can be imported and used in other modules. Here’s an example of exporting and importing modules:

// greeting.ts
export function sayHello(name: string) {
  console.log(`Hello, ${name}!`);
}

// main.ts
import { sayHello } from './greeting';

sayHello("John"); // Output: "Hello, John!"

In this example, the sayHello function is defined in the greeting.ts file and exported using the export keyword. It can then be imported in the main.ts file using the import statement. The imported function can be invoked and used within the importing module.

Module Resolution Strategies

When working with modules in TypeScript, the module resolution strategy determines how the TypeScript compiler locates and loads modules. There are two main module resolution strategies: Classic and Node.

Classic Module Resolution

Classic module resolution is based on relative or absolute paths and relies on the baseUrl and paths compiler options in the tsconfig.json file. It follows a file extension-based approach to locate and import modules.

To use classic module resolution, you need to specify the baseUrl and paths options in your tsconfig.json file:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@components/*": ["components/*"]
    }
  }
}

In this example, the baseUrl is set to the src directory, and the paths configuration maps the @components/* pattern to the components/* path. This allows you to import modules using the @components/* pattern.

import { Component } from '@components/component';

Classic module resolution is useful for projects that use custom module paths or have a complex file structure.

Node Module Resolution

Node module resolution is based on the same module resolution strategy used by Node.js. It relies on the node_modules folder and the package.json file of the module being imported.

Node module resolution follows these steps:

  1. If the module is a core Node module (e.g., fs, http), the TypeScript compiler uses the core module directly.

  2. If the module is a file or a directory, the TypeScript compiler looks for an exact match in the current directory or its ancestor directories. It follows the same algorithm used by Node’s require() function.

  3. If the module is not found as a file or a directory, the TypeScript compiler checks the node_modules directories in the directory tree upwards, starting from the current directory and going up to the root directory.

To use Node module resolution, you don’t need to configure any additional settings. It is the default module resolution strategy in TypeScript.

import * as _ from 'lodash';

In this example, the lodash module is imported using Node module resolution.

The TypeScript compiler looks for the lodash module in the node_modules directory and resolves it accordingly.

Ambient Modules

In addition to regular modules, TypeScript supports ambient modules that provide a way to describe the shape and types of existing modules or global objects. Ambient modules are particularly useful when working with external JavaScript libraries or APIs that don’t have TypeScript declarations.

To define an ambient module, you can use the declare keyword. Here’s an example:

declare module 'my-library' {
  export function doSomething(): void;
}

In this example, the declare keyword is used to define an ambient module for the my-library module. It specifies that the module has an exported function doSomething that takes no arguments and returns void.

Ambient modules allow you to provide type information and enable better type checking when working with external JavaScript libraries or APIs.

Conclusion

TypeScript modules provide a powerful way to organize and encapsulate your code into reusable and maintainable units. Modules allow you to break down your application into smaller, modular pieces, making it easier to manage dependencies, share code between files, and promote code reusability. Understanding and utilizing TypeScript modules is essential for building scalable and maintainable applications.

Module resolution strategies, such as classic and Node, determine how the TypeScript compiler locates and loads modules. Classic module resolution is based on relative or absolute paths and is useful for projects with custom module paths or complex file structures. Node module resolution, on the other hand, follows the same strategy as Node.js and relies on the node_modules folder and package.json files.

In addition, TypeScript supports ambient modules, which provide a way to describe the shape and types of existing modules or global objects. Ambient modules enable better type checking when working with external JavaScript libraries or APIs that lack TypeScript declarations.

By mastering TypeScript modules and understanding module resolution strategies, you can effectively organize your codebase, manage dependencies, and build robust applications.

There we have typeScript Modules and Module Resolution Strategies, if you want more like this be sure to check out some of my other posts!

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app

Some graphics used on this post were made using icons from flaticon.

Latest Posts

Learn React, JavaScript and TypeScript

Learn React, JavaScript and TypeScript

Join the platform that top tier companies are using.
Master the skills you need to succeed as a software engineer and take your career to the next level with Pluralsight.

Start here

Become an expert in ReactJS, TypeScript, and JavaScript.

Here you will find my personal recomendations to you, for full disclosure I earn a small commission from some of these links, but I only recommend what I trust and personally use.

Good things are coming, don't miss out!

Good things are coming, don't miss out!

Follow me on Twitter to stay up to date and learn frontend, React, JavaScript, and TypeScript tips and tricks!

Are you a novice, intermediate or expert react engineer?

Find out here by taking my fun, interactive, quick quiz which takes approximately 1 - 3 minutes. How well will you will do?

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app