当前位置: 首页 > 科技观察

一些你需要掌握的 Tsconfig.Json 常用配置项

时间:2023-03-14 22:56:04 科技观察

Tsconfig.Json的一些常用配置项你需要掌握tsconfig.json用于配置TS编译选项,一般位于项目的根目录下。我们可以使用ts提供的tsc命令行工具来执行tsc--init。Copy$tsc--initCreatedanewtsconfig.jsonwith:TStarget:es2016module:commonjsstrict:trueesModuleInterop:trueskipLibCheck:trueforceConsistentCasingInFileNames:true你可以在https://aka.ms/tsconfig了解更多,然后我们可以得到A默认tsconfig.json文件,这是一个可注释的json文件。里面有很多带注释的选项,目的是让开发者可以取消注释,快速启用一些配置。但是注释的选项太多了,所以我去掉了,得到了如下默认配置:forceConsistentCasingInFileNames":true,"strict":true,"skipLibCheck":true}}顶级配置首先,让我们看一下顶级配置字段。compilerOptions:编译器相关的选项。比如配置编译成ES5,使用commonjs进行模块化。这里有很多编译配置,后面会讲解一些常用的配置;files:指定需要编译的文件列表。这里不能指定目录,只能指定文件,.ts后缀可以省略。适用于需要编译的文件较少的情况。默认值为假;include:指定需要编译的文件或匹配模式的列表。include可以通过通配符指定目录,比如“src/**/*”表示src下的所有文件。如果不指定files配置,默认值为**,即项目下的所有文件;如果配置了files,默认值为[]一个空数组;exclude:排除include所划定范围内的部分文件。我们经常用它来排除编译输出目录、测试文件目录以及一些生成文件的脚本等文件。默认值为“node_modules,bower_component”;extends:继承另一个ts配置文件。这在monorepo代码组织中非常有用,不同的包可以通过extends继承共同的ts配置。用法示例:“扩展”:“./common-tsconfig.json”。参考:参考。如果项目中有多个独立的模块,可以使用该属性将它们分开。这样的模块改动后,只重新编译这个模块,其他模块不重新编译。编译时,改用tsc--build。这应该在非常大的项目中得到回报。需要注意的是,files、include、exclude只是指定了编译的入口文件的范围。如果里面的一个文件导入了作用域外的ts文件,作用域外的文件还是会被编译。VSCode下,作用域外的ts文件不会应用项目下的tsconfig.json配置。编译器常用配置(compilerOptions)接下来我们看一下compilerOptions下的常用配置属性。因为配置项比较多,我就挑一些比较基础的来讲解。target指定编译的目标版本。tsc也可以像babel一样把高版本的TS/JS编译成低版本。看看这个tsc脚本有多大。target用于指定TS编译的最后一个ES版本,默认值为ES3。对于一些高版本引入的新API,tsc不会注入polyfill,需要自己完全导入core-js,这比babel提供的按需引入core-js要好。当然,对于其他不能polyfill的实现,tsc还是会处理的。比如箭头函数转换成普通函数,async/await转换成大量等价代码。说实话ES3真的够老了,很多API都不支持。个人认为默认ES5比较好。我觉得可能是历史原因吧,因为在TS发布的时候,ES6还没有出来,只有ES5被编译成了ES3。尽管现在ES5得到了广泛支持,但为了兼容性,仍保留默认的ES3。target支持的值有:es3、es5、es6(也叫es2015)、es2016到es2022,然后是esnext。没有es7之类的,得用es2016。另外,esnext是指当前版本的TS编译器支持的最高版本。这些值区分大小写,可以是es5、ES5或大小写混合。一般来说,前端项目都会用到es5。后端项目取决于nodejs版本对ES的支持程度。对于Nestjs脚手架生成的项目,taget指定为es2017。libTypeScript默认自带了常见的JS内置API的类型声明,比如Math、RegExp等。但是JS运行在各种环境中,会有一些特有的全局对象,比如浏览器下的document,以及新的API由新的ES版本引入。为此,我们可以使用lib属性来设置需要导入的全局类型声明。有高级库:ES5、ES2015、DOM、ESNEXT、WebWorker、ScriptHost等。或者DOM.Iterable、ES2015.Core、ES2017.TypedArrays、ES2018.Intl等用于低级模块。更高级别通常是多个全局类型声明的组合。lib的默认值由target指定。比如你的target指定为ES7,就会引入ES7的全局类型(可能是lib.es2016.full.d.ts)。但是如果你想使用最新版本的ES语法,又想编译成兼容性好的ES5,就得手动设置lib,像这样:Copy"target":"ES5","lib":["DOM","DOM.Iterable","ESNext"]lib可以导入的全局类型声明文件都在这个目录下:https://github.com/microsoft/TypeScript/blob/main/lib。strict开启严格模式,可以更好的保证类型检测的正确性。将strict设置为true将启用一系列严格的类型检查配置。例如,strictNullChecks配置的默认值将变为true。这样一些对象类型就不能被赋值为undefined或者null,一定程度上可以防止obj.prop可能导致的Cannotreadpropertiesofundefined的运行时错误。例如,strictBindCallApply的默认值变为true。此时,在函数上使用bind、call、apply时,参数类型必须与原函数类型相同。如果为假,它可以是任何类型。此外,还有许多其他与严格模式相关的配置也将被启用。建议开启strict,可以减少bug。缺点是类型推断和分支判断需要多写代码。baseUrlbaseUrl用于设置baseurl,可以帮助我们省去一些多余的路径前缀。比如我们本来想写一个长篇:copyimport{Login}from"./src/features/user/login";但是如果我们将baseUrl设置为./src,我们就可以在使用绝对路径的时候去掉重复的前缀。路径更短:copyimport{Login}from"features/user/login";相对路径不需要baseUrl,因为它是相对于当前文件路径计算的。./来源是tsconfig.json配置文件所在的目录路径。其实也可以写成src,相当于./src。如果不设置baseUrl,模块文件导入需要使用相对路径,或者绝对路径(不是项目根目录的绝对路径,而是完整路径)。如果要使用相对于项目根目录的路径,则需要将baseUrl设置为.paths路径重映射。要使用路径,首先设置baseUrl,路径的源路径和新路径将使用baseUrl作为相对路径计算。复制"baseUrl":"./src","paths":{"@lib/*":["./other/_lib/*","./other/_lib2/*"]},上面的配置,就是将other/_lib和other/_lib2路径重新映射到@lib。这里的@不是必须的。这样写只是表明这条路径是一个重映射,或者别名。实际上,文件系统上并没有对应的真实目录。这样,原来比较冗长的路径:copyimportLibAfrom"other/_lib/lib_a";可以改为:copyimportLibAfrom"@lib/lib_a";声明是否生成相应的d。ts类型声明文件。TS编译成的JS是不带类型信息的。如果要保留信息,需要一个d.ts文件来描述对应的JS文件。我们使用NPM安装的第三方包。这些包下的package.json文件的types属性指定了包的类型文件。如果未明确提供类型属性,则使用默认的index.d.ts。declarationDir指定编译生成的类型声明文件的输出目录。如果不提供,默认会和生成的js文件放在一起。Copy"declarationDir":"./types"outDir编译文件的输出目录,默认为.,即项目根目录。如果不设置,编译后的文件会和源文件混在一起。通常我们会将outDir设置为“./dist”。outFile将所有ts文件合并编译生成一个js文件及其类型声明d.ts文件。这个配置项很少用到,因为它只能用在不支持模块化导入的系统中,即所有ts文件都是全局的。也就是说,模块配置项需要为None、System或AMD。复制"outFile":"./app.js"模块编译后的JS使用的模块系统。常用的模块系统有两种:ESModule和CommonJS。前者是ES的标准(使用import关键字),后者是Nodejs使用的模块系统(使用require)。还有AMD、UMD等,支持的值有:none、commonjs、amd、umd、system、es6/es2015、es2020、es2022、esnext、node16、nodenext。它们的具体区别可以看官方文档的代码示例:https://www.typescriptlang.org/tsconfig#module。如果target是ES3或ES5,则默认值为CommonJS(毕竟ES6之后ESModule可用);否则就是ES6/ES2015。allowJs将js文件作为编译对象,可以通过ts文件导入。布尔值,默认为false。引入类型声明的一种方法是@types包。例如,React框架使用流作为类型系统。为了支持TypeScript,React团队编写了一套d.ts类型文件,并发布在@types/react包中。然后我们下载这个类型包之后,用importReactfrom'react'之类的,TS会去node_modules/@types里面找react文件夹,如果找不到就继续往上层目录找,直到找到找到了。如果存在,React对象将被分配声明的类型。@types可以是模块类型声明(如React类型),或全局类型声明(如nodejs进程对象类型)。types配置可以指定使用哪些全局类型声明,而不是node_modules/@types下的所有类型声明。例如:copy"lib":["node",//即node_modules/@types/node"jest"]typeRoots前面说过ts会递归搜索node_modules/@types寻找类型声明文件。但是也可以使用typeRoots来指定只查找特定目录下的类型声明文件,如:结束了,不过我觉得基本上掌握以上配置的使用就差不多了。更多配置项请参考官方文档。建议搭建一个TS工程进行测试。