module 配置项用于指定生成代码的模块化规范,比如:commonjs 、umd 、es module (es6、es2020、es2022)等。
当 tsconfig 中 target 为 es5 时,module 配置项默认为 commonjs (模块格式);否则默认为 es6 (模块格式) 。
在项目里,要正确地设置 TypeScript 中的 module 配置,首先要明确宿主环境所期望的模块类型。例如,不同版本的 Node.js 对模块类型支持情况有所不同,Node.js 11 及更早版本只支持 CommonJs 模块(CJS)。Node.js 12 及更高版本同时支持 CommonJS 模块和 ES 模块,Node.js 会利用文件拓展名以及 package.json 文件来确定每个文件应采用的模块格式,如果文件内容与预期格式不匹配,就会抛出错误。
module 编译器选项的目的就是将宿主环境所期望的模块类型告诉 TypeScript 编译器。他会控制编译过程中所生成的任何 JavaScript 代码的模块格式,也用于告知编译器应如何检测每个文件所属的模块类型、不同模块类型之间如何相互导入,以及像 import.meta 和顶层 await 这类特性是否可用。因此,即便一个 TypeScript 项目设置了 noEmit ,为 module 选项选择正确的设置仍然很重要。因为编译器需要对模块系统有准确的理解,这样他才能对导入进行类型检查(从而提供类型的智能提示,即 IntelliSense)。
module 支持的配置较多,可以说是 tsconfig 中最难理解的配置之一。
module 支持的配置有 node16 、nodenext、preserve、es2015 (es6)、es2020、es2022、esnext、commonjs、system、amd 和 umd。
下面具体说说每个配置的含义与作用。
node16, nodenext
Node.js 同时支持 CommonJS 和 ECMAScript 模块,对于每种文件可以采用的格式,以及这两种格式如何实现互操作,都有特定的规则。node16 和 nodenext 描述了 Node.js 双格式模块系统的完整行为范围,并且会以 CommonJS 或 ESM 格式输出文件。这与其他所有模块选项都不同,其他模块选项与运行时无关,会强制所有输出文件采用单一格式,由用户来确保输出对其运行时来说是有效的。
一个常见的误解是,
node16和nodenext只输出 ES 模块。实际上,node16和nodenext描述的是支持 ES 模块的 Node.js 版本,而不只是使用 ES 模块的项目。基于检测到的每个文件的模块格式,既支持输出 ESM,也支持输出 CommonJS。由于node16和nodenext是仅有的反映 Node.js 双模块系统复杂性的module选项,所以对于所有打算在 Node.js v12 或更高版本中运行的应用程序和库来说,无论它们是否使用 ES 模块,它们都是唯一正确的module选项。
node16 和 nodenext 目前是相同的,唯一的区别在于它们意味着不同的默认 target 选项值。如果 Node.js 在未来对其模块系统做出重大更改,node16 将被冻结,即维持现有的行为不变,而 nodenext 会被更新以反映新的行为。
隐含与强制的配置
module为nodenext或node16时,会强制要求moduleResolution与module采用相同的名称。如果不指定moduleResolution,则默认为nodenext或node16。
-
module为nodenext时,target默认会为esnext -
module为node16时,target默认会为es2022 -
当
module为nodenext或node16时,esModuleInterop默认为 true
模块格式检测
.mts、.mjs和.d.mts文件会被认为是 ES 模块.cts、.cjs和.d.cts文件会被认为是 CommonJS 模块- 如果最近的
package.json文件包含"type": "module",则.ts、.tsx、.js、.jsx、.d.ts文件会被认为是 ES 模块,否则他们会被认为是 CommonJS 模块
检测到的输入 .ts、.tsx、.mts 和 .cts 文件的模块格式决定了输出 JavaScript 文件的模块格式。例如,一个完全由 .ts 文件组成的项目,当 module 设置为 nodenext 时,默认会输出 CommonJS 模块。但可以通过在 package.json 中设置 "type": "module" 改为输出 ES 模块。
互操作性规则
-
当一个 ES 模块引用一个 CommonJS 模块时:
- CommonJS 模块的
module.exports可以作为默认导入项供 ES 模块使用。
- CommonJS 模块的
-
当一个 CommonJS 模块引用一个 ES 模块时
-
require无法引用 ES 模块。对于 TypeScript 而言,这包括在被检测为 CommonJS 模块的文件中的import语句,因为在生成的 JavaScript 代码中,那些import语句会被转换为require调用。 -
可以使用动态的
import()调用导入一个 ES 模块。它返回一个 Promise,该 Promise 解析后得到模块的模块命名空间对象(就如同从另一个 ES 模块中使用import * as ns from "./module.js"所获取到的对象一样 )。
-
不过随着 node.js 22.0.0 版本的发布,CommonJS 模块中也可以使用 require() 命令导入 ES 模块了。不过这个目前还是实验性的特性,因此在执行代码的时候需要加上 --experimental-require-module 标识。
有关更多 ES 模块和 CommonJS 模块互相引用的知识可见JS 模块进阶:ES 模块与 CommonJS 模块的互相引用
生成
每个文件生成的模块格式由每个文件的模块格式检测结果决定。ESM 输出与 --module esnext 类似,但对于 import x = require("...") 有特殊的转换处理,不过在 --module esnext 模式下,这种写法是不被允许的:
// @Filename: main.ts
import x = require("mod");
// @Filename: main.js
import { createRequire as _createRequire } from "module";
const __require = _createRequire(import.meta.url);
const x = __require("mod");
例如这个例子,此例子的目的是演示 CommonJS 模块的代码转换为 ES 模块的代码,此例子的目录结构为:
index.ts 文件的代码如下:
import u = require('fs')
console.log('u ', u)
package.json 文件内容如下,并且 "type": "module" 告知 TypeScript 当前是 ESM :
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^22.10.2",
"typescript": "^5.7.2"
}
}
TypeScript 的配置文件 tsconfig.json 内容如下:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"module": "nodenext"
},
"include": ["src"]
}
在终端运行 npm run build 命令,得到 index.js 为:
import { createRequire as _createRequire } from "module";
const __require = _createRequire(import.meta.url);
const u = __require("fs");
console.log('u ', u);
可以发现 import u = require('fs') 这种写法做了特殊转换处理。
如果将 tsconfig.json 下的 module 修改为 esnext ,可以发现 import u = require('fs') 这种写法是不被允许的:
CommonJS 的输出与 --module commonjs 类似,但动态 import() 调用不会被转换。此处展示的输出是在启用 esModuleInterop 的情况下的:
// @Filename: main.ts
import fs from "fs"; // transformed
const dynamic = import("mod"); // not transformed
// @Filename: main.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs")); // transformed
const dynamic = import("mod"); // not transformed
接下来看看具体的例子,此例子的目的是演示 ES 模块的代码转成 CommonJS 模块的代码,此例子的目录结构为:
index.ts 文件的代码如下:
import fs from "fs";
const cmm = import("./common.cjs");
interface Cmm {
add: (a: number, b: number) => number
}
console.log('fs ', fs)
cmm.then(r => {
console.log('r ', (r as unknown as Cmm).add(1, 2))
})
common.cts 文件代码为:
function add(a: number, b: number) {
return a + b
}
module.exports.add = add
package.json 文件内容如下,并且 "type": "commonjs" 告知 TypeScript 当前是 CommonJS 模块:
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"type": "commonjs",
"main": "index.js",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^22.10.2",
"typescript": "^5.7.2"
}
}
TypeScript 的配置文件 tsconfig.json 内容如下:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"useDefineForClassFields": false,
"module": "nodenext",
"esModuleInterop": true
},
"include": ["src"]
}
在终端运行 npm run build 命令,得到 index.js 为:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs")); // transformed
const cmm = import("./common.cjs"); // not transformed
console.log('fs ', fs_1.default);
cmm.then(r => {
console.log('r ', r.add(1, 2));
});
common.cjs 为:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function add(a, b) {
return a + b;
}
module.exports.add = add;
总结
-
对于所有打算在 Node.js v12 或更高版本中运行的应用程序和库,无论它们是否使用 ES 模块,
node16和nodenext都是唯一正确的module选项。 -
node16和nodenext会根据检测到的每个文件的模块格式,以 CommonJS 或 ESM 格式输出文件。 -
Node.js 在 ESM(ES 模块)和 CJS(CommonJS 模块)之间的互操作性规则反映在了类型检查中。
Node.js 对 ES 模块和 CommonJS 模块互操作性的规则被融入到 TypeScript 的类型检查中,用于检查模块间引用是否符合规范,提前发现潜在的运行时错误。
-
ESM 输出会将
import x = require("...")转换为由createRequire导入构造的require调用。 -
CommonJS 输出不会转换动态
import()调用,因此 CommonJS 模块可以异步导入 ES 模块。
preserve
在 TypeScript 5.4 中新增了 module 为 preserve 模式。
在 preserve 模式下,输入文件中的 ECMAScript 导入和导出语句会在输出中保留,而 CommonJS 风格的 import x = require("...") 以及 export =... 语句会作为 CommonJS 的 require 和 module.exports 输出。换句话说,每个单独的导入或导出语句的格式都会被保留,而不会在整个编译过程(甚至整个文件)中被强制转换为单一格式。
export =和import = require()是 TypeScript 特有的语法。具体见 模块
来看具体的例子,该例子的目录结构为:
TypeScript 配置文件 tsconfig.json 如下,将 module 设置为 preserve:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"useDefineForClassFields": false,
"module": "preserve",
"esModuleInterop": true
},
"include": ["src"]
}
package.json 文件如下:
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"type": "commonjs",
"main": "index.js",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^22.10.2",
"typescript": "^5.7.2"
}
}
my-util.ts 文件的内容为:
const isArr = (list) => {
return Array.isArray(list)
}
export {
isArr
}
common.cts 文件的内容为,其中使用了 TypeScript 特有的 export = 语法,用于导出 add 函数:
function add(a: number, b: number) {
return a + b
}
export = {
add
}
index.ts 文件内容为,其中使用了 TypeScript import = require() 的特有语法:
import { isArr } from './my-util'
import fs = require('fs')
const cmm = import("./common.cjs");
interface Cmm {
add: (a: number, b: number) => number
}
console.log('fs ', fs)
console.log('isArr ', isArr([2, 3]))
cmm.then(r => {
console.log('r ', (r as unknown as Cmm).add(1, 2))
})
然后在终端运行 npm run build 命令,得到结果:
虽然很少需要在同一个文件中混合使用 import 和 require 调用,但这种模块模式最能体现大多数现代打包工具以及 Bun 运行时的功能。
为什么要在意 TypeScript 在使用打包器或 Bun 时的模块输出呢,毕竟你可能还设置了
noEmit?TypeScript 的类型检查和模块解析行为会受到它将要输出的模块格式的影响。设置module会向 TypeScript 提供有关打包器或运行时将如何处理导入和导出的信息,这能确保你在导入值上看到的类型准确反映运行时或打包后的情况。
隐含与强制的配置
-
当
module为preserve,moduleResolution配置默认为bundler -
当
module为preserve,默认会启用esModuleInterop
当
module为preserve时,esModuleInterop选项仅针对其类型检查行为默认启用。当module为preserve时,import语句永远不会转换为require调用,所以esModuleInterop不会影响输出的 JavaScript 代码。
es2015, es2020, es2022, esnext
-
对于打包工具(Webpack、Rollup、Vite 等)、Bun 和 tsx,建议结合
--moduleResolution bundler使用esnext -
不要用于 Node.js 。对于 Node.js 建议使用
node16或nodenext的module配置,并搭配package.json中设置"type": "module",以便输出 ES 模块格式的代码。 -
在非声明文件中不允许使用
import mod = require("mod")。
在普通的 TypeScript 实现文件(如
.ts或.tsx文件)中不允许使用import mod = require("mod")导入形式的语句。这种导入形式是为了在 ES 模块中引入 CommonJS 模块而设计的。在一般的 TypeScript 代码文件中,应该使用 ES 风格的导入语句,例如import * as mod from "mod";或者import mod from "mod";(对于默认导出)。
-
es2020增加了对import.meta属性的支持 -
es2022增加了对顶层await的支持。 -
exnext是不断变化的,包括对 ECMAScript 规范的支持 -
输出的文件是 ES 模块格式的,但是项目所依赖的库可以是任何模块格式的
例子
// @Filename: main.ts
import x, { y, z } from "mod";
import * as mod from "mod";
const dynamic = import("mod");
console.log(x, y, z, mod, dynamic);
export const e1 = 0;
export default "default export";
编译结果为:
// @Filename: main.js
import x, { y, z } from "mod";
import * as mod from "mod";
const dynamic = import("mod");
console.log(x, y, z, mod, dynamic);
export const e1 = 0;
export default "default export";
commonjs
-
不建议使用这个配置。建议使用
node16或nodenext配置来为 Node.js 输出 CommonJS 模块的代码 -
输出的文件是 CommonJS 模块格式的,但是项目所依赖的库可以是任何模块格式的
-
动态
import()会被转换为一个require()调用的 Promise -
esModuleInterop影响默认导入和命名空间导入的输出代码。
例子
下面是
esModuleInterop设置为 false 时的输出结果
// @Filename: main.ts
import x, { y, z } from "mod";
import * as mod from "mod";
const dynamic = import("mod");
console.log(x, y, z, mod, dynamic);
export const e1 = 0;
export default "default export";
// @Filename: main.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.e1 = void 0;
const mod_1 = require("mod");
const mod = require("mod");
const dynamic = Promise.resolve().then(() => require("mod"));
console.log(mod_1.default, mod_1.y, mod_1.z, mod);
exports.e1 = 0;
exports.default = "default export";
// @Filename: main.ts
import mod = require("mod");
console.log(mod);
export = {
p1: true,
p2: false
};
// @Filename: main.js
"use strict";
const mod = require("mod");
console.log(mod);
module.exports = {
p1: true,
p2: false
};
system
module 为 system 是专为与 SystemJS 模块加载器配合使用而设计的。
SystemJS 是一个 hookable、基于标准的模块加载器。它提供了一种工作流程,使得为浏览器中的原生 ES 模块生产工作流编写的代码(例如 Rollup 的代码分割构建)可以被转译成 System.register 模块格式,以便在不支持原生模块的老式浏览器中运行,同时几乎以原生模块的速度执行,并支持顶层 await、动态导入、循环引用和实时绑定、import.meta.url、模块类型、导入映射、完整性和内容安全策略,兼容性可追溯到 IE11。
简单点说,SystemJS 使现代 JavaScript 模块(ES 模块)能够在旧版浏览器中高效运行,同时保留了现代功能特性并确保了安全性与兼容性。
要注意的是,SystemJS 也支持对 amd、umd 模块的加载,是通用的模块加载器。
例子
此例子的目录结构为:
此例子的 TypeScript 配置 tsconfig.json 为:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"useDefineForClassFields": false,
"module": "system",
"target": "es6",
"paths": {
"undici-types": ["./node_modules/undici-types/index.d.ts"]
}
},
"include": ["src"]
}
注意上面的 path 配置,如果没有 path 配置,运行编译会报 Cannot find module 'undici-types' 的错误:
参考 [@types/node] Compiler error: Cannot find module 'undici-types' #67406
package.json 文件内容如下:
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "22.0.0",
"typescript": "^5.7.2"
}
}
my-util.ts 文件内容为:
const x = 1
const y = 2
const z = 3
export {
y,
z
}
export default x
index.ts 文件内容为:
import x, { y, z } from './my-util'
import * as util from './my-util'
const dynamic = import('./my-util')
console.log(x, y, z, util, dynamic);
export const e1 = 0;
export default "default export";
在终端运行 npm run build 命令,可得编译结果:
// @Filename:my-util.js
System.register([], function (exports_1, context_1) {
"use strict";
var x, y, z;
var __moduleName = context_1 && context_1.id;
return {
setters: [],
execute: function () {
x = 1;
y = 2;
exports_1("y", y);
z = 3;
exports_1("z", z);
exports_1("default", x);
}
};
});
// @Filename:index.js
System.register(["./my-util"], function (exports_1, context_1) {
"use strict";
var my_util_1, util, dynamic, e1;
var __moduleName = context_1 && context_1.id;
return {
setters: [
function (my_util_1_1) {
my_util_1 = my_util_1_1;
util = my_util_1_1;
}
],
execute: function () {
dynamic = context_1.import('./my-util');
console.log(my_util_1.default, my_util_1.y, my_util_1.z, util, dynamic);
exports_1("e1", e1 = 0);
exports_1("default", "default export");
}
};
});
amd
amd 全称为 "Asynchronous Module Definition",意思是“异步模块定义”。他采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
-
专为像 RequireJS 这样的 AMD 加载器设计。
-
不建议使用这个配置,建议用打包工具(Webpack、Rollup 等)代替
-
输出的文件是 AMD 模块,但是项目的依赖项可以是任何模块格式的
-
支持
outFile配置
outFile配置会将多个文件打包到 1 个文件中
例子
此例子的目录结构为:
此例子的 TypeScript 配置 tsconfig.json 为:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"useDefineForClassFields": false,
"module": "amd",
"target": "es6",
"paths": {
"undici-types": ["./node_modules/undici-types/index.d.ts"]
}
},
"include": ["src"]
}
注意上面的 path 配置,如果没有 path 配置,运行编译会报 Cannot find module 'undici-types' 的错误,这一点与上面的 system 一样:
package.json 文件内容如下:
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "22.0.0",
"typescript": "^5.7.2"
}
}
my-util.ts 文件内容为:
const x = 1
const y = 2
const z = 3
export {
y,
z
}
export default x
index.ts 文件内容为:
import x, { y, z } from './my-util'
import * as util from './my-util'
const dynamic = import('./my-util')
console.log(x, y, z, util, dynamic);
export const e1 = 0;
export default "default export";
在终端运行 npm run build 命令,可得编译结果:
// @Filename:my-util.js
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.z = exports.y = void 0;
const x = 1;
const y = 2;
exports.y = y;
const z = 3;
exports.z = z;
exports.default = x;
});
// @Filename:index.js
define(["require", "exports", "./my-util", "./my-util"], function (require, exports, my_util_1, util) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.e1 = void 0;
const dynamic = new Promise((resolve_1, reject_1) => { require(['./my-util'], resolve_1, reject_1); });
console.log(my_util_1.default, my_util_1.y, my_util_1.z, util, dynamic);
exports.e1 = 0;
exports.default = "default export";
});
outFile 配置会将多个文件打包到 1 个文件中,修改此例子的 tsconfig.json 文件,将其中的 outDir 去掉,并添加 outFile 配置:
在终端运行 npm run build 命令,看到多个文件都合并成一个文件输出了:
// @Filename:main.js
define("my-util", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.z = exports.y = void 0;
const x = 1;
const y = 2;
exports.y = y;
const z = 3;
exports.z = z;
exports.default = x;
});
define("index", ["require", "exports", "my-util", "my-util"], function (require, exports, my_util_1, util) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.e1 = void 0;
const dynamic = new Promise((resolve_1, reject_1) => { require(["my-util"], resolve_1, reject_1); });
console.log(my_util_1.default, my_util_1.y, my_util_1.z, util, dynamic);
exports.e1 = 0;
exports.default = "default export";
});
umd
umd 全称为 "Universal Module Definition" ,即通用模块定义,是 javascript 的通用模块化规范,能让 javascript 模块即在浏览器中运行,又在 Node.js 中运行
-
专为 AMD 或 CommonJS loader(加载器) 设计的
-
不会暴露一个全局变量
umd 模块通常会暴露一个全局变量,通过该全局变量访问模块内部所有的 API ,但是 TypeScript 编译输出的 umd 模块不会暴露全局变量
-
不建议使用这个配置,建议用打包工具(Webpack、Rollup 等)代替
-
生成的文件是 umd 模块,但项目依赖项可以是任何模块格式
例子
此例子的目录结构为:
此例子的 TypeScript 配置 tsconfig.json 为:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"module": "umd",
"target": "es6",
"paths": {
"undici-types": ["./node_modules/undici-types/index.d.ts"]
}
},
"include": ["src"]
}
注意上面的 path 配置,如果没有 path 配置,运行编译会报 Cannot find module 'undici-types' 的错误:
package.json 文件内容如下:
{
"name": "ts-demo3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc -b"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "22.0.0",
"typescript": "^5.7.2"
}
}
my-util.ts 文件内容为:
const x = 1
const y = 2
const z = 3
export {
y,
z
}
export default x
index.ts 文件内容为:
import x, { y, z } from './my-util'
import * as util from './my-util'
const dynamic = import('./my-util')
console.log(x, y, z, util, dynamic);
export const e1 = 0;
export default "default export";
在终端运行 npm run build 命令,可得编译结果:
// @Filename:my-util.js
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.z = exports.y = void 0;
const x = 1;
const y = 2;
exports.y = y;
const z = 3;
exports.z = z;
exports.default = x;
});
// @Filename:index.js
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "./my-util", "./my-util"], factory);
}
})(function (require, exports) {
"use strict";
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
Object.defineProperty(exports, "__esModule", { value: true });
exports.e1 = void 0;
const my_util_1 = require("./my-util");
const util = require("./my-util");
const dynamic = __syncRequire ? Promise.resolve().then(() => require('./my-util')) : new Promise((resolve_1, reject_1) => { require(['./my-util'], resolve_1, reject_1); });
console.log(my_util_1.default, my_util_1.y, my_util_1.z, util, dynamic);
exports.e1 = 0;
exports.default = "default export";
});
总结
module 配置项用于指定生成代码的模块化规范,比如:commonjs 、umd 、es module (es6、es2020、es2022)等。
module 支持的配置较多,可以说是 tsconfig 中最难理解的配置之一。
module 支持的配置有 node16 、nodenext、preserve、es2015 (es6)、es2020、es2022、esnext、commonjs、system、amd 和 umd。