Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ianvs/ts-module-resolution-examples
Examples and explanations of TypeScript module resolution
https://github.com/ianvs/ts-module-resolution-examples
bundlers cjs esm nodejs typescript
Last synced: 20 days ago
JSON representation
Examples and explanations of TypeScript module resolution
- Host: GitHub
- URL: https://github.com/ianvs/ts-module-resolution-examples
- Owner: IanVS
- Created: 2022-12-02T02:35:08.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-12T14:09:28.000Z (3 months ago)
- Last Synced: 2024-10-18T10:44:25.439Z (about 1 month ago)
- Topics: bundlers, cjs, esm, nodejs, typescript
- Language: TypeScript
- Homepage:
- Size: 43 KB
- Stars: 36
- Watchers: 1
- Forks: 9
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# TypeScript Module Resolution Examples
A set of example projects exploring TypeScript module resolution with various settings and situations.
Table of contents:
- [About this project](#about-this-project)
- [Introduction to TS module resolution](#introduction-to-ts-module-resolution)
- [Modules](#modules)
- [Module resolution](#module-resolution)
- [TypeScript Options](#typescript-options)
- [`moduleResolution`](#moduleresolution)
- [New options in development](#new-options-in-development)
- [`baseUrl`](#baseurl)
- [`moduleSuffixes`](#modulesuffixes)
- [`resolution-mode`](#resolution-mode)
- [Miscellaneous](#miscellaneous)
- [Ambient modules](#ambient-modules)
- [TS V5](#ts-v5)
- [TS V5.0](#ts-v50)
- [Resolution Customization Flags](#resolution-customization-flags)
- [ModuleResolution Bundler](#moduleresolution-bundler)
- [TS V5.1](#ts-v51)
- [TypeRoots Are Consulted In Module Resolution](#typeroots-are-consulted-in-module-resolution)
- [Explicit TypeRoots Disables Upward Walks for node_modules/@types](#explicit-typeroots-disables-upward-walks-for-node_modulestypes)
- [TS V5.2](#ts-v52)
- [Module and moduleResolution Must Match Node.js Settings](#module-and-moduleresolution-must-match-nodejs-settings)
- [Type-Only Import Paths + TypeScript Implementation File Extensions](#type-only-import-paths--typescript-implementation-file-extensions)## About this project
This was initially created for [a talk](https://www.youtube.com/watch?v=MEl2R7mEAP8) at Michigan TypeScript Developers.
The repository is roughly organized around TypeScript settings, with subfolders for possible values for those settings
and examples demonstrating various aspects of module resolution. There are `README.md` files in most examples to
explain the concept being demonstrated. Usually you can run `npm run build` in each example folder to generate
`example.d.ts` type definition files and see a log of the module resolution process that TypeScript uses printed
to the terminal.Feel free to submit issues or pull requests. I hope for this to be a learning resource for TypeScript developers who
want to understand the complex topic of TypeScript module resolution. So with that, let's start learning!## Introduction to TS module resolution
### Modules
Let's begin by defining what we mean by a "module". When we write TypeScript code,
we typically don't write everything in one single file. Instead, we break up our code
into smaller pieces and put these into files. JavaScript can treat each file as either
a "script" or a "module".Basically, a script file is a standard JavaScript file that does not import or require any other files
and does not have any exports. It might operate on the global scope, or it might not.JavaScript Modules, on the other hand, generally come in two flavors, CommonJS (CJS) and
ES Modules (ESM). Node.js historically used CJS and has started supporting ESM since version 12.
Modern browsers also support ES modules, but they use slightly different rules for resolving
imports from other modules. To learn more about ES modules in the browser, I recommend reading the
[MDN article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules).In TypeScript, most files you write will be considered a module. By default, any file that uses `import` or `export` is treated as a module. Starting in version 4.7, in some situations TypeScript will also check for a package.json file containing `"type": "module"`. The module detection behavior can be
adjusted with the [`moduleDetection`](https://www.typescriptlang.org/tsconfig#moduleDetection) setting.### Module resolution
When we need to use code from another TypeScript file than the one we are writing, we generally
use an `import` statement (or `import()` function). We might write something like:```ts
import foo from "moduleA";
```TypeScript will then need to find what module we mean by "moduleA", in order to determine what type
"foo" should have.This is important. We are talking about _types_ when we talk about TypeScript module resolution.
It's true that TypeScript can also compile `.ts` files into `.js` files, converting our TypeScript into
JavaScript that can run in Node.js, or browsers, or elsewhere. But it's the runtime that will perform
the actual imports, using its own module resolution algorithms. Module resolution rules are left up to the runtime to determine, it is not determined by the JavaScript specification.So, TypeScript does its best to try to match the same module resolution rules that the final runtime
will use, so that the type information it gathers is complete and accurate. Because there are different
runtimes with different rules, TypeScript exposes some options that we can set in order to match up with
the runtime environment.## TypeScript Options
These are some options which TypeScript uses to adjust its module resolution. Please see the
[TypeScript config reference](https://www.typescriptlang.org/tsconfig) for details on each option
and the minimum TypeScript version required for support.Note that some module-related options, such as `module` and `target` effect the emitted JavaScript files, but not module resolution (other than by changing the defaults for other options in some cases), so they are not explored here.
### `moduleResolution`
[Config reference](https://www.typescriptlang.org/tsconfig#moduleResolution)
This is the most direct way to change TypeScript's module resolution mode. It has three current possible values,
and more are being developed to better meet the needs of bundlers and browser-native modules.The currently-supported values are (as of TS 4.9):
- `"Classic"`
- `"Node"`
- `"Node16"` or `"NodeNext"` (currently these mean the same thing)"Classic" mode is rarely used in modern projects, and is not explored in this repository. For details on how it works,
see the TypeScript [module resolution guide](https://www.typescriptlang.org/docs/handbook/module-resolution.html#classic)."Node" is likely the most commonly-used option, and mimics the behavior of Node 11 and below.
See the `moduleResolution/Node` examples and [README](moduleResolution/Node/README.md)."NodeNext" is intended to evolve as Node.js adds new versions and new features, but for now it is the same as "Node16",
which adds support for the Node.js style of ES modules. There are some differences in TypeScript Module resolution
compared to "Node", and these are explored in `moduleResolution/Node16`.
See the [README](moduleResolution/Node16/README.md) there to begin.#### New options in development
The TypeScript team identified that the current `moduleResolution` options are not flexible enough for those using
bundlers or writing ESM to be directly consumed in browsers, so they are creating new options:- `"Hybrid"` (final naming TBD): designed primarily for bundlers, with some behavior customizable by settings.
- PR: https://github.com/microsoft/TypeScript/pull/51669
- `"Minimal"`: A common-denominator for resolution features supported in browsers, Node, Deno, and bundlers.
- PR: https://github.com/microsoft/TypeScript/pull/50153There are no examples of these in this repo, but I intend to add them once they are released.
### `baseUrl`
[Config reference](https://www.typescriptlang.org/tsconfig#baseUrl);
_Examples TBD_
Provides a way to inform TypeScript that when compiled, non-relative imports can be resolved relative to this path.
It is similar to the (discouraged) `NODE_PATH` option for Node.js.### `moduleSuffixes`
[Release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#resolution-customization-with-modulesuffixes)
_Examples TBD_
Allows customizing the “sub” extensions TS will examine, which can be particularly useful when targeting React Native
as a runtime. For example, `"moduleSuffixes": [".ios", ".native", ""]` will look for files ending with `.ios.ts`, `.native.ts`, then `.ts`.### `resolution-mode`
[Release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#resolution-mode)
_Examples TBD_
This is an experimental feature, parts of which are available only in nightly versions, which can change the
"resolution mode" of globals or imported types, allowing CJS types to be used in ESM files, and vice-versa.## Miscellaneous
### Ambient modules
Ambient modules make it possible to import a JavaScript project without types, and use
[community-supplied](https://github.com/DefinitelyTyped/DefinitelyTyped) types or custom-written types to
describe that project. The examples in `misc/ambient-modules` explore different ways that ambient modules can be
configured and used.## TS V5
### TS V5.0
#### Resolution Customization Flags
- [Youtube - Resolution Customization Flags](https://youtu.be/uKcfxI84xPc?si=4C8Fa1kGB-roejUP)
#### ModuleResolution Bundler
- [Youtube - --moduleResolution bundler](https://youtu.be/wfCRQF-HxwY?si=E28B1MipgyElA8QS)
### TS V5.1
#### TypeRoots Are Consulted In Module Resolution
- [Youtube - typeRoots Are Consulted In Module Resolution](https://youtu.be/Z5Qk6z9RK4s?si=-mPoX2bmxp0ey5oK)
#### Explicit TypeRoots Disables Upward Walks for node_modules/@types
- [Youtube - Explicit typeRoots Disables Upward Walks for node_modules/@types](https://youtu.be/avVimJ1gdNA?si=zm-lwIQHCNo3JA-j)
### TS V5.2
#### Module and moduleResolution Must Match Node.js Settings
- [Youtube - module and moduleResolution Must Match Node.js Settings](https://youtu.be/j3OUn0iw4k8?si=Km4-xA1FkmpW6gaj)
#### Type-Only Import Paths + TypeScript Implementation File Extensions
- [Youtube - Type-Only Import Paths + TypeScript Implementation File Extensions](https://youtu.be/ZwNIsSmk-Ks?si=XGQl-BmzXYOGUhYF)