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.
En fait, la déclaration d'importation d'ES import default
和import *
并不是同一回事,它們在這種情況下表現(xiàn)相同是因為React作者選擇以這種方式發(fā)布庫并在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.
React n'est pas une bibliothèque ES6. Si vous regardez le code source , vous verrez ceci dans 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;
(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沒有規(guī)范兼容的導入方式,比如將函數(shù)或類作為模塊導入。為了解決這些不兼容性問題,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 CJS
Pour 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 grace 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. :)