1. ホーム
  2. javascript

[解決済み] インポート * as React from 'react'; vs インポート React from 'react';

2023-06-01 15:42:07

質問

私は、以下のことに気づきました。 React はこのようにインポートすることができます。

import * as React from 'react';

...あるいはこんな感じ。

import React from 'react';


1つ目は react モジュールにインポートします (参照。 モジュールの内容全体をインポートする )

2つ目は default モジュールのエクスポート(参照。 デフォルトのインポート )


この2つのアプローチは異なっており、根本的に相容れないもののように思えます。

なぜ両方ともうまくいくのでしょうか?


ソースコードを参照し、仕組みを説明してください...この仕組みを理解することに興味があります。


更新

これは ではなく の複製です。 import * as react from 'react' と import react from 'react'の違いは何ですか?

その質問には、一般的なES6モジュールの情報で答えました。

私が質問しているのは react モジュールがこのように動作するメカニズムについて質問しています。 エクスポートの仕組みが関係しているようです。 のソースはこちらです。 をインポートすることができるのですが、それがどのように 全体 モジュールと デフォルトの にエクスポートします。 React へのエクスポートと、これらのアプローチの両方がJSXのトランスパイルなどで動作するようにします。

どのように解決するのか?

TL;DR

確かにESのimport文 import defaultimport * は同じものではありません。この場合、同じ動作をするということは、Reactの作者がライブラリと互換性レイヤーをTypeScriptで公開する方法を選択したこと(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ライブラリであるかのようにReactをインポートすることを可能にします(using import 構文ではなく require() など)でも、CJSとESの間には解決しなければならない違いがあります。そのひとつは export = ができる は、ES がモジュールとして関数やクラスのようなインポートするための仕様に準拠した方法を持たないものを提供します。これらの非互換性を回避するために、Babel はしばらくの間、CJS モジュールがデフォルトで何かをエクスポートしているかのようにインポートすることを許可しています。 または を名前空間としてインポートすることができます。TypeScriptはしばらくの間これを行わなかったが、最近、オプションとして esModuleInterop . そのため、BabelとTypeScriptの両方が、CJSモジュールがデフォルトまたは名前空間ESインポートを使用してインポートされることを、かなり一貫して許可することができるようになりました。

TypeScriptでは、ライブラリの型定義が実際にどのように定義されているかに依存します。これについては触れませんが、トランスパイラーやバンドラーのおかげで、特定のインポート が実行時に動作する しかし、TypeScriptはエラーなくコンパイルできない。

もう一つ特筆すべきは、Reactのビルドコードを見ると UMDモジュール バージョンと CJS バージョンがあります。UMD版には、ブラウザを含むあらゆるモジュール環境で動作するようにするための、いくつかの厄介なランタイムコードが含まれています。主に、実行時に React をインクルードしたい場合 (つまり、バンドラーを使用しない場合) に使用します。 .

紛らわしい?ええ、そうですね :)