esModuleInterop 到底做了什么?

作者&投稿:薄环 (若有异议请与网页底部的电邮联系)
~ 很多 React 开发者在从 JavaScript迁移到 TypeScript(TS)时,会遇到一个关于导入问题的困惑。在 JavaScript中,引入React模块通常是这样的:

然而,在 TypeScript中,引入方式却变成了这样:

当尝试在TypeScript中模仿JavaScript的导入方式时,编辑器会报错,指出该模块是由 "export =" 声明的,仅在启用 "esModuleInterop" 标志时与默认导入一起使用。要解决这个问题,需要在 `tsconfig.json` 文件中设置 `compilerOptions.esModuleInterop` 为 `true`。

理解这一问题的关键在于了解JavaScript的模块系统。常用的JavaScript模块系统有三种,其中AMD模块系统已经较为少见,故略过。在TypeScript和Babel编译器中,更倾向于使用CommonJS(CJS)模块。默认情况下,代码中表示的ES模块(ESM)都会被转换为CJS模块。

回到开头的问题,打开React库的`index.js`文件,可以发现React基于CJS模块,等效于:

而`index.ts`文件中,写入一段代码:

编译后的代码为:

因此,打印结果为`undefined`,因为`react`模块的`module.exports`中没有`default`属性,后续获取`React.createElement`和`React.Component`等函数时自然会报错。

这一问题引申出的是,大量现有的第三方库大多使用UMD或CJS模块,而前端代码几乎都是使用ESM模块。因此,ESM和CJS模块之间需要一套规则来实现兼容。

在TypeScript中,默认的导入转换规则为:

而对于`export`变量的转换规则为:

在启用`esModuleInterop`属性后,TypeScript对于导入的转换规则发生了变化(`export`规则保持不变):

这里,对于默认导入和命名空间(`*`)导入,TypeScript使用了两个辅助函数来协助转换。

首先,`__importDefault`函数做的事情是:

比如上面的导入语句,编译后再层层翻译:

这样就成功获取了`react`模块的`module.exports`。

接下来是`__importStar`函数,它做的事情是:

(对`__importStar`的层层翻译分析过程省略)

在默认情况下,Babel的转换规则与启用`esModuleInterop`的TypeScript情况相似,同样通过两个辅助函数来处理。

关于`_interopRequireDefault`和`_interopRequireWildcard`函数,它们分别类似`__importDefault`和`__importStar`。

在特殊的Webpack环境中,通常情况下,Babel和TypeScript会一起使用Webpack。而Webpack与TypeScript的结合有两种方式:

如果使用`ts-loader`,Webpack会先将源代码交给TypeScript编译器(tsc)进行编译,然后处理编译后的代码。编译后的所有模块都会变为CJS模块,因此Babel不会进行处理,直接交给Webpack以CJS方式处理模块。

如果使用`@babel/preset-typescript`,Webpack不会调用tsc,忽略`tsconfig.json`配置,而是直接使用Babel编译TS文件。这个编译过程相比调用tsc轻得多,因为Babel只会简单移除所有TS相关代码,不做类型检查。在这种情况下,一个TS模块通过Babel的`@babel/preset-env`和`@babel/preset-typescript`两个预设处理。后者的工作很简单,仅去除所有TS相关代码,不处理模块,前者则将ESM转换为CJS。然而,Webpack的`babel-loader`在调用`babel.transform`时,传入了`caller`选项:

这导致Babel保留了ESM的`import`和`export`语法。

Webpack为模块提供了一个runtime机制,使得Webpack在模块闭包中注入代表`module require`和`exports`的变量,因此Webpack处理模块对于自身而言较为自由。

在CJS引用ESM的场景中,Webpack的编译机制较为特别,通过`_webpack_require__`类似于`require`,返回目标模块的`module.exports`对象。`_webpack_require__.n`函数接收一个参数对象,返回一个对象,该返回对象的`a`属性(其确切名称未知)会被设定为参数对象。因此,上述源代码的`console.log(cjs)`会打印出`cjs.js`的`module.exports`。

总结:当前许多常用的包基于CJS/UMD开发,而前端代码主要使用ESM,常见场景是ESM导入CJS库。由于ESM和CJS在概念上存在差异,最大的差异在于ESM有`default`概念而CJS没有,因此在`default`上会遇到问题。TypeScript、Babel、Webpack都有各自的处理机制来解决这个兼容问题,核心思想基本都是通过添加和读取`default`属性来实现。


找个英语高手,谁帮我把初一下学期的英语一些公式写出来啊!比如:like...
Phrases in Module 1 1.have a good time = enjoy oneself 玩得很开心 2.match …with 与…配对 3.on the Great Wall 在长城上 4.talk to 对…说话 5.on a school trip 学校外出活动 6.That’s great 太棒了 7.the others 其他的(人\/物)8.lots of 许多,大量的 9.eat lunch 吃...

Python中list,tuple,dict,set的区别和用法
Python中的List是有序的,所以要访问List的话显然要通过序号来访问,就像是数组的下标一样,一样是下标从0开始:>>> print L[0]12 千万不要越界,否则会报错 >>> print L[3]Traceback (most recent call last):File "<stdin>", line 1, in <module> IndexError: list index out of range...

python中print'% s'报错?
python中TypeError: not all arguments converted during string formatting解决方法例如:>>> str=(1,2,3) #创建一个集合 >>> str (1, 2, 3)>>> print 'str= %s ' % str Traceback (most recent call last):File "<pyshell#43>", line 1, in <module> print 'str= %s ' % st...

