React
は次のようにインポートできることに気付きました。
import * as React from 'react';
...または次のようにインポートします:
React を 'react' からインポートします。
最初のメソッドは、react
モジュールのすべてのコンテンツをインポートします (参照: モジュール全体のコンテンツのインポート)
2 番目の方法では、default
モジュール エクスポートのみをインポートします (参照: デフォルト エクスポートのインポート)
この 2 つのアプローチは異なっており、根本的に互換性がないように見えます。
なぜそれらはすべて機能するのでしょうか?
ソースコードを参照してメカニズムを説明してください...これがどのように機能するかを理解することに興味があります。
アップデート
これは重複した質問ではありません。「import * as React from 'react' と import accept from 'react' の違い」とは異なります
その質問は、一般的な ES6 モジュール情報で答えられます。
react
モジュールがこのように動作することを可能にするメカニズムについて質問しています。これはソース コード内の「ハックな」エクスポート メカニズムと関係があるようですが、モジュール全体をインポートする方法とデフォルトのエクスポートを React
にインポートする両方の方法がどのように機能するのかは不明です。トランスパイルされたJSXなどを使用して
おそらく
tsconfig.json
ファイルに"allowSyntheticDefaultImports": true,
が設定されており、実際にはコンパイラが無効とみなしたデフォルトのインポートをサイレントにします。 Typescript はesModuleInterop
を追加します。これはモジュールの読み込みに関して babel が行うことと基本的に同じです。これにより、インポートされたソース コードにデフォルトのエクスポートがない場合に、ES6 のデフォルトのインポートを使用できるようになります。
Typescript はこの点に関して厳密 (ルールに従って) であるため、
import * as React from 'react'
を使用する必要があります。または、基本構成で合成デフォルトのインポートを許可するように指示する必要があります。その他の関連情報
TL;DR
実際には、ES インポート ステートメント
import default
とimport **
は同じものではありませんが、この場合、React 作成者がこの方法を選択したため、これらは同じように動作します。ライブラリを公開し、TypeScript の互換性レイヤー (esModuleInterop
を使用) または Babel とパッケージ化ツールを使用して「正常に機能する」ようにします。 ES6 の仕様によれば、おそらく適切に動作しないはずですが、現在でも JS モジュールが混沌とした時代にあるため、Babel、TypeScript、Webpack などのツールはすべて動作を標準化しようとしています。詳細:
React は ES6 ライブラリではありません。ソース コードを見ると、
リーリーindex.js
に次のことがわかります:(コメントに注意してください。React ソース コードでも、ES6 のデフォルト エクスポートとの互換性の問題に取り組んでいます。)
module.exports =
構文は CommonJS (NodeJS) の構文です。ブラウザはこの構文を理解できません。そのため、Webpack、Rollup、Parcel などのパッケージ化ツールを使用します。これらはさまざまなモジュール構文を理解し、ブラウザで動作するバンドル ファイルを生成します。ただし、React は ES ライブラリではありませんが、TypeScript と Babel の両方で ES ライブラリのようにインポートできます (
require()
ではなくimport
構文を使用し、など)、ただし、CJS と ES の間には、対処する必要があるいくつかの違いがあります。その 1 つは、export =
が、関数やクラスをモジュールとしてインポートするなど、ES 仕様に準拠していないインポート メソッドを提供する可能性があることです。これらの非互換性を解決するために、Babel ではデフォルトまたは名前空間ごとに CJS モジュールをインポートできます。 TypeScript は以前はこれをサポートしていませんでしたが、このオプションは最近esModuleInterop
に追加されました。そのため、Babel と TypeScript の両方で、デフォルトまたは名前空間 ES インポートを使用して CJS モジュールをインポートできるようになりました。TypeScript の場合、ライブラリの型定義の定義方法にも依存します。詳細については説明しませんが、トランスパイラーとパッケージ化ツールのおかげで、特定のインポートが実行時には正常に機能しても、TypeScript がコンパイル時にエラーをスローする場合があることは想像できます。
もう 1 つ言及する価値があるのは、React のビルド コードを見ると、CJS バージョンだけでなくUMD モジュールバージョンも存在するということです。 UMD バージョンには、ブラウザを含むあらゆるモジュール環境で適切に動作するための複雑なランタイム コードが含まれています。これは主に、React のみがランタイムに含まれている場合 (つまり、パッケージ化ツールが使用されていない場合) に使用することを目的としています。 ###例###。わかりにくいですか?はい、私もそう思います。 :)