esModuleinterop
当没有加esModuleInterop时
库的代码:
ts
export const a = 1
export default function b() {}
生成代码
js
exports.__esModule = true
exports.a = 1
function b() { }
exports.default = b
使用库的代码:
ts
import * as lib from './export'
console.log(lib)
生成代码
js
exports.__esModule = true
const lib = require('./export')
console.log(lib)
ts
import lib from './export'
console.log(lib)
生成代码
js
exports.__esModule = true
const export_1 = require('./export')
console.log(export_1.default)
以上代码使用ts生成代码都是可以的。但是如果我们使用的库是第三方的,比如fs。我们的代码如下
ts
import fs from 'node:fs'
console.log(fs)
生成代码
js
exports.__esModule = true
const fs_1 = require('node:fs')
console.log(fs_1.default)
fs是没有default属性的,所以这种使用fs的方法是不对的。
所以,不加esModuleInterop时,正确引用fs的方法是下面这样:
ts
import * as fs from 'node:fs'
// 或者
import { fsync } from 'node:fs'
console.log(fs)
console.log(fsync)
加上esModuleInterop,代码
ts
import * as lib from './export'
console.log(lib)
编译为:
js
const __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule)
return mod
const result = {}
if (mod != null) {
for (const k in mod) {
if (Object.hasOwnProperty.call(mod, k))
result[k] = mod[k]
}
}
result.default = mod
return result
}
exports.__esModule = true
const lib = __importStar(require('./export'))
console.log(lib)
代码
ts
import lib from './export'
console.log(lib)
编译为
js
const __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { default: mod }
}
exports.__esModule = true
const export_1 = __importDefault(require('./export'))
console.log(export_1.default)
这时
ts
import fs from 'node:fs'
console.log(fs)
就可以正常使用了。
总结:
因为很多老的js库使用了commonjs的导出方式,并且没有导出default属性,而是使用module.exports=xxx直接导出,这样会导致 import fs from 'fs';的语法引入失败。
typescript为了兼容这些js库,于是引入了esModuleInterop,使import fs from 'fs'能正常使用。