" Similitudes et différences entre import * as React from 'react' ; et import React from 'react' ;"
P粉596161915
2023-08-22 19:59:28
<p>J'ai remarqué que <code>React</code> peut être importé comme ceci : </p>
<pre class="brush:js;toolbar:false;">importer * en tant que React depuis 'react';
≪/pré>
<p>...ou importez comme ceci : </p>
<pre class="brush:js;toolbar:false;">importer React depuis 'react';
≪/pré>
<heure />
<p>La première méthode importe tout le contenu du module <code>react</code> (voir : Importer le contenu de l'ensemble du module)</p>
<p>La deuxième méthode importe uniquement l'export du module <code>default</code> (voir : Importer l'export par défaut)</p>
<heure />
<p>Les deux approches semblent différentes et fondamentalement incompatibles. </p>
<p>Pourquoi fonctionnent-ils tous ? </p>
<heure />
<p>Veuillez vous référer au code source et expliquer le mécanisme... Je souhaite comprendre comment cela fonctionne. </p>
<heure />
<p><strong>Mise à jour</strong></p>
<p>Ce n'est pas une question en double, elle est différente de "la différence entre importer * comme réaction de 'réagir' et importer réagir de 'réagir'"</p>
<p>Cette question reçoit une réponse avec des informations générales sur le module ES6. </p>
<p>Je pose des questions sur le mécanisme qui permet au module <code>react</code> Cela semble avoir quelque chose à voir avec un mécanisme d'exportation "hacky" dans le code source, mais il n'est pas clair comment cela permet aux deux façons d'importer le module entier et d'importer simplement les exportations par défaut vers <code>React</code> avec JSX transpilé etc. </p>
Le vôtre
tsconfig.json
文件中很可能设置了"allowSyntheticDefaultImports": true,
,这实际上让编译器对它认为无效的默认导入保持静默。Typescript 添加了esModuleInterop
, ce qui est fondamentalement la même chose que Babel fait en termes de chargement de module.Cela vous permet d'utiliser les importations par défaut ES6 lorsque le code source importé n'a pas d'exportation par défaut.
Typescript est strict (suit les règles) à cet égard, c'est pourquoi il vous oblige à utiliser
import * as React from 'react'
. Ou vous demander de l'indiquer dans la configuration de base pour autoriser les importations synthétiques par défaut.Plus d'informations connexes
TL;DR
En fait, la déclaration d'importation d'ES
import default
和import *
并不是同一回事,它们在这种情况下表现相同是因为React作者选择以这种方式发布库并在TypeScript(使用esModuleInterop
) ou Babel et la couche de compatibilité utilisée dans les outils d'emballage font que cela "fonctionne simplement". Selon la spécification ES6, cela ne devrait probablement pas fonctionner correctement, mais aujourd'hui, nous sommes toujours à l'ère du chaos des modules JS, donc des outils comme Babel, TypeScript, Webpack, etc. tentent tous de standardiser le comportement.Plus de détails :
React n'est pas une bibliothèque ES6. Si vous regardez le code source , vous verrez ceci dans
index.js
:(Notez que même dans le code source de React, ils travaillent sur des problèmes de compatibilité avec les exportations par défaut de ES6.)
module.exports =
La syntaxe est celle de CommonJS (NodeJS). Le navigateur ne peut pas comprendre cette syntaxe. C'est pourquoi nous utilisons des outils de packaging comme Webpack, Rollup ou Parcel. Ils comprennent diverses syntaxes de modules et génèrent des fichiers groupés qui devraient fonctionner dans le navigateur.Cependant, même si React n'est pas une bibliothèque ES, TypeScript et Babel vous permettent de l'importer comme une bibliothèque ES (cette option a été ajoutée sous Utiliser
.import
语法,而不是require()
等),但是CJS和ES之间存在一些需要解决的差异。其中之一是export =
可以为你提供ES没有规范兼容的导入方式,比如将函数或类作为模块导入。为了解决这些不兼容性问题,Babel允许你以默认方式导入CJS模块,或者以命名空间方式导入。TypeScript以前不支持这样做,但是最近在esModuleInterop
Alors maintenant, Babel et TypeScript autorisent assez systématiquement l'utilisation d'espaces par défaut ou d'espaces de noms). Import ES pour importer des modules CJSPour TypeScript, cela dépend également de la façon dont la définition de type de la bibliothèque est définie. Je n'entrerai pas dans les détails, mais vous pouvez imaginer qu'il existe des cas où une importation spécifique fonctionnera correctement au moment de l'exécution grâce au transpileur et aux outils d'empaquetage, mais TypeScript générera des erreurs au moment de la compilation.
Une autre chose à mentionner est que si vous regardez le code de build de React, il existe également une version module UMD ainsi qu'une version CJS. La version UMD contient du code d'exécution complexe pour le faire fonctionner correctement dans n'importe quel environnement de module, y compris les navigateurs. Il est principalement destiné à être utilisé lorsque seul React est inclus dans le runtime (c'est-à-dire qu'aucun outil de packaging n'est utilisé). Exemple.
Déroutant ? Oui je pense aussi. :)