React
次のようにインポートできることに気付きました:
import * as React from 'react';
...または次のようにします:
import React from 'react';
最初のものはreact
モジュール内のすべてをインポートします(参照:モジュール全体のコンテンツをインポートする)
2番目はdefault
モジュールエクスポートのみをインポートします(参照:デフォルトのインポート)
どうやらこの 2 つのアプローチは異なり、根本的に互換性がないようです。
なぜ両方とも機能するのでしょうか?
ソースコードを参照してメカニズムを説明してください...これがどのように機能するかを理解することに興味があります。
アップデート
これはないの複製import * as react from 'react' と import react from 'react' の違いは何ですか?
その質問には、一般的な ES6 モジュール情報で回答しました。
モジュールをこのように動作させるメカニズムについて質問していますreact
。これは「ハッキーな」エクスポートメカニズムに関連しているようです。ここのソースでしかし、それがどのようにして全体モジュールとデフォルトにエクスポートReact
し、両方のアプローチを JSX のトランスパイルなどで機能させます。
ベストアンサー1
要約
確かにESのインポート文import default
とはimport *
同じものではありませんが、この場合、それらが同じように動作するという事実は、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の間には解決しなければならない違いがあります。その1つは、export =
できるES では仕様に準拠した方法でインポートできない関数やクラスをモジュールとして提供できます。これらの非互換性を回避するために、Babel ではしばらくの間、CJS モジュールをデフォルトでエクスポートしているかのようにインポートできるようにしてきました。または名前空間としてインポートします。TypeScript はしばらくの間これを行っていませんでしたが、最近になって のオプションとして追加されましたesModuleInterop
。そのため、Babel と TypeScript の両方で、デフォルトまたは名前空間の ES インポートを使用して CJS モジュールをインポートすることがほぼ一貫して可能になりました。
TypeScriptでは、ライブラリの型定義が実際にどのように定義されているかにも依存します。これについては触れませんが、トランスパイラとバンドラのおかげで、特定のインポートが実行時に動作するただし、TypeScript はエラーなしでコンパイルされません。
もう一つ言及する価値のあることは、Reactのビルドコードを見ると、UMDモジュールバージョンと CJS バージョンがあります。UMD バージョンには、ブラウザーを含むあらゆるモジュール環境で動作するようにするための厄介なランタイム コードが含まれています。これは主に、実行時に React のみを組み込む場合 (つまり、バンドラーを使用しない場合) に使用します。例。
混乱しますか?ええ、そうだと思います。:)