Skip to content

cyberuni/typescript-module-resolutions-demo

Repository files navigation

TypeScript Module Behavior Demo

This repository demostrate the behavior of TypeScript module system.

There are may issues about the module system in TypeScript:

Objectives

This repository tries to answer the following questions:

  • How to write your code when using certain settings?
  • Does the code compile?
  • Is the compile result correct?
  • Which setting should you use in different situations?

It is currently tests against TypeScript 5.0.0-dev.20230103

Test Configurations

This demo contains multiple test configurations.

Each test configuration contains a specific tsconfig.json setting:

Test Configuration moduleResolution allowSyntheticDefaultImports esModuleInterop
node Node false false
node-allow Node true false
node-es Node (true) true
node16 Node16 false false
node16-allow Node16 true false
node16-es Node16 (true) true
nodenext NodeNext false false
nodenext-allow NodeNext true false
nodenext-es NodeNext (true) true

Note that when esModuleInterop is true, allowSyntheticDefaultImports will automatically be true.

Within each test configuration, there are multiple tsconfig.*.json. One for each module values as follow:

  • CommonJS
  • ES2015
  • ES2020
  • ES2022
  • ESNext
  • Node16
  • NodeNext

The other module values are not tested.

The ES* code are tested with type: module under Node.js. Theoretically, it should be run under browser or use a bundler to bundle them first. We can improve that in the future. For now, running them under Node.js with type: module should be suffice.

Each test project imports multiple packages. Each of the package represents certain scenario.

Within each test configuration, the way to consume each package might be different.

They are adjusted to fit the configuration as much as possible.

When either or both compile and runtime fails, the code is adjusted to make compile pass if possible. This helps to identify any hidden issue where TypeScript says the code is good, but it is not.

Every test file is named with the following format: <package>-<import syntax>.<scope>.ts

For example:

  • assert-default-as.all.ts
  • param-case-star.cjs.ts
  • param-case-star.es.ts: for ES*
  • param-case-star.es2015.ts: for ES2015

The convention allow us to scope test easily so that it is easier to collect test results.

assert

assert is a module within Node.js itself. The type definition comes from @types/node from DefinitelyTyped.

It utilizes module declaration (i.e. declare module). The module is exported with export = declaration.

assertron@7

assertron@7 is written in TypeScript, and compiled to CommonJS. Its type definition uses export default declaration, generated by tsc. It also exposes a module field in package.json, but that should not affect the test.

It also has a transient dependency on assertion-error which uses export = in the type definition.

param-case@1

param-case@1 is written in TypeScript, and compiled to CommonJS. It exposes CJS with export = in the type definition. The type definition is hand-written to match CJS behavior. It does not use declare module.

cjs

cjs is a local package that exposes CJS. Its type definition uses export default declaration, generated by tsc. It does not contain module field in package.json.

es-cjs

es-cjs is a local package that exposes main in CJS and module in ES* format. It should behaves identical to cjs for these tests. It is added for reference.

esm-cjs

esm-cjs is a local package that exposes main in CJS and exports in Node* format.

esm

esm is a local package that expose exports in Node* format. It does not contain a main field.

This package does not apply to test configurations that uses moduleResolution: Node.

Running the demo

The project comes with a tester cil tool to build the results.

To run everything, run pnpm demo.

After running demo, a test-result.<typescript-version>.md will be created in each test project. You can format the file in VSCode to make it easier to read directly.

If you want to run the demo against a new version, update the typescript with pnpm up -r typescript@<version>

Furthermore, you can:

pnpm demo [project] --moduleTypes [...]
pnpm demo compile [project] --moduleTypes [...]
pnpm demo runtime [project] --moduleTypes [...]

Other test cases to cover

  • referencing a esm package which depends on cjs with export default
  • referencing a esm package which depends on cjs with export =

Examples to cover/reference

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published