电脑开机就出现这个 帮忙解决下 谢谢
电脑开机就出现这个帮忙解决下谢谢开机就出现Accessviolationataddress031F6B18inmodule'esatb.dll'.Readofaddress00000004... 电脑开机就出现这个 帮忙解决下 谢谢开机就出现 Access violation at address 031F6B18 in module 'esatb.dll' . Read of address 00000004 展开  我来答 5个回答 #热议# 该不该让...

服装用语英语翻译
太长了

ACCA的OBU学位怎么在官网查看是否open in
1.注册过这个学位(可以在My ACCA中查看此学位的状态是否为opted-in)2.通过前九门考试(F7,F8,F9不可以免考) 3.在通过F7,F8,F9之前提交并通过英语成绩证明4.完成道德模块测试(Professional Ethics module二、英语成绩证明提交:在2014年6月及之前通过的F4考试可以直接当做英语证明,无需另外提交;在2014年12月及之后...

module 到底是什么意思
module[英][ˈmɒdju:l][美][ˈmɑ:dʒul]n.模块; 组件; (宇宙飞船上各个独立的)舱; 测量流水等的单位;复数:modules 例句:1.By one count there are at least 30 listed solar-cell and module makers globally.据统计,全球目前至少有30家上市的太阳能电池和模块...

s( )m补充英语单词
Your search for s-m matched 3 words in this word list sim abbr.模拟(=simulation)abbr.(=subscriber identity module)【信】用户识别卡 n.模拟电脑(或电子)游戏 网络模拟经营(Simulation);新加坡管理学院(Singapore Institute of Management);手机卡 som n.管理学院 n. 索姆(吉尔吉斯共和国货币...

INN实现深入理解
F_fully_connected 类使用包含四层全连接层的神经网络实现 INN 基础构建块中的 s、t 转换。其本身是不可逆的。 2. Coupling layers F_* 类本身都是不可逆的,而 coupling_layers 层中的类就是赋予 INN 可逆能力的。 class FrEIA.modules.coupling_layers.rev_layer(dims_in, F_class=<class 'FrEIA.modules...

求外研版高中英语必修1 module3 my first ride on the train 的introd...
Yang Liwei is China’s first astronaut. He was a pilot in the army. He was chosen from 1,500 other army pilots and started training for his space flight in 1998. During the 21-hour space flight, he circled the earth 14 times. When the spaceship was doing its seventh circle, Yang ...

秦都区19484342667: 从······到······ 英文 -
禤顾麦角: 从······到的英文:From... to From 读法 英 [frɒm; frəm] 美 [frʌm]prep. 来自,从;由于;今后 短语: 1、out from 从…中迸出 2、from then on 从那时起 3、to and from 往返;来来回回 4、from out of 从…之中 5、due from 应收 扩展...

秦都区19484342667: until需要改成to吗from until 与from to与神魔区别 -
禤顾麦角: 两者的意思从中文上讲差不多,有时也可以互换的,(当然to后不能接从句) from until “从....直到.....” from to “从....到.....” 但from until “我从四岁直到六岁,都在破坏玩具”,有一点暗含的意思:六岁后我就不破坏了 from to就没有这一暗含的意思,只表示四到六岁破坏,六岁以后还会不会破坏就不知道了

秦都区19484342667: “追溯到”用英文怎么说? -
禤顾麦角: trace back to ; go back to ; date to ; retrospect to ; ascend to trace 英 [treɪs] 美 [tres] n. 痕迹,踪迹;微量;[仪] 迹线;缰绳 vt. 追踪,查探;描绘;回溯 vi. 追溯;沿路走 retrospect 英 ['retrəspekt] 美 ['rɛtrəspɛkt] n. 回顾,追溯 vt. 回顾;追忆 vi. ...

秦都区19484342667: AI 复制到 其他图层 却被 粘贴回 原图层 -
禤顾麦角: 可能是被勾选了“粘贴记住本层”选项,解决: 图层面板———点击右上角多选项下拉菜单————去掉“粘贴记住本层”的勾选.

秦都区19484342667: 从.到.用英语怎么说 -
禤顾麦角: 答案: from ..... to ....from January to March 从一月到三月

秦都区19484342667: 到……的时间了 用英语怎么说 -
禤顾麦角: It's time to .....

秦都区19484342667: 认识到 英语怎么说 -
禤顾麦角: 认识到的英文翻译是realize,在句中作为动词使用,具体解析如下: realize 英 [ˈri:əlaɪz] 美 [ˈriəˌlaɪz] vt.实现;了解,意识到;(所担心的事)发生;以…价格卖出 vt.& vi.变卖,赚得 相关短语: 1、realize aim 实现目标 2、realize ...

秦都区19484342667: 苹果手机更新软件但一点进去就跳到此程序上 -
禤顾麦角: 你好, 最近很多人都出现了这样的问题,点击更新后会直接打开APP. 不过不用担心,其实这并不是手机出了毛病,而是苹果的AppStore出了问题. 如果App有新版本需要更新的话,可以在电脑上通过Itunes来进行App更新, 目前Itunes还是可以正常使用的. 或者也可以暂时不进行更新,等到AppStore恢复之后再更新,苹果应该很快就会修复的. 望采纳噢

秦都区19484342667: 如何将一张EXCEL表格中符合条件的数据导入到另一张表中 -
禤顾麦角: 假设将表1的A列大于100的内容,导入表2的A列中.表2的A1公式:=IF(表1!A1<100,"",表1!A1)将公式向下拖拽复制公式.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网