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

如何编写TypeScript配置文件?

时间:2023-03-16 10:12:50 科技观察

前言这篇文章是我的TypeScript系列文章的第5篇。今天我们就来看看如何编写TypeScript配置文件tsconfig.json。和package.json一样,它也是一个JSON文件。package.json是包描述文件,对应Commonjs规范,tsconfig.json是JSON文件,最终被TypeScriptCompiler解析使用。TypeScript编译器使用这个配置文件来决定如何编译项目。说到编译,就不得不提一个大名鼎鼎的播放器——babel。与TypeScript类似,它们可以将一种语法静态编译为另一种语法。如果说我想编译一个文件,我只需要告诉babel我的文件路径。npxbabelscript.js有时候想编译整个文件夹:npxbabelsrc--out-dirlibbabel也可以指定输出目录,指定需要忽略的文件或目录等,TypeScript也是一样的!当然,你可以像babel一样在命令行中全部指定,也可以将这些配置放在tsconfig.json中,以配置文件的形式传递给TypeScriptCompiler。这是tsconfig.json文件的初衷,它接受用户输入作为配置项。初看tsconfig让我们先看一个简单的tsconfig文件。{"compilerOptions":{"outDir":"./built","allowJs":true,"target":"es5"},"include":["./src/**/*"]}按照配置aboveDid:读取可识别的src目录中的所有文件(通过include)。接受JavaScript作为输入(通过allowJs)。所有生成的文件都放在构建目录中(通过outDir)。将JavaScript代码降级到较低版本,如ECMAScript5(通过目标)。实际项目比这更复杂。接下来,让我们仔细看看。不过在说配置项之前,我们先看看tsconfig.json是怎么解析的。tsconfig是怎么解析的?如果某个目录下有tsconfig.json文件,就说明这个目录是TypeScript项目的根目录。如果你使用tsc编译你的项目,并且没有显式指定配置文件的路径,那么tsc会逐步搜索父目录来找到tsconfig.json,这个过程类似于node的模块搜索机制。如图:在_uglify-js@3.7.2@uglify-js下执行tsc会找到配置文件1,在_uglify-js@3.7.2@uglify-js/bin下执行tsc也会找到配置文件1同理,在lib中,node_modules也会找到配置文件1。在_uglify-js@3.7.2@uglify-js/bin/lucifer下执行tsc会在_uglify-js@3.7.2@uglify-下执行tsc找到配置文件2。在js下执行tsc/lib/lucifer会找到配置文件3我从上帝的角度看TypeScriptOne讲述了TypeScript是干什么的,带你从宏观的角度看TypeScript。提到TypeScript编译器将接受一个文件或文件集合作为输入,并最终转换为JavaScript(noEmit为false)和.d.ts(declarations为true)。这里其实少了一点,就是除了接受文件或者文件集合作为输入外,还会接受tsconfig.json。tsconfig.json的内容决定了编译的范围和行为,不同的配置可能会得到不同的输出或不同的检查结果。当tsc找到一个tsconfig.json文件时,它指定的所有编译目录都会被typescript处理,包括它所依赖的文件。如果tsc没有找到tsconfig.json或者tsconfig没有有效信息,那么tsc将使用默认配置。例如tsconfig为空,则不会有有效信息:{}tsconfig的所有属性及其默认值都可以在这里找到:http://json.schemastore.org/t...总结tsc解析tsconfig.json逻辑。如果在命令行指定了配置选项或者指定了配置文件的路径,则直接读取。根据tsconfigjsonschema检查格式是否正确。如果正确,它将与默认配置合并(如果它有extends字段),将合并的配置传递给TypeScript编译器并开始编译。否则,将抛出错误。否则会从当前目录开始查找tsconfig.json文件,如果找不到则逐层查找父目录。如果找到,它将根据tsconfigjsonschema检查格式是否正确。如果正确,它将与默认配置合并(如果它有extends字段),将合并的配置传递给TypeScript编译器并开始编译。否则,将抛出错误。否则,如果还是找不到,那么就直接使用默认配置。tsconfig的顶层属性(TopLevel)并不多,主要有:compilerOptions、files、include、exclude、extends、compileOnSave等,compilerOptions是重头戏,它的属性也是最多的。我们的项目也有很多针对这个的定制,后面会重点介绍。files是你需要编译的文件exclude是你不需要编译的文件目录(支持glob)include是你需要编译的文件目录(支持glob)extends是继承另一个配置文件,TypeScript会合并它,更多项目公共配置很有用。也可以直接继承社区的“最佳实践”,比如:{"extends":"@tsconfig/node12/tsconfig.json","compilerOptions":{},"include":["src/**/*"],"exclude":["node_modules"]}compileOnSave是和编辑器(具体是文件系统)挂钩的配置,即文件保存后是否编译,实际项目不建议使用。除了compilerOptions,其他的都比较好理解。所以接下来我只会详细解释compilerOptions。tsconfig编译项的详细全面的内容,只需要参考官网即可。官网不仅全面,而且分类,一目了然。下面我就根据它们的作用说说几种常用的配置。以下四种是常用的与文件相关的。由于前面已经介绍过,所以不再详细介绍。excludeextendsfilesincludealwaysStrictcheckalwaysStrictDefault:false初始发布版本:2.1这个跟ECMAScript规范有关,工作机制和ES5的strict模式一样,输出JS的最前面也会有'usestrict'.noImplicitAny(建议开启)Default:trueFirstreleaseversion:-我在-TypeScript类型系统中提到过,如果你没有显式声明变量的类型,那么TypeScript会对该变量进行类型推导。当然,也有无法推演的情况。这时变量的类型是any,称为隐式any。区别于明确的任何:consta:any={};隐式any由TypeScript编译器推断。noImplicitThis(建议开启)默认值:true初版:2.0和implicitanytype,不过这次是针对一个特殊的关键字this,即需要显式指定this的类型。strict(建议开启)默认值:true首次发布版本:2.3其实strict只是简写,是多条规则的集合。类似于babel中plugins和presets的区别。换句话说,如果您将strict指定为true,那么将启用所有严格相关的规则。我说的严格检查都说了,还有一些我没说。另外,如果以后添加更严格的规则,只要开启strict,就会自动添加。ModuleResolutionModule相关用途:allowSyntheticDefaultImports、allowUmdGlobalAccess、esModuleInterop、moduleResolution都是为了兼容其他模块化规范而制定的。allowSyntheticDefaultImportsallowUmdGlobalAccessesModuleInteropmoduleResolution还有一个配置模块,指定了项目的模块化方式。选项包括AMD、UMD、commonjs等。路径相关用途:baseUrl、paths、rootDirs、typeRoots、types都是为了简化路径的拼写。baseUrl配置告诉TypeScript如何解析模块路径。例如:从“hello/world”导入{helloWorld};控制台日志(你好世界);这将从baseUrl.hello目录中找到world文件。Paths定义了类似别名的存在,从而简化了path的写法。注意rootDirs是rootDirs,不是rootDir,也就是说根目录可以有多个。当指定多个根目录时,不同根目录下的文件可以像在一个目录下一样相互访问。其实还有一个叫rootDir,和rootDirs的区别是只能指定一个。typeRootstypestypes和typeRoots我在-什么是类型和@types?已经解释的很清楚了,这里就不多说了。项目配置JavaScript相关allowJs默认值:false初始发布版本:1.8顾名思义,TypeScript项目中允许使用JavaScript,这对于从JavaScript迁移到TypeScript非常重要。checkJs默认值:false首次发布版本:-与allowJs类似,只是checkJs会额外验证JS文件。声明文件相关如果TypeScript将TS文件编译成JS,那么声明文件+JS文件可以反向生成TS文件。这两个sourcemap文件用于生成.d.ts和.d.ts。declarationdefault:falsefirstreleaseversion:1.0declarationMapdefault:falsefirstreleaseversion:2.9externallibraryrelatedjsxdefault:reactfirstreleaseversion:2.2这是告诉TypeScript如何编译jsx语法。libdefault:-firstreleaseversion:2.0lib我在TypeScript类型系统中介绍过。Typescript提供了lib.d.ts等类型库文件。随着ES的不断更新,JavaScript的类型和全局变量会逐渐增多。Typescript也是用这个lib的方法来解决的。(TypeScript提供的lib的一部分)outDir和outFile输出相关的两个配置,是告诉TypeScript在哪里生成文件。outDirdefault:与ts文件同目录(同名,但后缀不同)firstreleaseversion:-outFiledefault:-firstreleaseversion:1.0模块是CommonJS和ES6模块不知道outFile,只有None,System或AMD会工作,它会在全局文件内容之后打包这些模块的文件内容。而noEmit控制是否输出JS文件。noEmit默认值:false首次发布版本:-如果你只想使用TypeScript进行类型检查而不希望它生成文件,你可以将noEmit设置为true。target是输出JavaScript基准ECMA规范。比如"target":"es6"就是把es6+的语法转成ES6的代码。它的选项有ES3、ES5、ES6等,为什么没有ES4呢?^_^总结tsconfig只是一个JSON文件,TypeScript用来决定如何编译和检查TypeScript项目。和babel类似,甚至很多配置项都是环环相扣的。如果某个目录下有tsconfig.json文件,就说明这个目录是TypeScript项目的根目录。如果你使用tsc编译你的项目,并且没有显式指定配置文件的路径,那么tsc会逐步搜索父目录来找到tsconfig.json,这个过程类似于node的模块搜索机制。tsconfig中最重要的可能是编译器选项(compilerOptions)。如果按照功能来背会比较简单,比如哪些文件是相关的,哪些是经过严格检查的,哪些是声明文件等等。