从'react'导入*作为React; vs从'react'导入React; [英] import * as React from 'react'; vs import React from 'react';

查看:132
本文介绍了从'react'导入*作为React; vs从'react'导入React;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到React可以这样导入:

I've noticed that React can be imported like this:

import * as React from 'react';

...或者像这样:

import React from 'react';


首先导入react模块中的所有内容(请参阅:


The first imports everything in the react module (see: Import an entire module's contents)

第二个仅导入default模块导出(请参阅:导入默认值)

The second imports only the default module export (see: Importing defaults)

这两种方法似乎是不同的,并且根本上是不兼容的.

It seems like the two approaches are different and fundamentally incompatible.

为什么它们都起作用?

请参考源代码并解释该机制...我有兴趣了解其工作原理.

Please reference the source code and explain the mechanism...I'm interested in understanding how this works.

更新

这不是不是

使用一般的ES6模块信息回答了该问题.

That question was answered with general ES6 module information.

我在问使react模块像这样工作的机制.它似乎与"hacky"导出机制有关在此处的源代码中,但尚不清楚如何将 entire 模块导入并且仅将 default 导出到React转译JSX等.

I am asking about the mechanism that makes the react module work like this. It seems to be related to "hacky" export mechanism in the source here but it's not clear how that enables both importing the entire module and just the default export into React and having both of those approaches work with transpiling JSX, etc.

推荐答案

TL; DR

独立的ES导入语句import defaultimport *是不同的,在这种情况下它们的行为相同是React作者选择使用TypeScript发布库和兼容性层的组合(使用esModuleInterop)或Babel和您的捆绑器使它们正常工作".它可能不应该根据ES6规范工作,但是今天我们仍然在一个JS模块混乱的时代工作,因此Babel,TypeScript,Webpack等工具试图规范行为.

TL;DR

Indeed ES import statements import default and import * are not the same thing, the fact that they behave the same in this case is a combination of how React authors chose to publish the library and compatibility layers in TypeScript (using esModuleInterop) or Babel and your bundler to make them "just work". It probably shouldn't work according to ES6 spec, but today we are still working in an era where JS modules are a mess, so tools like Babel, TypeScript, Webpack, etc try to normalize behavior.

React不是ES6库.如果您查看源代码,您会在index.js:

React is not an ES6 library. If you look at the source code you see this in 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默认导出兼容性兼容.)

(Note the comment, even in React source code they struggle with ES6 default export compatibility.)

module.exports =语法为CommonJS(NodeJS).浏览器不会理解这一点.这就是为什么我们使用诸如Webpack,Rollup或Parcel之类的捆绑器的原因.他们了解各种模块语法,并生成应在浏览器中使用的捆绑软件.

The module.exports = syntax is CommonJS (NodeJS). A browser would not understand this. This is why we use bundlers like Webpack, Rollup, or Parcel. They understand all kinds of module syntax and produce bundles that should work in the browser.

但是,尽管React不是ES库,但是TypeScript和Babel都允许您将其导入(就像使用import语法,而不是require()等),但是CJS和ES之间存在差异必须解决.其中一个事实是,export = 可以可以为您提供ES没有符合规范的导入方式,例如函数或类作为模块.为了解决这些不兼容问题,Babel允许您暂时导入CJS模块,就像默认情况下它们正在导出某些内容一样, import作为命名空间. TypeScript暂时没有执行此操作,但最近在esModuleInterop下将其添加为一个选项.因此,现在Babel和TypeScript都可以非常一致地允许使用默认或名称空间ES导入来导入CJS模块.

But even though React is not an ES library, both TypeScript and Babel let you import it as if it is (using import syntax, rather than require(), etc), but there are differences between CJS and ES that have to be resolved. One of them is the fact that export = can give you things that ES has no spec-compliant way to import, like a function or a class as the module. To work around these incompatibilities Babel has for awhile allowed you to import CJS modules as if they were exporting something by default, or import as a namespace. TypeScript for awhile didn't do this, but more recently added that as an option under esModuleInterop. So now both Babel and TypeScript can pretty consistently allow a CJS module to be imported using default or namespace ES imports.

使用TypeScript,它还取决于实际定义库的类型定义的方式.我不会对此进行介绍,但是您可以想象这样的情况:由于使用了编译器和捆绑器,特定的导入在运行时有效,但是TypeScript不会在没有错误的情况下进行编译.

With TypeScript it also depends on how the type-definitions for the library are actually defined. I won't get into that, but you can imagine situations where thanks to transpilers and bundlers a particular import works at runtime, but TypeScript doesn't compile without errors.

值得一提的另一件事是,如果您查看React的内置代码,则会有一个 UMD模块版本以及CJS版本. UMD版本包含一些粗糙的运行时代码,以尝试使其在任何模块环境(包括浏览器)中都能正常工作.如果您只想在运行时包括React(即不使用捆绑程序),则主要用于此. 示例

Another thing worth mentioning is that if you look at the built code for React there is a UMD module version as well as the CJS version. The UMD version includes some gnarly runtime code to try to make it work in any module environment, including the browser. It's mainly for use if you want to just include React at runtime (ie you don't use a bundler). Example.

令人困惑?是的,我是这样认为的. :)

Confusing? Yeah, I think so. :)

这篇关于从'react'导入*作为React; vs从'react'导入React;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