Skip to content

bundler

bundler 是 TypeScript5.x 新增的一个模块解析策略,这其实是社区倒逼的标准,是对现实的妥协。

比如vite,声称是完全基于ESM的打包工具,但是为了用户方便,声明相对路径模块的时候却不要求写扩展名。这其实是和ESM的标准冲突的,但是这种做法是没有毛病的。本身用户之前已经习惯了在引入模块的时候不写后缀名,毕竟甚至好多程序员都已经把文件夹下写一个index.js当成标准了。

但是问题就出在现有的几个模块解析策略,都不能完美适配 vite + typescript + esm 的开发场景:

如果moduleResolution:node,对于esm支持不好

如果moduleResolution:node16 / nodenext,强制要求使用相对路径模块时必须写扩展名

moduleResolution:node16 / nodenext实际上算是typescript中完美的解决方案,但是在打包器环境中实在是非常尴尬。

所以才有了moduleResolution:bundler,目的就是告诉你,模块解析就交给打包器了,typescript不再负责,而且不负责模块解析的话,由typescript去编译生成js文件就并不安全了

而且选择bundler的话,module就只能是ESM相关的配置

搭配 module 和 moduleResolution

说了这么多,关键是到底怎么配置这两个东西?

如果打算编写 commonJS 风格的 nodejs 程序,不支持解析exports字段:

typescript
"module": "CommonJS"
"moduleResolution": "Node"

如果打算nodejs 程序支持比较新的内容,无论模块化commonjs还是es module选择:

typescript
"module": "NodeNext"
"moduleResolution": "NodeNext"

当然,ESM需要设置 package.json"type": "module",要么通过后缀区分.cjs, .mjs

如果在vite环境中:

typescript
"module": "ESNext"
"moduleResolution": "Bundler"

如果在webpack相关的打包环境中:

typescript
"module": "ESNext"
"moduleResolution": "node"