tsconfig.json解析

allowSyntheticDefaultImports和esModuleInterop的区别

allowSyntheticDefaultImportsesModuleInterop是TypeScript编译器(tsc)配置中的两个重要选项,它们各自具有不同的作用,但在某些情况下会协同工作以解决模块导入时的兼容性问题。以下是对这两个选项区别的详细解释:

allowSyntheticDefaultImports

作用

  • allowSyntheticDefaultImports允许开发者从不包含默认导出的模块中进行默认导入。这意味着,即使一个模块没有使用export default导出任何内容,开发者仍然可以使用import something from 'module'的语法来尝试导入它。
  • 此选项仅影响类型检查,不会改变生成的JavaScript代码。如果模块实际上没有默认导出,运行时仍然会出错,除非模块或TypeScript的其他配置(如esModuleInterop)提供了相应的默认导出。

示例

假设有一个CommonJS模块,它没有默认导出,但有一个或多个命名导出。在默认情况下,TypeScript不允许使用默认导入语法来导入它。但是,将allowSyntheticDefaultImports设置为true后,TypeScript在类型检查时会忽略这个问题,允许开发者使用默认导入语法。

esModuleInterop

作用

  • esModuleInterop用于改进TypeScript与ES模块和其他模块系统(如CommonJS)之间的互操作性。当设置为true时,TypeScript会在编译过程中生成额外的代码,以确保模块能够正确地被导入和使用。
  • 它主要通过提供两个帮助函数__importStar__importDefault来实现这一点,这两个函数分别用于处理命名导入和默认导入的情况。
  • allowSyntheticDefaultImports不同,esModuleInterop会改变生成的JavaScript代码,以确保导入的模块在运行时能够正常工作。

示例

当尝试从一个CommonJS模块中默认导入时,如果模块本身没有默认导出,esModuleInterop会生成额外的代码来模拟一个默认导出。这样,开发者就可以使用默认导入语法来导入模块,而不会在运行时遇到错误。

区别总结

  1. 影响范围allowSyntheticDefaultImports仅影响类型检查,而esModuleInterop会改变生成的JavaScript代码。
  2. 目的allowSyntheticDefaultImports的目的是允许开发者在不包含默认导出的模块上使用默认导入语法(尽管这可能导致运行时错误),而esModuleInterop的目的是改进模块之间的互操作性,确保导入的模块在运行时能够正常工作。
  3. 协同工作:在某些情况下,这两个选项会协同工作以解决模块导入时的兼容性问题。例如,当从CommonJS模块中默认导入时,可能需要同时设置allowSyntheticDefaultImportsesModuleInterop来确保类型检查和运行时行为都符合预期。

tsconfig.json中没有配置allowSyntheticDefaultImports和esModuleInterop为true,.mjs文件中也能使用import CommonJS模块

在 Node.js 项目中,即使没有在 tsconfig.json 中配置 allowSyntheticDefaultImportsesModuleInteroptrue,你仍然可以在 .mjs 文件中使用 import 来加载 CommonJS 模块。这是因为 .mjs 文件被默认识别为 ES 模块,并且 Node.js 有内置的兼容性处理。

tsconfig.jsoninclude的作用?

tsconfig.json 文件中,include 配置项用于指定要包含在编译过程中的文件或目录。它接受一个字符串数组,每个字符串可以是一个文件路径或一个模式匹配表达式。

include 的作用

include 指定 TypeScript 编译器在编译时应包含的文件和目录。只有在 include 指定的文件和目录中的 TypeScript 文件才会被编译。include 配置项通常与 exclude 配置项配合使用,以排除不需要编译的文件或目录。

示例

基本示例

1
2
3
{
  "include": ["src/**/*.ts"]
}

此配置指定 TypeScript 编译器应包含 src 目录下的所有 .ts 文件,以及其子目录中的所有 .ts 文件。

配合 exclude 使用

1
2
3
4
{
  "include": ["src/**/*.ts"],
  "exclude": ["dist", "**/*.js", "node_modules", "src/tests"]
}

此配置指定 TypeScript 编译器应包含 src 目录下的所有 .ts 文件,以及其子目录中的所有 .ts 文件,但排除所有js文件和 distsrc/testsnode_modules 目录中的所有文件。

注意事项

  • 如果未指定 includefiles,TypeScript 编译器将默认包含项目根目录及其子目录中的所有 .ts.tsx.d.ts 文件(除 node_modulesoutDir 指定的目录)。
  • includefiles 都未指定时,TypeScript 将使用默认的包含模式。

总结

include 配置项用于指定 TypeScript 编译器应包含在编译过程中的文件和目录。通过 include 可以明确告诉编译器哪些文件需要参与编译,这在大型项目中尤为重要,以确保编译过程高效且准确。

