TL; DR
事实上,ES import语句
import default和
import*不一样的东西,他们的行为在这种情况下,同样的事实是如何反应作者选择发布的库和兼容层以打字稿联合使用(使用
esModuleInterop)或巴贝尔和你捆绑,使他们“正常工作”。根据ES6规范,它可能
不应该 工作,但是今天,我们仍处于一个JS模块混乱的时代,因此Babel,Typescript,Webpack等工具试图规范行为。
更多细节:
React不是ES6库。如果您查看源代码,则会在以下代码中看到它
index.js:
const React = require('./src/React');// TODO: decide on the top-level export form.// This is hacky but makes it work with both Rollup and Jest.module.exports = React.default || React;(请注意注释,即使在React源代码中,它们也难以与ES6默认导出兼容性兼容。)
该
module.exports=语法是CommonJS的(的NodeJS)。浏览器不会理解这一点。这就是为什么我们使用诸如Webpack,Rollup或Parcel之类的捆绑器的原因。他们了解各种模块语法,并产生应在浏览器中工作的捆绑软件。
但是,尽管React不是ES库,但Typescript和Babel都允许您将其导入为原样(使用
import语法,而不是
require(),等等),但是CJS和ES之间必须解决差异。其中一个事实是,您
export=可以
得到ES没有符合规范的导入方式,例如函数或类作为模块。为了解决这些不兼容问题,Babel允许您暂时导入CJS模块,就像默认情况下它们正在导出某些内容一样,
或者
作为命名空间导入。Typescript暂时没有执行此操作,但最近在下方将其添加为一个选项
esModuleInterop。因此,现在Babel和Typescript都可以非常一致地允许使用默认或名称空间ES导入来导入CJS模块。
使用Typescript,它还取决于实际定义库的类型定义的方式。我不愿赘述,但是您可以想象这样的情况:由于使用了编译器和捆绑器,特定的导入
可以在运行时进行 ,但是Typescript不会没有错误地进行编译。
值得一提的另一件事是,如果您查看React的内置代码,则有UMD模块版本和CJS版本。UMD版本包含一些粗糙的运行时代码,以尝试使其在任何模块环境(包括浏览器)中都能工作。如果您只想在运行时包含React(即您不使用捆绑程序),则主要用于此。实例。
令人困惑?是的,我是这样认为的。:)



