typescript 项目配置,让你来控制编译行为...

1,323 阅读5分钟

wo.png

tsconfig.json 项目配置,用来指定typescript 编译的行为,要编译文件的范围,排除的范围...。通常是放在项目的根目录下,当然可以通过 --project 指定配置的文件。整个项目配置主要有5个部分组成:files,extends,include,exclude andreferences,compilerOptions

文件-files

files: 指定要包含在程序中的文件许可列表。如果任何一个文件找不到,则会发生错误。当您只有少量文件并且不需要在整个根目录来引用许多文件时,这很有用。如果要对整个typescript项目进行编译,请使用include.

根字files,extends,include,exclude andreferences, 他们是受到TSConfig 的root 字段影响的,和你如何设置 TypeScript or JavaScript 项目息息相关。项目配置文件,也支持jsconfig.json,这里统一只使用tsconfig.json ,不作过多的区分说明。

{
  "compilerOptions": {},
  "files": [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "utilities.ts",
    "binder.ts",
    "checker.ts",
    "tsc.ts"
  ]
}

继承-extends

extends 字段是来用继承另一个项目配置文件的,有几个关键点要注意

  • 路径的解析 和 nodejs 解析模块路径一样的
  • 文件的路径是基于原项目配置文件
  • 继承处理机制:先解析被继承的目配置文件,然后用继承文件去覆盖
// configs/base.json:
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

// tsconfig.json:
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

// tsconfig.nostrictnull.json:
{
  "extends": "./tsconfig",
  "compilerOptions": {
    "strictNullChecks": false
  }
}

包含-include

指定typesript 文件编译的范围包含哪些,支持指定文件的方式,同时也支持glob 模式的格式。路径的解析也是相对于项目配置文件tsconfig.json 文件

include并exclude支持通配符来制作 glob 模式:

  • * 匹配零个或多个字符(不包括目录分隔符)
  • ? 匹配任何一个字符(不包括目录分隔符)
  • **/ 匹配嵌套到任何级别的任何目录

如果 glob 模式不包含文件扩展名,则只包含支持扩展名的文件(例如.ts, .tsx, 并且.d.ts默认情况下, with.js和.jsxifallowJs设置为 true )。

排除-exclude

指定include 选项在解析时应跳过的文件名或模式数组

  • 它只是一个作用于 include 字段
  • exclude 排除的文件中,有使用import , /// <reference 引用的文件,不在排除的范围中

它不是一种防止文件被包含在代码库中的机制——它只是改变了include 查找范围。

引用-references

项目引用是一种以更小的方式去 组件typscript 项目。这样可以明显提供代码的构造/编辑时间,根据逻辑加强组件化,并以一种改进后全新的方式组织代码。

假设你的项目结构如下

├── src
│   ├── list.ts
│   └── login.ts
├── test
│   ├── list-test.ts
│   └── login-test.ts

测试文件导入相应的实现文件并进行测试:

// list-test.ts
import * as list from "../list";

assert.areEqual(list.action(0), 32);

在之前,这种使用单一tsconfig文件的结构会出现下面的情况:

  • 实现文件也可以导入测试文件, 这是不允许的
  • 无法同时构建test和src,除非把src也放在输出文件夹中,但通常并不想这样做
  • src目录下的文件改动,必需再次对测试进行类型检查,尽管这是根本不必要的
  • test目录下的文件改动,必需再次对测试进行类型检查,尽管这是根本不必要的

主要就是src,test 都是使用同一个tsconfig.json,没有任何的test -> src依赖方向可言,2个目录不是单独完依赖项。

当你引用一个工程时,会发生下面的事:

  • 导入引用工程中的模块实际加载的是它输出的声明文件(.d.ts)。 typescript 侧重的是编译时的类型推导,是一个静态的分析过程,这样的话,如果是类型变化了,就可以做增量编译

  • 如果引用的工程生成一个outFile,那么这个输出文件的.d.ts文件里的声明对于当前工程是可见的。

  • 构建模式(后文)会根据需要自动地构建引用的工程。 类型依赖发生变化,运行时的业务代码发生变化,要重新编译

当你拆分成多个工程后,会显著地加速类型检查和编译,减少编辑器的内存占用,还会改善程序在逻辑上进行分组。

typescript github 上的 TypeScript/src/tsconfig.json,它引用了多个项目配置文件

{
    "files": [],
    "include": [],
    "references": [
        { "path": "./shims" },
        { "path": "./tsc" },
        { "path": "./tsserver" },
        { "path": "./typingsInstaller" },
        { "path": "./watchGuard" },
        { "path": "./debug" },
        { "path": "./cancellationToken" },
        { "path": "./testRunner" }
    ]
}

references 提供了引用tsconfig.json 的从而可以把整个子项目,当作一个依赖处理的能力。相当于一个类型系统的热更新。

编译选项

编译选项有很多,可以根据需求去查看typescript 编译选项

image.png

  • allowJs:允许编译javascript文件。

  • experimentalDecorators: 启用实验性的ES装饰器。

  • declaration: 构造时生成相应的 .d.ts文件。

  • declarationDir:生成声明文件的输出路径

  • module:指定生成哪个模块系统代码: "None", "CommonJS", "AMD", "System", "UMD", "ES6"或 "ES2015"。

  • strict:启用所有严格类型检查选项。

    启用 --strict相当于启用 --noImplicitAny, --noImplicitThis, --alwaysStrict, --strictNullChecks和 --strictFunctionTypes和--strictPropertyInitialization。

  • jsx:在 .tsx文件里支持JSX: "React"或 "Preserve"

  • importHelpers:从 tslib 导入辅助工具函数

  • moduleResolution:决定如何处理模块。或者是"Node"对于Node.js/io.js,或者是"Classic"(默认)

  • skipLibCheck:忽略所有的声明文件( *.d.ts)的类型检查。

  • allowSyntheticDefaultImports:允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。

  • sourceMap 生成相应的 .map文件

  • baseUrl: 解析非相对模块名的基准目录

  • types:要包含的类型声明文件名列表。

  • paths:模块名到基于 baseUrl的路径映射的列表。

  • lib编译过程中需要引入的库文件的列表。可能的值为:es5,6,7,8+ DOM,

结语

到此typescript 的学习也算告一个段落,从基本类型->类型运算->声明文件->项目配置, 几个核心部分也算有一个整体的知识框架。还有一些类型兼容,声明的冲突/合并,零星的没有涉及,如果有时间,再整合到一起学习。typscript 不仅仅是一个类型,更多的是编程中抽象能力。在项目中,让我们一起使用它吧,也许会有不一样的收获。

文章中如有错漏,欢迎指正,谢谢。