tsconfig.jsoncompilerOptions.types的作用?

在您提供的 tsconfig.json 配置片段中,“types”: [“node”] 指定了在 TypeScript 编译过程中仅包含 Node.js 的核心类型声明。这意味着,当您使用 Node.js 的 API 时,TypeScript 编译器将能够提供类型检查和自动补全功能。

具体来说,“types”: [“node”] 的作用如下:

包含 Node.js 类型声明:它告诉 TypeScript 编译器在编译过程中包含 Node.js 的类型声明文件。这些类型声明文件定义了 Node.js API 的形状,使得 TypeScript 能够理解并检查使用这些 API 的代码。 优化编译性能:通过仅包含必要的类型声明,可以减少 TypeScript 编译器需要处理的文件数量,从而提高编译性能。 避免类型冲突:如果您的项目中使用了多个库,并且这些库之间存在类型冲突,通过显式指定需要加载的类型声明文件,可以避免这些冲突。 在这个例子中,由于只指定了 “node”,所以 TypeScript 编译器将只会加载 Node.js 的类型声明,而不会加载其他库(如 React、Lodash 等)的类型声明,除非它们在代码中被显式引用或使用 /// 指令引入。

如果您需要使用其他库的类型声明,可以在 “types” 数组中添加这些库的名称。例如,如果您还需要使用 React 的类型声明,可以将配置修改为:

1
2
3
4
5
{  
  "compilerOptions": {  
    "types": ["node", "react"]  
  }  
}

这样,TypeScript 编译器在编译过程中就会同时包含 Node.js 和 React 的类型声明了。

tsconfig.jsonreferences的作用?

在 TypeScript 项目中,references 配置项主要用于支持 TypeScript 项目引用(Project References) 功能。这一功能允许将一个大型项目分解成多个更小的、相互独立的子项目或包,从而提高代码管理的灵活性和编译速度。

项目引用的好处

  1. 增量编译:通过项目引用,TypeScript 只需要重新编译那些发生变化的子项目,而不是整个项目。
  2. 模块化:将项目拆分成多个模块,方便代码管理和维护。
  3. 独立构建:每个子项目可以独立构建和发布,适合构建大型单体应用或多个包的仓库(monorepo)。

如何使用项目引用

  1. 配置项目引用:在根 tsconfig.json 中通过 references 指定要引用的子项目。
  2. 启用 composite:在所有被引用的子项目中,启用 composite 选项。
  3. 编译项目:通过 tsc --build 命令进行构建。此命令会自动处理项目间的依赖关系。
1
tsc --build

应用场景 - Vue3 + Vite

以下是一个示例,展示了如何使用 references 配置项来管理项目引用。

根 tsconfig.json

根配置文件,指定项目引用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.node.json"
    }
  ]
}

tsconfig.app.json

前端项目的 TypeScript 配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "compilerOptions": {
    "composite": true, // 被引用的项目必须启用新的 composite 设置。
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

tsconfig.node.json

vite.config.js单独指定配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "compilerOptions": {
    "composite": true, // 被引用的项目必须启用新的 composite 设置。
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "noEmit": true
  },
  "include": ["vite.config.ts"]
}

应用场景 - Node.js项目

在后端项目(使用 Node.js)中应用tsconfig.node.json

在 Node.js 项目中,你可以使用 ts-nodetsc 命令来执行和编译代码。例如:

  1. 使用 ts-node 运行 TypeScript 代码:

    1
    
    ts-node -P tsconfig.node.json src/server.ts
    
  2. 使用 tsc 编译 TypeScript 代码:

    1
    2
    
    tsc -p tsconfig.node.json
    node dist/server.js
    

这样可以确保 Node.js 环境使用 tsconfig.node.json 中的配置进行 TypeScript 编译和执行。

示例项目结构

假设你的项目中既有前端代码,也有后端代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
project-root/
├── src/
│   ├── client/
│   │   ├── components/
│   │   └── main.ts
│   ├── server/
│   │   └── server.ts
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── vite.config.ts

在这种结构中:

  • 前端代码位于 src/client 目录下,使用 tsconfig.app.json 进行配置。
  • 后端代码位于 src/server 目录下,使用 tsconfig.node.json 进行配置。

通过上述配置和使用方式,你可以确保在不同场景下正确地使用不同的 TypeScript 配置文件。

总结

项目引用是 TypeScript 提供的一项强大功能,允许将一个大型项目分解成多个更小的子项目,从而提高代码管理的灵活性和编译速度。通过在根 tsconfig.json 中配置 references,并确保所有子项目启用了 composite 选项,可以轻松实现项目引用。

参考资料

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计