typescript编译选项esModuleInterop的作用

esModuleInterop选项的作用是支持使用import d from 'cjs'的方式引入commonjs包。

引入commonjs模块的方式

无类型声明文件

如果一个模块没有类型声明,可以直接使用const cjs = require('cjs')的方式引入模块,此时cjs的类型是any

有类型声明文件

1.使用import cjs = require('cjs')方法引入

2.使用import * as cjs from 'cjs'方法引入,此时cjs相当于exports变量(虽然这能够正常工作,但其实不符合es模块规范,es模块规范规定cjs这个命名空间只能是一个纯对象,但是不能够直接调用,以koa举例)

import * as Koa from 'koa';
// 不符合规范
const app = new Koa();

// 编译后的结果
const Koa = require("koa");
const app = new Koa();

那怎么才能使用import cjs from 'cjs'语法呢?

首先你需要去除类型检查(允许从没有设置默认导出的模块中默认导入),这可以使用allowSyntheticDefaultImports配置项帮你达到。

其次你的导出需要有default属性,因为allowSyntheticDefaultImports只是帮你去掉类型检查,但是并不会影响编译后的代码输出,假设没有default属性,虽然可以正常编译,但是在运行时还是会报错的,这就需要esModuleInterop配置帮你完成了,因为对于大对数模块而言,并没有default属性。

esModuleInterop配置提供的帮助

提供两个helper函数__importStar__importDefault分别处理import * asimport default

例如对于下面的代码:

import * as foo from "foo";
import b from "bar";

编译后的结果:

"use strict";
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;
}
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
}
exports.__esModule = true;
var foo = __importStar(require("foo"));
var bar_1 = __importDefault(require("bar"));

可以看到会主动帮你设置default属性

allowSyntheticDefaultImports和esModuleInterop的关系

开启esModuleInterop后会默认开启allowSyntheticDefaultImports选项

发布了78 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/juzipidemimi/article/details/103438437
今日推荐