web-dev-qa-db-ja.com

TypeScript出力を有効なES6モジュールインポートステートメントにする方法は?

すべての主要なブラウザ しばらくの間ES6モジュールをサポートしてきました。

これらは、インポート元の正確なファイルを指定する必要があるという点で、サーバー側のアプローチの多くとは異なります。ファイル検出を使用することはできません。

これは理にかなっています-Node WebPackのようなアプリケーションやバンドラーでは、実際にはモジュールの名前だけが必要であり、コードを保持する特定のファイルを見つけるのに少し余分な時間を費やすことができます。多くの無駄な往復になる可能性のあるWeb(_'library'_の_library/index.js_、または_library/library.js_、または_library.js_?require()は気にしませんがウェブ上では)。

TypeScriptはES6モジュールをサポートしています(_"module": "es6"_を_tsconfig.json_に設定)が、ファイル検出アプローチを使用しているようです...

私が_library.ts_を持っているとしましょう:

_export function myFunction(...) {  ... }
_

次に、_app.ts_で:

_import {myFunction} from './library';
var x = myFunction(...);
_

ただし、これはトランスパイルの場合は変更されません。TS出力にはファイル検出用の_'library'_名が残っているため、機能しません。 _'library'_が見つからないため、これはエラーをスローします。

_<script type="module" src="app.js"></script>
_

ES6モジュールが機能するためには、TS出力が特定のファイルを参照する必要があります。

_import {myFunction} from './library.js';
var x = myFunction(...);
_

TS出力を有効なES6モジュールimportステートメントにするにはどうすればよいですか?

注:私はではなく、バンドラーにTS出力を単一のファイルに結合させる方法を尋ねています。特に_<script type="module">_を使用してこれらのファイルを個別にロードしたい

12
Keith

これは TypeScriptのバグ ですが、修正する必要があるかどうかについては議論があります。

回避策があります。TSではモジュールのソースとして.tsファイルを指定することはできませんが、.js拡張子を指定することはできます(その後無視します)。

したがって、app.tsでは:

import {myFunction} from './library.js';
var x = myFunction(...);

これにより、app.jsに正しく出力され、TSはimportの定義とバインディングを正しく検出しました。

これには、注意/注意すべき1つの利点/落とし穴があります。TSは.js拡張子を無視し、パスの残りの部分を通常のファイル検出でロードします。これは、library.tsをインポートすることを意味しますが、library.d.tsのような定義ファイルを検索したり、library/フォルダーにファイルをインポートしたりすることもあります。

これらのファイルをlibrary.js出力に結合する場合は、最後のケースが望ましいかもしれませんが、そのためには、ネストされたtsconfig.jsonファイル(乱雑)がたくさんあるか、場合によっては別のライブラリの事前に変換された出力。

4
Keith

コンパイラはモジュールの種類フラグを取ります。

--module ES2015

また、ECMAScript6/2015をターゲットにする必要があります...

--target ES2015

「変換のインポートがゼロ」になるには、モジュールの種類とコンパイルターゲットの両方がECMAScript2015の最小値である必要があります。

Importステートメントは、2つの例の中間にあるはずです。

import {myFunction} from './library';

その他の注意事項

モジュールの解決についてはまだ明らかに多くの議論があります... TC39仕様WHATWG仕様 -plus Node現在もファイル拡張子がありません... RequireJSは私たちが思っていたよりも長持ちする可能性があります...参照してください:

インポート変換中にファイル拡張子をサポートするためのTypeScriptスレッド (つまり、ファイル拡張子を追加しますか?).

勧告

RequireJSやSystemJSなどのモジュールローダーを使用します。これは、UMDまたはシステムモジュールの種類をそれぞれ使用することで、モジュールをブラウザとサーバー間で共有できることも意味します。

明らかに、ECMAScriptの議論が結論に達したら、これを再検討する必要があります。

2
Fenton