web-dev-qa-db-ja.com

commonjs / AMDモジュールをインポートするための新しいes6構文、つまり `import foo = require( 'foo')`

以前は私ができました:

import foo = require('foo');

しかし、TypeScript(1.5)はes6モジュール構文をサポートするようになりました。ES6モジュール構文で同じことを実現する正しい方法は何ですか。

50
basarat

正しい方法は、古いインポート構文を引き続き使用することです。新しいインポート構文はESモジュール専用で、古いインポート構文はES6以前のモジュール用です。この2つは明確に区別されています。 import * as foo from 'foo'モジュール 'foo'のすべてのpropertiesをインポートします。それはデフォルトをインポートしませんfooとしての値。

機能の設計者から

  • エクスポートのデフォルト宣言は、常にdefaultという名前のエクスポートされたメンバーを宣言し、常にexports.defaultへの割り当てとして発行されます。言い換えれば、export defaultには一貫してESモジュールのセマンティクスがあります。 Babelとの互換性のために、モジュールにデフォルトのエクスポートがある場合、オプションで__esModuleマーカーを発行できますが、実際にはそのマーカーを何にも使用しません。
  • モジュール自体の代わりにエクスポートされる別のエンティティを置換するexport =宣言は、常にmodule.exportsへの割り当てとして発行されます。 export =を使用するモジュールに他のエクスポートがあるとエラーになります。これは既存のTypeScriptの動作です。
  • export =を使用して別のモジュール(内部または外部モジュール)をエクスポートするモジュールは、新しいES6コンストラクトを使用してインポートできます。特に、このようなモジュールでは便利な非構造化インポートを使用できます。 export =を使用して別のモジュールをエクスポートするパターンは、内部モジュール(例:angle.d.ts)のCommonJS/AMDビューを提供する.d.tsファイルで一般的です。
  • モジュール自体の代わりにexport =を使用して非モジュールエンティティをエクスポートするモジュールは、現在のように既存のimport x = require("foo")構文を使用してインポートする必要があります。

2016 update:ある時点でTypeScriptコンパイラは、import * as foo from 'legacy-module-foo'が特定の状況でレガシーモジュールのデフォルトインポートを取得できるようになりました。 これはES6仕様の違反です§15.2.1.16“ The value " * "は、インポート要求がターゲットモジュールの ネームスペースオブジェクト 。”)に対するものであることを示します。

この方法でインポートしたレガシーモジュールがES6モジュールに更新されると、それらのモジュールの「デフォルト」インポートは機能しなくなります(* as fooインポートはsupposedであるため) namespace objects)。これを行うことがTypeScript/SystemJSのハックであることを知らない場合、非常に混乱する可能性があります。また、将来のTypeScriptのES仕様への再調整により、それらが破損する可能性もあります。

そのため、おそらく上記のレガシーインポート構文を引き続き使用してレガシーモジュールをロードし、ES6名前空間のインポートのしくみについてコードで作業している開発者や他の開発者を混乱させないようにしてください。

85
C Snover

ES6モジュールの構文に対応する構文は次のとおりです。

import * as foo from 'foo';

基本的に、fooモジュールからfooという名前のローカル変数にすべてをインポートします。

10
basarat

ES6モジュールは、効果的に新しい構文を持つTypeScript外部モジュールです。ES6モジュールは、他のモジュールをインポートし、外部からアクセス可能な多数のエクスポートを提供する可能性のある、個別にロードされるソースファイルです。 ES6モジュールには、いくつかの新しいエクスポートおよびインポート宣言があります。 TypeScriptライブラリとアプリケーションを更新して新しい構文を使用することをお勧めしますが、これは必須ではありません。

ソース

私が理解している限り、それはあなたがあなた自身のTypeScriptモジュールを新しい構文に移行することが奨励されることを意味しますが、実際のAMD/CommonJSモジュールをインポートするためにimport foo = require('foo')を使い続けます。

3
cubuspl42

TypeScript 2.7 の時点で、CommonJS/AMD/UMDでデフォルトのインポートを有効にするために使用できる新しいesModuleInteropフラグがあります。 tsconfig.jsonでそのフラグをtrueに設定すると、これは期待どおりに機能するはずです。

import foo from 'foo';
2
Danny Guo

別のオプションは、commonjs構文を使用してインポートすることです。

const foo = require("foo");

TypeScriptとBableは両方とも、これをどうするかについて同意します。また、とにかくES5以下にコンパイルしている場合、これは最終的なフォームからそれほど遠くありません。

1
johnnyodonnell

すべてをインポートするには、

const foo = require("foo");

これにより、ファイル「foo」からすべてのインスタンスがインポートされます

const foo = require("./foo");

foo.InstanceNameを呼び出して各インスタンスにアクセスできます

特定のインスタンスをインポートする場合、

import MyInstance from "foo";

したがって、これは「foo」から特定のインスタンス(Myinstance)をインポートしますが、上記の方法を使用してすべてをインポートできます。

import * as ReferenceName from "foo";

と同等、

const ReferenceName = require("foo");