编译器
编译选项
我们通过 pnpm install -g typescript
下载的包会附带一个 bin/tsc
,这就是实际上会使用的 TypeScript 编译器,他的参数可以大体分为输入文件和编译选项两种。如果仅指定了输入文件,就会在指定文件的同目录下编译出同样功能的 JavaScript 代码。之后我们也可以通过编译选项来调整编译器的行为,而这也是我们最需要关注的地方。
编译选项分为 长名称
和 短名称
两种风格,其中长名称风格的选项会覆盖更广,而短名称只是长名称的缩写,仅仅为了方便使用,可读性和可维护性并不如长名称风格的编译选项。我们下面列出一些常用的编译选项:
编译选项名称 | 功能描述 |
---|---|
-h --help | 展示帮助文档 |
-d --declaration | 生成类型描述文件,通常库模块会使用该选项来提高用户体验 |
-m --module | 指定编译后的 JavaScript 代码使用什么模块类型,可选包括 CommonJS ,AMD ,ESNext |
-p --project | 指定使用的 tsconfig.json 文件路径 |
-t --target | 指定编译后的 JavaScript 版本,包括 ES3 (默认),ES5 ,ESNext 等 |
-w --watch | 在观测模式下进行编译 |
--strict | 启用严格模式,这是一系列的编译选项的总和,一般在 tsconfig 中指定 |
配置文件(tsconfig.json
)
在 1.5
版本之后,TypeScript 推出了配置文件的方式来管理工程,在这个配置文件中,能够指定
- 输入输出文件路径及格式
- 编译选项
- 继承配置位置
- 工程之间的引用关系
我们首先了解 tsc
是如何找到这个配置文件的,仅输入 tsc
命令时,它先从我们当前指令运行所在的目录开始找起,然后逐级向上,直到家目录下停止,如果还没有找到,则停止编译。我们可以通过上面提到的 --project
来改变他的这个行为。
输入输出指定
如果目录下包含一个默认的 tsconfig.json
,那么编译器将会编译目录下所有的文件(包含类型声明文件),我们可以通过下面三种属性来更改这一默认行为:
files
一个列表, 指定所有需要编译的文件,不支持通配符include
也是一个列表,但是支持三种通配符*
,?
,**/
,分别表示任意多个(包含零个)字符,一个任意字符,任意目录包含其子目录exclude
和include
配置方式一样,同时使用它的时候必须加上include
属性
他们都是配置文件的顶层属性,注意使用的位置(虽然说现在 JSON scheme 已经很成熟了,但还是了解为好)
编译选项
除了通过命令行指定编译选项,还可以通过配置文件中的同名属性来指定,上面 cli 中提到的我就不在赘述,主要讲一些特别的选项。
在使用 IDE 的 TypeScript 插件时候,我们能看到 LSP 协议精确地给出的各种模块的类型提示,这都是归功于 tsconfig.json
中的 typeRoots
选项,其默认值是 node_modules/@types
所以语言服务器可以正确的读取通过包管理器下载的模块的类型信息。我们也可以自己设定这个选项来指定项目中的类型文件的目录
同样,如果感觉某个目录下面的代码不需要所有的模块的类型信息,我们可以使用 types
来简单筛选一下,比方说我们下载了 lodash
和 vite
两个模块,只想使用 lodash
的类型信息,只需要在 types
列表中填入 lodash
即可
至于验证方法,可以使用 --listFiles
编译选项来输出所有被编译的文件来查看(当然也可以在配置文件中指定)
target
上面我们提到过,只是说他会决定编译产物的版本,但也会决定能否使用某些方法。比如我们指定了 target
为 ES6
,那么我们就无法使用 ES2017
中支持的 padStart
方法,强行使用会爆出错误(这是否也可以体现出 TypeScript 实际上只是完成了编译的任务,没有做 Polyfill 的工作呢)
但如果指定了 lib
这个字段,使其包含 ES2017.String
,那么就可以正常通过编译,虽然此时 target
已经形同虚设了……因为你的编译产物已经包含了一个 ES6
平台无法执行的函数。
outDir
指定了所有输出产物(包含 JavaScript 文件和类型声明文件)的输出位置,通常和 package.json
中的 main
和 types
字段综合使用,指定我们编写的工具模块的类型声明文件和入口文件路径。
如果希望最后输出一个文件,那么可以指定 outFile
字段, 但是该字段需要配合 module
使用,module
用来指定编译产物使用的模块语法,可选的有 CommonJS
,AMD
等,且只有后者才能输出单文件。
除此之外还有很多的编译选项,比如针对 JavaScript 的类型检查编译等,我们暂不介绍,以后使用到再补充。
继承配置
在大型项目中,我们可能需要针对源码,测试等不同部分分别进行编译,而他们可能有共同的配置,为了提高维护性,可以使用 extends
字段来实现配置文件的继承。他有两种解析模式
- 相对路径解析:以相对该配置文件的路径来查找(而不是我们运行
tsc
指令时候的相对路径,因为想也知道不可能,如果换个路径编译就无法成功也太荒谬了) - 绝对路径解析:这里的绝对路径不是文件系统绝对路径,而是
node_modules
的绝对路径,比如"extends": "tsconfig/tsconfig.standard.json"
实际查找的位置为app/node_modules/tsconfig/tsconfig.standard.json
,还有全局的node_modules
下的绝对路径