浅析tsconfig.json中module, moduleResolution, target, lib的作用
背景
- 业务部门这一年全面拥抱 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
定义编译器如何找到(处理)引入的包文件, 共有两种可用的模块解析策略: node
和classic
, 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,没什么好担忧的