TypeScript – tsconfig


前言

上一篇  使用了命令

tsc index.ts --module es2015

很少人会在命令时给写 config, 更正规的做法是创建一个 tsconfig.json 把所有 config 写到里面去. 类似 webpack.config.js, tailwind.config.js, .eslintrc.json, prettier.config.js, stylelint.config.js

参考

详解tsconfig.json文件 (must read)

Create tsconfig.json

tsc --init

运行命令后就会创建出 tsconfig.json 了

里面包含了所有 config 和 注释. 有需要的就开启.

常用 Config

1. target

{
    "target": "es2016"
}

target 指的是 TypeScript transpile 出来想要生成什么 version 的 ECMAScript

ES3 已经完全没有人用了, ES5 应该是目前最低的配置了.

tsconfig 的 默认是生成 ES2016 也就是 ES7. 毕竟很少人要支持 Internet Explorer 了.

Angular 默认是生成 ES2017.

2. lib

{
    "target": "ES2016",
    "lib": ["DOM", "ES2016", "ES2017.Object"],
}

lib 和 target 通常是一套的. 它指的是在开发阶段, TypeScript 对应的 ECMAScript version.

我举个具体的例子你就明白了. 假设项目需要支持比较旧的游览器, 哪个游览器只支持 ES2016, 那么 target 就 set 成 ES2016 咯.

但是呢, 开发人员又很想用 ES2017 的某个功能, 比如 Object.values. 那怎么办? 要让游览器支持 Object.values 可以通过 polyfill (比如引入 core.js)

但是在开发阶段, TypeScript 不知道你有 polyfill, 所以如果你写 Object.values 它就报错提示你 (因为你 target ES2016 不能超过这个功能范围). 所以 lib 就排上用场了.

lib 就是让你声明开发阶段, 你的 ECMAScript version. 

"DOM" 声明, 这个 TypeScript 用于游览器, 所以可以调用 document, window 这类接口

"ES2016" 声明, TypeScript 能写到 ES2016 的语法和各种 build-in 方法

"ES2017.Object" 声明, TypeScript 还能写到 ES2017 Object 的 build-in 方法 (比如 Object.values).

所以 target, lib, polyfill 的玩法就是这样拉.

注: lib 如果没有声明它 default 是 "DOM" 和 target 的 ECMAScript version, 一旦声明了它就是完全 override 掉 default 的.

p.s: 我为了做测试特地学了如何在 Windows 11 开启 Internel Explorer, 这里做个记入呗: Youtube – How to enable Internet Explorer on Windows 11

3. files, include, exclude

这 3 属性都是用来设定 .ts files 扫描范围的

默认情况下, tsconfig sibling 和 descendant 的 .ts 都会被 transpile to .js

例子说明:

注: 它不是 complilerOptions 的属性哦, 是最外面对象的属性

这是 files 结构

files 只能指定具体的 file 不能写 glob

include 和 exclude 则可以写 glob

通常设置的方式是这样的, include 你要的大范围, files 一些例外 (out of inclde 范围的), exclude 一些例外 (在 include 范围内的)

4. outDir & rootDir

{
    "rootDir": "./src",
    "outDir": "./dist",
}

rootDir 我也不清楚什么时候会用到, outDir 就是指 transpile 后的 .js 要 output 到哪里. 默认情况下是 output 到 .ts 的 sibling.

配置成 ./dist 以后, 它就会创建一个 dist folder, 然后依据 .ts 结构 output 到 dist 里面.

5. removeComments

{
    "removeComments": true,    
}

顾名思义, 就是把 .ts 里面的 comment 在 transpile 过程中移除. .js file 里面就看不到任何 comment 了

6. sourceMap, inlineSourceMap

{
    "sourceMap": true,
}

transpile 的 JavaScript 阅读非常不友好, runtime debug 就会很困难. 开启 sourceMap compiler 就会创建一个 .map 的 file

这样 chrome dev tool / debuger 就可以找到 erorr 在 .ts 源文件的位置. 开发阶段必开.

p.s: inlineSourceMap 就是它会把 mapping 放入 .js 文件, 而不是创建都都一个 .map 的 file.

7. module

JavaScript 的 modular 是出了名的混乱. 可以看这篇 .

JavaScript 又可以用于前端 Browser 和后端 Node.js. 所以 TypeScript 需要兼顾到这些.

如果是 for Node.js 那么 module 的值是 "CommonJS" 或者 "ES2020".

如果是 for Browser 而且有使用 module bundler (e.g. Webpack), 那么 module 设置成 "ES2020" 就可以了, bunlder 会处理好一切. (像 Angular 那样)

如果没有使用 module bundler, 设置 "ES2020" 就表示完全使用游览器的 . 通常不是一个好主意. 现阶段最好还是使用 SystemJS 或者 RequireJS 来管理前端模块 (不然会需要加载很多 js files)

一个折中的方案是用 TypeScript Compiler 的 bundler 配上 SystemJS 或 RequireJS. module 设置成 "AMD" 或者 "System". 看这篇 TODO..

example:

8. moduleResolution

它有 2 个值, "Classic""Node". 默认是 Classic, 但凡你有用 node_modules 就设置成 Node 就对了.

它指的是当我们写 import {} from 'xxx' 的时候, TypeScript Compiler 怎么去找到这个 module.

想具体了解的话建议看这篇: 深入理解TypeScript的模块系统, 讲的比较清楚.

9. outFile

上面有提到 TypeScript bundler, 它只是一个简单 for 单元测试的工具, TypeScript 的职责是 transpile 不是 bundle. 

bundle 还是用 Webpack 之类的比较好.

{
    "module": "System",
    "outFile": "./dist/bundle.js",  
}

设置 outFile 以后, 最后只会生成一个 bundle.js 所有代码都在里头. 必须配上 SystemJS 或者 RequireJS 才能发挥功效哦.

10. declaration, declarationDir

{
    "declaration": true
}

TypeScript transpile 除了生成 .js 还可以生成 .d.ts 类型文件.

这个对 Library 发布就很重要, 因为有了 .d.ts, 那些使用 Library 开发者即使没有用 TypeScript 也可以通过 VS Code 得到很多类型的提示.

11. allowJs, checkJs

{
    "allowJs": true,
    "checkJs": true,
}

TypeScript 默认配置是不允许 import js 的, 如果想 import js 文件那么需要在 tsconfig 设置 allowJs

JavaScript 是没有类型检查的, 但如果你想让它带有一点类型检查, 但又不要像 TypeScript 那么 "类型", 可以开启 checkJs

这个功能和 VS Code 的 Working with JavaScript 是一样的

// @ts-check, // @ts-ignore // @ts-nocheck 配上 checkJs 一同使用

使用注释来声明类型

例子可以看这篇 TODO...

12. typeRoots, types

看这篇 TODO...

13. paths

{
    "paths": {
      "local-library": ["./local-library/local-library"],
      "local-library/*": ["./local-library/*"],
    },
}

这个常用在本地 Library. 

当配置好 paths 以后, import 的时候就不走 relative path 了, 反而是像 import node_modules 的 module 那样, 直接写名字

import { localLibraryFunction } from 'local-library';
import { abc } from 'local-library/abc';

这些名字就会去 tsconfig paths 做匹配, 然后去寻找 .ts 文件. 它就是这样串起来用的. 

相关