Open jtwang7 opened 2 years ago
在默认情况下,ts 会将 esm 模块编译成 commonjs:
export default
module.exports
default
export
__esModule: true
在 npm 包中,react 是以如下形式导出的:
module.exports = require('xxx');
可以发现:通过 npm 方式引用 react 时,默认是以 commonjs 方式导出的。 而根据 TS 默认编译的规则,esm 模块中通过 import React from 'react' 引入的方式,最终会被编译成到 module.exports.default 上拿代码。
module.exports.default
import * as React from 'react'
其实不仅仅是引入react,在ts默认编译时,在 esm 中引入任何 commonjs 的模块都会有这样的问题。 因此 ts 配置文件提供了:
这两个配置来影响ts默认的解析。
allowSyntheticDefaultImports 是一个类型检查的配置,它会把 import 没有 exports.default 的报错忽略,如果你的target是 es6 加上这个配置就够了,但如果你的目标代码是 es5 仅仅加上这个还不行,还需要使用 esModuleInterop,因为它才会改变tsc的编译产物。
allowSyntheticDefaultImports
exports.default
esModuleInterop
Reason
在默认情况下,ts 会将 esm 模块编译成 commonjs:
export default
的变量,TS 会将其放在module.exports
的default
属性上export
的变量,TS 会将其放在module.exports
对应变量名的属性上__esModule: true
的属性,用来告诉编译器,这本来是一个 esm 模块在 npm 包中,react 是以如下形式导出的:
可以发现:通过 npm 方式引用 react 时,默认是以 commonjs 方式导出的。 而根据 TS 默认编译的规则,esm 模块中通过 import React from 'react' 引入的方式,最终会被编译成到
module.exports.default
上拿代码。import * as React from 'react'
则会把 React 作为为一个对象因此不会有问题。Expand
其实不仅仅是引入react,在ts默认编译时,在 esm 中引入任何 commonjs 的模块都会有这样的问题。 因此 ts 配置文件提供了:
这两个配置来影响ts默认的解析。
allowSyntheticDefaultImports
是一个类型检查的配置,它会把 import 没有exports.default
的报错忽略,如果你的target是 es6 加上这个配置就够了,但如果你的目标代码是 es5 仅仅加上这个还不行,还需要使用esModuleInterop
,因为它才会改变tsc的编译产物。Conclusion