"import * as React from 'react'; 与 import React from 'react'; 的异同"
P粉596161915
P粉596161915 2023-08-22 19:59:28
0
2
356
<p>我注意到<code>React</code>可以这样导入:</p> <pre class="brush:js;toolbar:false;">import * as React from 'react'; </pre> <p>...或者这样导入:</p> <pre class="brush:js;toolbar:false;">import React from 'react'; </pre> <hr /> <p>第一种方式导入了<code>react</code>模块的所有内容(参见:导入整个模块的内容)</p> <p>第二种方式只导入了<code>default</code>模块导出(参见:导入默认导出)</p> <hr /> <p>这两种方式似乎是不同且根本上不兼容的。</p> <p>为什么它们都能工作?</p> <hr /> <p>请参考源代码并解释机制...我对了解这是如何工作感兴趣。</p> <hr /> <p><strong>更新</strong></p> <p>这不是一个重复的问题,不同于“import * as react from 'react' vs import react from 'react'的区别”</p> <p>那个问题是通过一般的ES6模块信息回答的。</p> <p>我问的是使<code>react</code>模块能够这样工作的机制。它似乎与源代码中的“hacky”导出机制有关,但不清楚它如何使导入整个模块和只导入默认导出到<code>React</code>的两种方式都能与转译JSX等工作。</p>
P粉596161915
P粉596161915

全部回复(2)
P粉023650014

TL;DR

实际上,ES的import语句import defaultimport *并不是同一回事,它们在这种情况下表现相同是因为React作者选择以这种方式发布库并在TypeScript(使用esModuleInterop)或Babel以及打包工具中使用兼容层使其“正常工作”。根据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都允许你像导入ES库一样导入它(使用import语法,而不是require()等),但是CJS和ES之间存在一些需要解决的差异。其中之一是export =可以为你提供ES没有规范兼容的导入方式,比如将函数或类作为模块导入。为了解决这些不兼容性问题,Babel允许你以默认方式导入CJS模块,或者以命名空间方式导入。TypeScript以前不支持这样做,但是最近在esModuleInterop下添加了这个选项。因此,现在Babel和TypeScript都可以相当一致地允许使用默认或命名空间ES导入来导入CJS模块。

对于TypeScript来说,还取决于库的类型定义是如何定义的。我不会详细介绍,但你可以想象在某些情况下,由于转译器和打包工具的原因,特定的导入在运行时可以正常工作,但TypeScript在编译时会出现错误。

另一个值得一提的事情是,如果你查看React的构建代码,还有一个UMD模块版本以及CJS版本。UMD版本包含一些复杂的运行时代码,以使其在任何模块环境中(包括浏览器)正常工作。它主要用于在运行时仅包含React(即不使用打包工具)的情况下使用。示例

令人困惑吗?是的,我也这么认为。:)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!