CommonJs Modules Flashcards

1
Q

How are commonJs modules exported?

A

Identifiers are exported via setting the exports property on a global called module.

function absolute(num: number) {
  if (num < 0) return num * -1;
  return num;
}
 
module.exports = {
  pi: 3.14,
  squareTwo: 1.41,
  phi: 1.61,
  absolute,
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How are commonJs modules imported?

A

Files can be imported via a require statement:

const maths = require("./maths");
maths.pi;

Or you can simplify a bit using the destructuring feature in JavaScript:

const { squareTwo } = require("./maths");
squareTwo;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How can you reduce the friction between CommonJS and ES Modules ?

A

There is a mis-match in features between CommonJS and ES Modules regarding the distinction between a default import and a module namespace object import. TypeScript has a compiler flag to reduce the friction between the two different sets of constraints with esModuleInterop.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is module resolution?

A

Module resolution is the process of taking a string from the import or require statement, and determining what file that string refers to.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

List all TypeScript module resolution strategies

A

TypeScript includes two resolution strategies: Classic and Node. Classic, the default when the compiler option module is not commonjs, is included for backwards compatibility. The Node strategy replicates how Node.js works in CommonJS mode, with additional checks for .ts and .d.ts.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Relative vs. Non-relative module imports

A

Module imports are resolved differently based on whether the module reference is relative or non-relative.

A relative import s one that starts with /, ./ or ../. It is resolved relative to the importing file and cannot resolve to an ambient module declaration.

A non-relative import can be resolved relative to baseUrl, or through path mapping. They can also resolve to ambient module declarations.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Explain classic module resolution strategy

A

This used to be TypeScript’s default resolution strategy. Nowadays, this strategy is mainly present for backward compatibility.

A relative import will be resolved relative to the importing file. So import { b } from "./moduleB" in source file /root/src/folder/A.ts would result in the following lookups:

/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts

For non-relative module imports, however, the compiler walks up the directory tree starting with the directory containing the importing file, trying to locate a matching definition file.

For example:

A non-relative import to moduleB such as import { b } from "moduleB", in a source file /root/src/folder/A.ts, would result in attempting the following locations for locating “moduleB”:

/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts
/root/src/moduleB.ts
/root/src/moduleB.d.ts
/root/moduleB.ts
/root/moduleB.d.ts
/moduleB.ts
/moduleB.d.ts

“Classic” (typescriptlang.org). Retrieved May 29, 2023.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Explain Node.js module resolution strategy

A

For Relative paths are fairly straightforward. As an example, let’s consider a file located at /root/src/moduleA.js, which contains the import var x = require("./moduleB"); Node.js resolves that import in the following order:

  1. Ask the file named /root/src/moduleB.js, if it exists.
  2. Ask the folder /root/src/moduleB if it contains a file named package.json that specifies a “main” module. In our example, if Node.js found the file /root/src/moduleB/package.json containing { "main": "lib/mainModule.js" }, then Node.js will refer to /root/src/moduleB/lib/mainModule.js.
  3. Ask the folder /root/src/moduleB if it contains a file named index.js. That file is implicitly considered that folder’s “main” module.

For non-relative module names, Node will look for your modules in special folders named node_modules. A node_modules folder can be on the same level as the current file, or higher up in the directory chain. Node will walk up the directory chain, looking through each node_modules until it finds the module you tried to load.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Explain TypeScript’s node resolution strategy

A

TypeScript will mimic the Node.js run-time resolution strategy in order to locate definition files for modules at compile-time. To accomplish this, TypeScript overlays the TypeScript source file extensions (.ts, .tsx, and .d.ts) over Node’s resolution logic. TypeScript will also use a field in package.json named types to mirror the purpose of "main" - the compiler will use it to find the “main” definition file to consult.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How can you trace module resolution?

A

Invoking the compiler with traceResolution

tsc --traceResolution
How well did you know this?
1
Not at all
2
3
4
5
Perfectly