當沒有加esModuleInterop時
庫的代碼:
export const a = 1; export default function b() {}
生成代碼
exports.__esModule = true; exports.a = 1; function b() { } exports["default"] = b;
使用庫的代碼:
import * as lib from './export';
console.log(lib);
生成代碼
exports.__esModule = true; var lib = require("./export"); console.log(lib);
import lib from './export';
console.log(lib);
生成代碼
exports.__esModule = true; var export_1 = require("./export"); console.log(export_1["default"]);
以上代碼使用ts生成代碼都是可以的。
但是如果我們使用的庫是第三方的,比如fs。我們的代碼如下
import fs from 'fs';
console.log(fs);
生成代碼
exports.__esModule = true; var fs_1 = require("fs"); console.log(fs_1["default"]);
fs是沒有default屬性的,所以這種使用fs的方法是不對的。
所以,不加esModuleInterop時,正確引用fs的方法是下面這樣:
import * as fs from 'fs'; console.log(fs); // 或者 import {fsync} from 'fs'; console.log(fsync);
加上esModuleInterop,代碼
import * as lib from './export';
console.log(lib);
編譯為:
var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; exports.__esModule = true; var lib = __importStar(require("./export")); console.log(lib);
代碼
import lib from './export';
console.log(lib);
編譯為
var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; exports.__esModule = true; var export_1 = __importDefault(require("./export")); console.log(export_1["default"]);
這時
import fs from 'fs';
console.log(fs);
就可以正常使用了。
總結:
因為很多老的js庫使用了commonjs的導出方式,並且沒有導出default屬性,而是使用module.exports=xxx直接導出,這樣會導致 import fs from 'fs';的語法引入失敗。
typescript為了兼容這些js庫,於是引入了esModuleInterop,使import fs from 'fs'能正常使用。