浅析tsconfig.json中module, moduleResolution, target, lib的作用

背景

  1. 业务部门这一年全面拥抱 typescript, 再也不直接使用 js 编写代码。但是我们知道 ts 实际上还是会被编译成 js 的,tsconfig.json则起到重要作用, 其中module, moduleResolution, target, lib这些 field 及其 value 长得好像都差不多, 所以一直没搞清楚这些 field 是做什么的

module

定义模块解决方案, typescript 中都是通过import/export处理模块, 但编译成 js 存在AMD, CMD, ES20XX, commonjs等多重模块解决方案, 这里的建议是运行在浏览器的项目使用ES20XX, 因为现代浏览器大多已经原生支持import/export; 运行在 node.js 的项目使用commonjs, 高版本的 node 版本才开始支持import/export, commonjs会使用module.export/require引入模块, 其余值很少用到.

不同 module 编译出的代码

commonjs

es20xx

如果明确项目是运行在高版本 node, 可以尝试使用ES20XX, 但是也需要注意引入的第三方 npm 包是否支持, 在 nestjs 中尝试使用ES20XX就会有报错, 于是老老实实的使用commonjs

moduleResolution

定义编译器如何找到(处理)引入的包文件, 共有两种可用的模块解析策略: nodeclassic, node是 typescript 现在默认的解析策略, classic更多是用于向下兼容, 很少回去配置改 field, 保持默认即可

target

定义编译为什么版本的代码, 我们都知道,es2015~es20xx 每年都会新增新的 api 和新的语法, 例如 es2017 之后可以使用async/await, target 设置为es2017编译时tsc就不会对该语法做 polyfill, 设置为es2015就会进行 polyfill

不同 target 编译出的代码

可以看到当设置 es2015 时会对async/await做 polyfill

es2017

es2015

lib

定义支持的类型声明, 大部分情况下都是和 target 一致, 除了一些特殊场景, 比如: 1. target 设置了 es5 但是存在对 Promise 的 polyfill 处理 2. 运行在浏览器中需要 BOM/DOM 对象类型声明, 可以设置数组

ts or babel

另外 typescript 是可以直接代码编译为 es5 的, 但是目前业界前端打包方案还是愿意将 babel 和 typescript 结合使用, 反正是有好处=。=

babel 和 ts 都会转换语法,两者是冲突的,一般不会同时出现。然后 Promise 是 api,Symbol 是内置类型,api 可以通过 polyfill 在不支持的环境上获得支持,但类型不支持就是不支持,没有 polyfill。而且现代浏览器基本都支持 promise 和 symbol,没什么好担忧的

reference

  1. Typescript confusion: tsconfig.json module, moduleResolution, target & lib explained
  2. Typescript tsconfig.json 全解析
  3. Intro to the TSConfig Reference
  4. 用了 typescript 还需要 babel 或者 polyfill 吗?
  5. 为什么说用 babel 编译 typescript 是更好的选择

浅析tsconfig.json中module, moduleResolution, target, lib的作用
https://mariana-yui.github.io/2022/05/15/2022-05-15-tsconfig-confused-field-explain/
作者
Mariana
发布于
2022年5月15日
许可协议