Typescript: モジュール指定子の最後に「.js」ファイル拡張子を追加する方法を提供します

作成日 2017年06月16日  ·  273コメント  ·  ソース: microsoft/TypeScript

ブラウザでes6モジュールを使用するには、.jsファイル拡張子が必要です。 ただし、出力はそれを追加しません。

tsで:
import { ModalBackground } from './ModalBackground';
ES2015の出力:
import { ModalBackground } from './ModalBackground';

理想的にはこれを出力したい
import { ModalBackground } from './ModalBackground.js';

そうすれば、Chrome51の出力を使用できます

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Webpack boilerplate</title>
  <script type="module" src="index.js"></script>
</head>
<body></body>
</html>

image

https://github.com/Microsoft/TypeScript/issues/13422に関連

ES Modules Needs Proposal Suggestion

最も参考になるコメント

また、この問題を少し一般化するために、実際には.js拡張子を追加することではなく、拡張子が何であれ、モジュール指定子を実際のパスに解決することだと思います。

全てのコメント273件

#13422に関連しているだけでなく、同じ問題です。 しかし、それは重要な問題だと思うにもかかわらず、反応はかなり否定的でした。あなたの問題がよりよく受け取られることを願っています。

これが追加されることを願っています。次のTypeScriptポッドキャストでこれを使用してPOCについて話し合うのを本当に楽しみにしていましたが、ビルドツールなしでTypeScriptを使用するのを待つ必要があるようです。

現時点では、TypeScriptはパスを書き換えません。 確かに面倒ですが、現在、 .js拡張機能を自分で追加できます。

@justinfagnani @rictic

ヒントをありがとう、これを行うためのシェル/ノードスクリプトを作成します。

@DanielRosenwasserは、ネイティブES6モジュールの問題をラベルの下に収集することは理にかなっていますか?

また、この問題を少し一般化するために、実際には.js拡張子を追加することではなく、拡張子が何であれ、モジュール指定子を実際のパスに解決することだと思います。

私は実際にはtypescriptのドメインではない別の問題に遭遇しましたが、それは私のユースケースのためです。

node_modulesの処理方法がわかりません。 通常、webpackはts-loaderを介してそれらをコードにバンドルしますが、明らかに、これはブラウザーによって理解されません。

import { KeyCodes } from 'vanilla-typescript;
https://github.com/quantumjs/vanilla-typescript/blob/master/events/KeyCodes.ts#L3

ここにjs拡張機能を追加しても意味がありません。

サーバー上で実行されているtypescriptまたはURLリゾルバーによるパス拡張が必要になると思います。

かなりニッチなケースだと思いますが、TSがこの分野の早い段階で輝ける方法になると思います。 多分それはtscコンパイラへのプラグインかもしれませんか?

これに来て、暫定的な解決策が必要な人のために、私はステートメントをインポートするためにjsファイル拡張子を追加するスクリプトを書きました:

"use strict";

const FileHound = require('filehound');
const fs = require('fs');
const path = require('path');

const files = FileHound.create()
  .paths(__dirname + '/browserLoading')
  .discard('node_modules')
  .ext('js')
  .find();


files.then((filePaths) => {

  filePaths.forEach((filepath) => {
    fs.readFile(filepath, 'utf8', (err, data) => {


      if (!data.match(/import .* from/g)) {
        return
      }
      let newData = data.replace(/(import .* from\s+['"])(.*)(?=['"])/g, '$1$2.js')
      if (err) throw err;

      console.log(`writing to ${filepath}`)
      fs.writeFile(filepath, newData, function (err) {
        if (err) {
          throw err;
        }
        console.log('complete');
      });
    })

  })
});

これをCLIツールにするかもしれません。

@justinfagnaniのコメントは頭に釘を打ちます。

また、この問題を少し一般化するために、実際には.js拡張子を追加することではなく、拡張子が何であれ、モジュール指定子を実際のパスに解決することだと思います。

あなたが書くとき

import { KeyCodes } from 'vanilla-typescript';

またはそのことについて

import { KeyCodes } from 'vanilla-javascript';

モジュール指定子からインポートする場合、ファイルである場合とそうでない場合がありますが、この場合、末尾に.jsを追加しても、有効な解決策が得られない可能性があります。

NodeJSアプリケーションを作成している場合、NodeJS Requireアルゴリズムはさまざまな解決を試みますが、抽象名を参照し、慣例および構成によって解決されるため、 'vanilla-typescript.js'に解決しようとはしない可能性があります(おそらくさまざまな試みで) '../../../node_modules/vanilla_typescript/index.js'のようなものに。

AMDなどの他の環境では、この解決の実行方法に違いがありますが、これらの環境すべてに共通していることの1つは、抽象化されたモジュール指定子の概念です。

さまざまなブラウザに出荷されているESモジュールの実装が不完全なものを実装しているため、これを取り上げます。 最も単純な依存関係でさえも考慮すると、推移的な依存関係の主題を打ち破るとすぐに、やっかいなものを構成する方法が必要になることが明らかになります。

それは遠いかもしれませんが、あなたが発見しているように、私たちが与えられたこの(丁寧に)概念実証の実装に書き込むことは現実的ではありません。

さらに、問題は環境固有であるため、TypeScriptがここでどのように役立つかわかりません。

@QuantumInformationパスに.jsを追加するためのプログラムは、見栄えがよく、軽量で、エレガントですが、最終的には独自のモジュールバンドラーを実装しています。 これは面白くて興味深い作業ですが、ブラウザーで使用可能な現在の実装の欠陥を示しています。 純粋なJavaScriptで記述した場合でも、推移的にインポートされた依存関係をコンパイルおよびパッケージ化するための何かが必要です。

私は基本的に、リリースされたESモジュールの実装が十分とはほど遠いという事実についてただ怒鳴っています。

ここでも、NodeJS、RequireJS AMD、Dojo AMD、Sea Package Manager、CommonJS、Browserify、Webpack、SystemJSにはそれぞれ独自の方法がありますが、それらはすべて抽象的な名前解決を提供します。 それは_基本的_であるため、彼らはそれを提供しなければなりません。

私の暴言を読んでくれてありがとう。

TSのどのバージョンがそれを追加したかはわかりませんが、 ' ./file.js'などのインポートが機能するようになりました(ファイルが実際にfile.tsであっても)。
TypeScriptはファイルを正常に解決し、完全な.jsインポートをターゲットに出力します。
lit-html使用する: https ://github.com/PolymerLabs/lit-html/blob/master/src/lib/repeat.ts#L15

TS2.0以降で可能です。 しかし、webpackのようなツールはそれをサポートしていないので、結局は役に立たない。

ソースでts-loaderを使用している場合は役に立ちません(最も一般的なユースケース)。
実際のjsファイルがそこに存在し、解決プロセスで見つけることができるため、ターゲット(通常は「dist」フォルダー)をバンドルすることは引き続き可能です。

ts-loaderで、ターゲットコードから.js拡張子を取り除き、ソースから直接バンドルできるようにするクイックトランスフォーメーションを実装できるかどうか疑問に思います。

気軽にそうしてください、それは素晴らしいことです。 数か月前に、ts-loaderなどのメインのwebpack tsローダーに問題を投稿しましたが、非常に評判が悪かったです...

参考までに、ロールアップtypescriptプラグインに問題はありません。これは、実行可能な証拠です。

ほとんどの依存関係が正しくロードされないため、ブラウザーローダーの実装とWGATWGローダーの仕様が少なくとも_some_構成をサポートするまで、これが何をするのかわかりません。

私の観点からは、任意の文字列リテラル指定子を参照するインポートでネイティブローダーを使用することが実用的であるまで、これは重要ではありません。これは、まだURLではない可能性があり、変換を経て、実際のURL。

それまでは、SystemJSやWebpackなどのツールに依存し続けます。

import / exportステートメントから「.js」を取り除く小さなトランスフォーマーを作成しました。
tsutilsタイプのガードを使用したので、 yarn add tsutils --dev 。 (プロジェクトにtslintがある場合、パッケージは通常とにかくインストールされるため、追加の依存関係があります)

https://gist.github.com/AviVahl/40e031bd72c7264890f349020d04130a

これを使用すると、 .jsで終わるファイルからのインポートを含むtsファイルをバンドルし( webpackts-loaderを使用)、ソースをesmモジュールにトランスパイルしてロードできます。ブラウザ( tscを使用)。

これが役立つユースケースの数はおそらく限られています。

編集:エクスポートでも機能するように要点を更新しました。 ナイーブで最適化されていませんが、機能します。

この問題に関する動きはありますか?

この拡張の問題は、TypeScriptの最初の部分に戻り、 tsconfig.jsonが必要な理由と、 moduleオプションがcompilerOptions設定に追加された理由に戻ります。

拡張子のextensionの問題は、requireが非常にうまく解決できるため、ES2015 +でのみ重要なので、対象のコードがES2015 +の場合はコンパイラーによって追加されます。

  1. .js .ts
  2. .jsx .tsx

こんにちは、私はこの遅い時間に来ていますが、助けたいと思います。 ここで問題が何であるかを理解するのに苦労しています。 OPの例から、次のようになります。

import { ModalBackground } from './ModalBackground';

'./ModalBackground'が何であるかわからないという問題ですか? それはフォルダか何か他のものである可能性がありますか?

プロジェクト全体でtscを実行し、ModalBackground.tsが存在することわかっている場合、拡張機能を追加しても安全であることがわかります。

この問題は、RxJSコミュニティが非常に関心を持っている問題でもあります。これに対するソリューションのタイムラインは何ですか? それも優先されますか? 役立つサードパーティの変換はありますか?

出力ターゲットがES2015の場合、これが問題になるかどうかはよくわかりません。 これは、ES2015ブラウザ機能のドメインに該当する可能性があります。 さらに、 @ justinfagnaniは、心配するプラットフォームの目標としてこれを推進することはできませんか? (多分別のスレッドにフォークする必要があります)。

さらに、 @ justinfagnaniは、心配するプラットフォームの目標としてこれを推進することはできませんか? (多分別のスレッドにフォークする必要があります)。

はい、もちろん多くの人がプラットフォームに何らかの形の裸の指定子をサポートさせたいと思っていますが、現在のところ、サポートされておらず、それらを追加する提案すらありません。 私たちはその全体、おそらく複数年のプロセスを経る必要があります。

最終的にベア指定子のサポートが得られたとしても、それがそのままのノードモジュール解決の形式になる可能性は非常に低いです。 したがって、tscがファイルを検索するために使用する解決アルゴリズムと、ブラウザー(および場合によってはノードのネイティブモジュールサポートであるafaik)が使用する解決アルゴリズムとの間に不一致が生じます。

tscが別のモジュールを見つけるために使用したパスを具体化して、ダウンストリームのツールと環境が相反する意見で指定子を解釈しないようにできれば素晴らしいと思います。

@justinfagnani彼らはすでに相反する意見で解釈されています。 TSは、生成するJSコードが指していないJSファイルを生成します。 ES6は、JavaScriptを実行するための公式に正しい方法に最も近いものです。したがって、TypesScriptによって生成されたES6コードが間違っている場合、これは単純で単純なバグです。 提案などを待つ必要はありません。TypeScriptのバグを修正するだけです。 しかし、今日、人々は、何かに誤りを見つけず、行動する前にそれを10層の提案に通すと、知的に行動していないと感じています。 休憩してください。

@aluanhaddad確かに多くのプロジェクトはメリットがありませんが、npmの依存関係を使用しない(または何らかの方法でnpmの依存関係を処理できる)プロジェクトもあるため、これらのプロジェクトはメリットがあります。

ES6にコンパイルされたTypeScriptライブラリにも非常に役立ちます。 現在、これらのライブラリはブラウザでネイティブに使用することはできませんが、TypeScriptが.js拡張機能を出力した場合は、機能します。

@justinfagnaniまだ標準化も実装もされていませんが、ブラウザでnpmパッケージを動作させる提案があります。

パッケージ名マップは、TypeScriptコンパイラまたは別のツールによって自動的に生成できます。

だから私はこれをもう一度見直しています、私のノードスクリプト以外にこれに対する良い回避策はありましたか?

私はこのソリューションを使用しています:
https://github.com/Microsoft/TypeScript/issues/16577#issuecomment -343610106

しかし、モジュールにファイル拡張子がなく、正しいMIMEタイプで提供されている場合は、解決するはずです。

これに関する動きはありますか?

多分https://github.com/Microsoft/TypeScript/pull/25073はこれを解決できますか?

@Kingwl他のファイル拡張子をサポートしますか? .mjs .es .esmなど。

そうではないかもしれませんが、これは別の機能です

これもどうですか? タイプスクリプトコンパイラは、ターゲット出力がJSファイルであることを_知っています_。 私はこれらのスレッドを15分間閲覧していますが、なぜ拡張機能が省略されているのかまだわかりません。

この問題への参照の数から、私はそれが正しい方向に進んでいると思います。 もうすぐ試してみます。

これもどうですか? タイプスクリプトコンパイラは、ターゲット出力がJSファイルであることを_知っています_。 私はこれらのスレッドを15分間閲覧していますが、なぜ拡張機能が省略されているのかまだわかりません。

人々が使用する一般的なユースケースがあり、拡張機能がないため、より柔軟なインフラストラクチャが可能になります。 Node requirehookとwebpackloaderはそのような2つのケースです。

これもどうですか? タイプスクリプトコンパイラは、ターゲット出力がJSファイルであることを_知っています_。 私はこれらのスレッドを15分間閲覧していますが、なぜ拡張機能が省略されているのかまだわかりません。

人々が使用する一般的なユースケースがあり、拡張機能がないため、より柔軟なインフラストラクチャが可能になります。 Node requirehookとwebpackloaderはそのような2つのケースです。

ブラウザモジュールはどれも気にしません。

タイプスクリプトチームを殺してオプトインフラグを追加し、.js拡張子を発行するだけでしょうか? 私たちはここで何をしているのかを_知っています_。さもないと、まだ返信や混乱した質問を集めているスレッド(開いているものと閉じているものの両方)が12個もありません。 TSの欠陥ではないことは理解していますが、TSがJSの問題を解決するためにここにある場合は、この問題をリストに追加してください。

免責事項:

はい、私はこれが「あなたはウェブパックをb0rked」という問題をここに投稿する多くの人々につながるかもしれないことを理解していますが、実際には、それらの人々にとっては厳しいおっぱいです。 オプトインする必要があります。

ところで、TypeScriptソースを掘り下げると、 importModuleSpecifierEndingが表示されます。これを(ab)使用して、エミッターに.jsの末尾を使用させることはできますか?

たぶん、tsconfigスキーマでこの提案をつぶしますか? https://github.com/domenic/package-name-maps

この時点で、TypeScriptがtsconfigで指定されたpathsを使用してインポートを自動的に書き換えることができれば幸いです。 ブラウザのサポートがなくても、おそらく私にとっての問題点のほとんどは解決するでしょう。

更新はありますか? この問題を解決するための試みはありますか? デフォルトでesモジュールをサポートするすべての主要なブラウザがあります。それらの標準では、拡張機能が存在する必要があります。 手動で追加できることは理解していますが、tscはそれを理解しますが、これは必須ではありません。なぜそれが機能しないのでしょうか。
泣き言を言って申し訳ありませんが、この問題は現在非常に古く、まだ何も行われていません...

これもどうですか? タイプスクリプトコンパイラは、ターゲット出力がJSファイルであることを_知っています_。 私はこれらのスレッドを15分間閲覧していますが、なぜ拡張機能が省略されているのかまだわかりません。

人々が使用する一般的なユースケースがあり、拡張機能がないため、より柔軟なインフラストラクチャが可能になります。 Node requirehookとwebpackloaderはそのような2つのケースです。

次に、Typescriptコンパイラが拡張機能を追加するかどうかのオプションを受け入れる可能性があります。 インクルードオプション(https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)のように、拡張機能を追加する(または追加しない)ために、一連の正規表現を受け入れることもできます。

ええ、それはすでに少なくとも一度は提案されています、それを考慮に入れてみませんか? TSには、ブラウザに実装されると将来変更される可能性のある実験的な機能がすでにいくつかありますが、TSには、これらの不安定な仕様のフラグがすでにあります。 module += '.js'を実行するだけの実験的なフラグaddImportsExtensionsを持っていないのはなぜですか、それだけです! ファンキーなロジックや追加機能はありません。 別のターゲットとして保持したい場合は、別のターゲットになる可能性があります。 それ以上に、上記のいずれかを受け入れた場合、私は個人的にtscコードを掘り下げて、そのためのPRを作成します。とにかく受け入れられない場合でも、時間を無駄にしたくありません。

カスタム変換を使用して、発行されたコードのインポートを書き換えることができます( '.js'を追加するか、モジュールインポートの解決されたパスを使用します)。

TypeScript変換の書き方
ttypescript:コンパイル中に変換を適用するtscのラッパー

たぶん、あなたが必要なことをする既存の変換がすでにあるでしょう。

私はそれが可能であることを知っています、私はコンパイラAPIをかなりいじりました(私が望むほどではありませんが)。 重要なのは、プロジェクトに追加のツールを追加し、追加のツールには追加のメンテナがあり、問題に十分な速さで対応する場合としない場合があります(多くの場合、彼らのせいではなく、私たち全員に命と仕事があります)。 小さなプロジェクトはしばしば放棄され、自分たちですべてを行うことは私たちに責任を移すだけなので、ビジネスコードを処理する代わりに、ツールに時間を費やします。
上記を考慮に入れると、多くのプロジェクトはそれをソリューションとは見なさず、代わりにロールアップなどの追加のビルドステップを追加します。これにより、追加の構成オーバーヘッドが追加され、追加のメンテナンスコストに戻ります。
要約すると、私は公式TSへのPRに時間を費やす方が好きです。そこでは、私とコミュニティの両方がそれから恩恵を受けるでしょう。 )、またはそれは世界中の誰もが使用できませんでした。

@ajafff​​それは解決策かもしれませんが、主な問題は次の問題だと思います。Typescriptトランスパイラーがブラウザーで間違ったソースコードを生成します。 変換を行うのは良いことですが、それは回避策だと思います。 トランスパイルの詳細に注意を払う必要があり、独自の変換を実装する必要があるのか​​、それともコンパイラーが管理する必要があるのか​​、疑問に思います。

変換は本当に強力なツールです。変換としてまったく新しいトランスパイラーを作成することもできますが、これは正しい方法ではないと思います。

ええ、それはすでに少なくとも一度は提案されています、それを考慮に入れてみませんか? TSにはすでに実験的な機能がほとんどありません

TypeScriptには、3年前に追加された実験フラグが1つだけあります。これは、現在の提案と互換性がなくなったECMAScript提案用でした。

Typescriptトランスパイラーがブラウザで間違ったソースコードを生成する

私はあなたの期待を理解していますが、コンパイラがあなたが書いたパスを書き直さないことを考えると、あなたがあなた自身のコードのインポートが「間違っている」と考えていないことに驚いています。 😉

申し訳ありませんが@ DanielRosenwasser 、npmというものを聞いたことがありますか? 人々はそこにパッケージを投稿するので、私たち全員がそれを使用できます。 あなたが私を非常に高く評価しているかもしれないことを理解していますが、残念ながら私はそれらの大多数の著者ではないので、拡張機能を追加して編集することはできません。
私のプロジェクトが私のコードのみを使用した場合、それは本当に私のコーディングの右腕であるため、typescriptがもたらすものに感謝します(WebStormは別として)。 しかし、私は私たちのほとんどが思うようにサードパーティのパッケージを使用しており、それらは必ずしも拡張機能を含んでいません。 rxjsのような一部のプロジェクトは、typescriptが拡張機能を追加する方法を提供することを期待して文字通り待機します。そうしないと、ビルドプロセス全体を変更する必要があるため、製品ではなくツールに余分な時間を費やすことに戻ります。
では、3つの質問に答えていただけませんか。

  1. typescriptチームはこの機能を出荷する用意がありますか?
  2. はいの場合、PRを受け入れますか?
  3. いいえの場合、これをいつリリースする予定ですか?

最初の質問の答えが「いいえ」の場合は、この問題を閉じて、この機能を出荷する意思がないことを公式に宣言してください。他の人に待たせないでください。

ええ、それはすでに少なくとも一度は提案されています、それを考慮に入れてみませんか? TSにはすでに実験的な機能がほとんどありません

TypeScriptには、3年前に追加された実験フラグが1つだけあります。これは、現在の提案と互換性がなくなったECMAScript提案用でした。

Typescriptトランスパイラーがブラウザで間違ったソースコードを生成する

私はあなたの期待を理解していますが、コンパイラがあなたが書いたパスを書き直さないことを考えると、あなたがあなた自身のコードのインポートが「間違っている」と考えていないことに驚いています。 😉

これは良い点です@ DanielRosenwasser 、Typescript仕様(https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#11.3)を正しく読んでいるように見えるので、私は自分のコードを正しく考えました。

ECMAScriptの仕様を読んだことは間違いありません。 仕様では、モジュールが拡張子で終了する必要があるかどうかは決定されていません。 仕様では、モジュールのインポートはHostResolveImportedModuleアルゴリズムを使用して解決されますが、定義があいまいです。 問題はECMAScriptの仕様ではありません。 問題は、仕様で定義されている[ModuleRequest]がリソースへのパスであるかのように、ブラウザーがモジュールを解決することです。

これを念頭に置いて、言語のホームページにアクセスしてください: https ://www.typescriptlang.org/。

ページのフッターでは、次の行を読むことができます。

JavaScriptで開始および終了

TypeScriptは、何百万ものJavaScript開発者が今日知っているのと同じ構文とセマンティクスから始まります。 既存のJavaScriptコードを使用し、一般的なJavaScriptライブラリを組み込み、JavaScriptからTypeScriptコードを呼び出します。

TypeScriptは、任意のブラウザー、Node.js、またはECMAScript 3(またはそれ以降)をサポートする任意のJavaScriptエンジンで実行されるクリーンでシンプルなJavaScriptコードにコンパイルされます。


すべてのブラウザで実行されるコードを約束しますが、それは真実ではないようです。そのため、この問題は1年以上続きます。

@Draccozが指摘しているように、この問題で何をしているのかを知りたいだけです。 しかし、あなたのホームページで1つのことを読み、この問題で反対のことを読むのは少しイライラします。

いいえ、ノードでのES相互運用機能や、最初にnpmから使用する推移的な依存関係を出荷するための合理的な戦略などが明確になるまで、これに関連するものは出荷しません。 TypeScriptを使用していなかった場合、依存関係の管理と解決に関して同じ問題が発生するため、JSエコシステム全体が独自に開発する可能性のあるものを考え出すことは意味がありません。 ただし、これらの問題が解決されたとしても、ここで変更を加えることを保証することはできません。

すべてのブラウザで実行されるコードを約束しますが、それは真実ではないようです。そのため、この問題は1年以上続きます。

この解釈は文字通りすぎると思います。 var fs = require('fs')はブラウザで実行すると機能せず、 HTMLDivElementはNodeで定義されておらず、 String.prototype.startsWithは古いブラウザでは機能しません。 これを解決するために、人々はTypeScriptの外部でツールとライブラリ/ポリフィルを作成しました。それらはより広範なJavaScriptエコシステムに適用されるからです。

では、この問題を閉じていただけますか? これは、TSがそれを実行するのを待つか、あなたがそれを実行していないと宣言する他のプロジェクトのブロッカーです。 単純なフラグを追加できない場合は、この問題を閉じて、他の人にあなたの決定を知らせてください。

@DanielRosenwasser迅速な対応ありがとうございました、本当にありがとうございます。 それは賢明な選択だと思います。

この解釈は文字通りすぎると思います。 var fs = require( 'fs')はブラウザで実行すると機能せず、HTMLDivElementはNodeで定義されておらず、String.prototype.startsWithは古いブラウザでは機能しません。 これを解決するために、人々はTypeScriptの外部でツールとライブラリ/ポリフィルを作成しました。それらはより広範なJavaScriptエコシステムに適用されるからです。

もちろんそうですが、¿Typescriptについて何も知らない人は他に何を考えることができますか? 私の解釈が文字通りすぎるという事実は、このテキストがTypescriptについて何も知らない人を「混乱させる」可能性があるという事実と同じくらい真実です😉。

実際の動作を反映するために、ドキュメント(https://www.typescriptlang.org/docs/handbook/modules.html)を更新できるかもしれません。

@DanielRosenwasserお返事ありがとうございます。 似たようなものを1年待っていました。

この機能が必要だったのは、ビルドツールなしで作成できるWebアプリの種類を確認できるようにするためです。 それまでは、前に書いたスクリプトを使用できます。

今日ブラウザでESモジュールとTypeScriptを使用できるようにするための解決策を探している私のような人々のために、私はhttps://github.com/guybedford/es-module-shimsを見つけました。 仕様の確定とブラウザの実装を待つ間、パッケージ名マップの一種のポリフィルとして機能します。 これは、TypeScript(TSコンパイラを除く)で単純なWebアプリを作成するときに、ビルドツールを使用したくないという@QuantumInformationの問題(私の問題も同様)を解決します。

import 'knockout'

export class MyViewModel {
    greeting: KnockoutObservable<string>
    target: KnockoutObservable<string>
    constructor() {
        this.greeting = ko.observable('hello')
        this.target = ko.observable('world')
    }
}
<!DOCTYPE html>


md5-f28d4b503a1603c40bfeb342f341bfbe


<main>
    <span data-bind='text: `${greeting()} ${target()}`'></span>
    <script type='module-shim'>
        import 'knockout'
        import { MyViewModel } from 'index'
        ko.applyBindings(new MyViewModel())
    </script>
</main>

理論的には、パッケージ名マップがブラウザでサポートされると、HTMLファイルでtype='module-shim'type='module'で検索/置換し、パッケージマップスクリプトを最終的にパッケージマップに含めるために最終的に変更することができます。スペック

.js拡張機能はブラウザなどで義務付けられていないことにも注意してください。いつでもWebサーバーをunpkgのように構成して、から.jsファイルを提供できます。拡張子のないリクエストURL。 すべてWebサーバー側で構成可能です。

@weswighamは非常に問題になる可能性があります。これは、tsc(およびクラシックノードモジュールの解決)が./foo./foo.jsが同じファイルを参照していることを認識しているためですが、ブラウザーはそれらを異なる方法で処理します。 Webサーバーがリダイレクトします。 インポートするたびに、まったく同じ方法でファイルを参照する必要があります。

ちなみに、この問題は、TypeScriptで生成されたモジュールが今日のブラウザーで使用されることを妨げるものではありません。 常に.js拡張子のファイルをインポートしてください。 tscは正しいことを行い、 .tsファイルから型を解決し、ブラウザーとの互換性を確保します。

@weswighamWebサーバーにアクセスせずにファイルを提供している場合があることに注意してください。 GitHub Pages、IPFS、S3など。シングルページアプリフレームワークの出現により、「サーバーレス」(ここでサーバーレスとは​​、アセットを提供するために制御/構成するサーバーがないことを意味します)を実行することがますます一般的になっています。 appleに対してリクエストが行われたときに、サーバー側のフィルターを使用してapple.jsを提供することはできません。

インポートするたびに、まったく同じ方法でファイルを参照する必要があります。

オーサリングの好みに応じて、いつでもどちらか一方の404を作成できます。 プロジェクト内でシンボリックリンクを使用した場合、同様の問題が発生し、対処方法も選択する必要があります。

常に.js拡張子のファイルをインポートするだけです

ええ、それもうまくいきます。

@QuantumInformationここで使用されているスニペットはオープンユースですか? プロジェクトで使用できますか? 😃

@distanteはいあなたはそれを使うことができます

参考までに、Jestを使用して、ソース内の.jsの拡張子をテストして変更している場合は、壊れます。
しかし、あなたはそれを修正するためにあなたのjest設定に以下を追加することができます

  "jest": {
    ...
    "moduleNameMapper": {
      "(.*)\\.js": "$1"
    }
  }

こんにちは@MrAntix

jestは、その逆ではなく、TypeScriptに適応する必要があるライブラリだと思います。

ビルドツールを使用したくない別のサイトがあります。 これは私たちがいる最高のものですか?

https://github.com/microsoft/TypeScript/issues/16577#issuecomment -452312753

回避策として、このようにすることができます(jsではなくtsファイルですが)😢

Screenshot 2019-06-05 at 22 47 49

誰かがそれを試してみたい場合:
https://github.com/QuantumInformation/web-gen-bot

ただし、現在のtsconfigでソースデバッグを機能させることができません。レポートが返されます。

結局、webpackに戻ったところ、ブラウザのビルドツールから離れようとしたときにnode_modulesがキラーでした。

Jestだけではありません。公開する前にtscを使用してTypeScriptをコンパイルすると、モジュールの解像度が異なるため、結果のパッケージをインポートするJSモジュールが破損します。

ここでの議論は、2つの関連するが、最終的には別々の問題に少し分かれているようです。

  • Typescriptは、ブラウザにネイティブにロードできるファイルを生成する必要があります
  • Typescriptは、ノードモジュールパスが常に有効なURLであるとは限らないという事実を解決する必要があります。

最初の問題に焦点を当てる必要があると思います。2番目の問題は明らかにtypescriptだけでは解決できないものだからです。

ただし、最初の問題は絶対にTypescriptが解決できるものであり、優先する必要があります。これは、Typescriptを使用して最新のブラウザーを対象としたWebアプリを構築したいほとんどの人にとって大きな障害となるためです。

私の意見では、問題はこれに要約されます:

tscを実行すると、拡張子が.jsのファイルが生成され、次に最初の.jsファイルをインポートする別のファイルが生成される場合、使用する拡張子にあいまいさはなく、拡張機能を含めるオプション。

Typescriptが生成するファイル以外のファイルを指すすべてのインポートステートメントについては、それらを変更しないでおくのは問題ないと思います(Typescriptが今日行っているように)。

最初のオプションと同様に、コマンドライン引数が最適であり、デフォルトではオフになっていると思います。 これは、webpackを使用する場合、webpackがモジュールのバンドルを処理するため、インポートに.jsを追加したくないためです。

とにかく、node_modulesは、ネイティブモジュールブラウザーアプリのハックを使用することを阻止したキラーでした。

これは、webpackを使用する場合、webpackがモジュールのバンドルを処理するため、インポートに.jsを追加したくないためです。

ただし、Webpackは.js拡張機能を完全にうまく処理するため、違いはありません。

実際、Webpackで.jsを使用する必要がある場合があります(同じ名前で拡張子が異なる複数のファイルがある場合)。

では、Webpackで.jsのインポートを望まない理由について詳しく説明していただけますか?

I don't wantと言うときは、ユースケースは必要ないという意味です。

その場合、デフォルトの動作にすべきではないという説得力のある理由はわかりません(常に別の構成フラグを追加することには消極的です...)

インポートを.jsに設定すると、ts-nodeはファイルに対して正しく機能しなくなります。 これは、ts-nodeが一度に1つのファイルのみをコンパイルし、出力されたファイルの内容がrequire('./foo.js')で終わる場合、nodejsがそのファイルを処理するときに、存在しない./foo.jsをロードしようとするためです。ディスク上のどこにでもあるため、失敗します。 一方、コードがrequire( ./foo )を行う場合、ts-nodeのハンドラーが呼び出され、その時点で./foo.tsをJSにコンパイルして返すことができます。

TypeScriptがすべての場合に.js拡張機能を発行する場合、ts-nodeは同じ問題に遭遇します。 ただし、拡張機能が自動的に追加されるかどうかを切り替えるオプションがある場合、ts-nodeはそのコンパイラオプションをオフに設定できます。これにより、現在のシステムが引き続き機能します。

Node.js --experimental-modulesには必須のファイル拡張子が必要なため、このためのAPIは依存関係の分析を必要とせずに簡単です- --jsextのようなオプションは、任意の.ts拡張子を.jsに書き換えることができますimport 'npmpkg.ts' $のように$ .tsで終わるパッケージ名です。 このケースは非常にまれですが、解決策でこれを包括的に処理するためのルールは、裸の指定子(URLまたは相対パスではない)が有効なnpmパッケージ名である場合(URLまたは相対パスではない)の行に沿って_裸の指定子_の例外を作成することです( https://github.com/npm/validate-npm-package-nameからの/^(@[-_\.a-zA-Z\d]+\/)?[-_\.a-zA-Z\d]+$/に一致し、書き換えの.ts拡張子を無視します。

.jsファイル拡張子を任意の相対インポートパスに追加するTypeScriptコンパイラトランスフォーマーを作成しました。 これは、 .tsファイルにimport { Foo } from './foo'がある場合、 import { Foo } from './foo.js'を発行することを意味します。 これはNPMで利用可能であり、使用方法の説明はプロジェクトのreadmeにあります。

https://github.com/Zoltu/typescript-transformer-append-js-extension

このようなものを(コンパイラオプションとして)TypeScriptコンパイラに統合する場合は、 .js拡張子を追加するタイミングと追加しないタイミングを決定する方が賢明なはずです。 現在、 ./または../で始まるパスを検索しますが、パス内の他の場所に.はありません。 これは、多くのエッジケースのシナリオでは正しく機能しないことを意味しますが、誰かが_実際に_それらのエッジケースに遭遇するかどうかは疑問です。

@MicahZoltuこれに対するユーザーランドのソリューションを見るのは素晴らしいことです。 TypeScript拡張オプションが_コンパイル時に.ts拡張を.js拡張に変換できるように、メンタルモデルに常にファイル拡張子が含まれるようになることは非常に重要だと思います。 これにより、解決のエッジケースが回避され、「。ts」で終わるnpmパッケージ名のケースだけが残ります。これは、前のコメントで説明したように処理できます。

@guybedford .tsファイルに.js拡張子を含めると、ファイルがts-nodeで実行できないようになります。 NodeJSがファイルを解決する方法のため、ts-nodeで問題を解決することは簡単ではありません。 これは、ハードコードされ.js拡張子を持つライブラリを公開した場合、そのライブラリはts-nodeを使用している人には機能しないことを意味します。 https://github.com/TypeStrong/ts-node/issues/783でこれに関する議論を参照してください。

@MicahZoltuつまり.tsファイルに.ts拡張子を含めるということです。

@guybedford .tsファイルに.js拡張子を含めると、ファイルがts-nodeで実行できなくなります。

これは、ノードとブラウザでTypeScriptを自動実行することが悪い考えであるもう1つの理由です。

@MicahZoltuつまり、.tsファイルに.ts拡張子を含めることを意味します。

これに伴う問題は、 .tsファイルと.js / .d.tsのペアの間の同等性を壊すことだと思います。 つまり、現在のプロジェクトでコンパイルされたファイルをインポートする場合は.tsを使用し、ファイルを別のプロジェクトに移動する場合は、 .jsを使用するようにインポートを変更する必要があります。 。

また、トランスがない標準的な環境では出力が機能しないことも意味します。 .tsconfigファイルからトランスフォーマーをインストールする方法がないことを考えると、それは常にカスタムコンパイラーを使用する必要があることを意味します。 これは、 .js .tsを使用するという小さなメリットのために、かなり大きな障壁になります。

つまり、現在のプロジェクトでコンパイルされたファイルをインポートする場合は.tsを使用し、ファイルを別のプロジェクトに移動する場合は、.jsを使用するようにインポートを変更する必要があります。

外部/内部のインポート境界は明確に定義されたものです。 依存関係が現在の同じビルドの内部.tsファイルから、独自の個別のビルドを持つ、またはおそらくTypeScriptではない別のパッケージインポートの外部.jsファイルに移行する場合、そしてはい、それは完全に異なる概念であるため、拡張機能を変更する必要があります。

また、トランスがない標準的な環境では出力が機能しないことも意味します。

トランスフォーマーはこれを調査するのに役立ちますが、この問題を解決するには、 --ts-to-jsまたは同様のコンパイラーフラグ/オプションが非常に必要です。

@guybedfordあなたは、 .tsを入れることがプラグインにとって正しいことだと私に確信させました。 しかし、それを実装しようとすると、TypeScriptでは実際には許可されていないことがわかりました。

// foo.ts
export function foo() { console.log('foo') }
// bar.ts
import { foo } from './foo.ts' // Error: An import path cannot end with a '.ts' extension. Consider importing './foo' instead
foo()

こんにちは、これはどうですか?


入力:

// src/lib.js.ts
export const result = 42;
// src/index.js.ts
import { result } from "./lib.js";

console.log(result);

出力:

// build/lib.js
export const result = 42;
// build/index.js
import { result } from "./lib.js";

console.log(result);

問題#30076

TypeScriptファイルの唯一の.ts拡張子は、私にとって最も適切だと感じています。 多くの場合、ターゲットが何であるかはコンパイル時までわかりません。 たとえば、私のライブラリプロジェクトの多くには、さまざまな環境を対象とする複数のtsconfig.jsonファイルがあります。たとえば、 .jsファイルを出力し、インポートパスを.jsにマップする最新のブラウザを対象としています。 、または.mjsファイルを出力し、インポートパスを.mjsにマップする必要がある最新のノードをターゲットにします。

@MicahZoltuは、 .tsで終わるファイルのインポートがエラーであるということは、実際にはおそらく私たちの利益になります。 これは、$ .ts拡張機能がフラグを必要とせずに使用されるときはいつでも、コンパイル時に.tsから.js拡張機能の書き換えを追加できることを意味するためです:)

おそらく、後続の.ts拡張機能がサポートされて.js拡張機能に書き換えられるようにするPR(おそらくこの機能を有効にするフラグの下にありますが、時間内に削除できるフラグの下で)は素晴らしい方法ですこのパスに沿って開始します。

// cc @DanielRosenwasser

この問題はすでに非常に長いので、誰かがすでにこれを言っている可能性があります。そのため、すでに言われていることを繰り返すリスクがあります。

TypeScriptは、JavaScriptが有効であるため、開発者がimportで拡張機能を指定できるようにする必要があります。 そして、これはJS / TS拡張機能だけではありません! ESMでは、MIMEタイプが正しい限り、どの拡張子も有効です。

import actuallyCode from './lookLikeAnImage.png';

…サーバーがそのファイルで有効なJavaScriptを提供し、正しいMIMEタイプを設定している限り有効である必要があります。 同じことがTSにも当てはまる可能性があるため、これはさらに進んでいます。 TSファイルは、JS MIMEタイプで提供される単なるJSソースコードである可能性があるため、ESMモジュールインポートの有効なパスです。

IMO TypeScriptは、拡張機能のないインポートのみを考慮し(今日必要なように)、そのままにしておく必要があります。エラーや警告などはありません。それ以外の場合は、JSのスーパーセットであると主張するものにとってはかなり残念な有効なJavaScriptコードを拒否します。

これを提起するのに適切な場所ではない場合は申し訳ありませんが、他にもいくつかの問題があります:#18971、#16640、#16640ですが、このトピックに関する問題は左右に閉じられているようですので、これが「メイン」の問題だと思います開いたままにしておいたので。

NodeJSv12.7.0で遊ぶ

salathiel@salathiel-genese-pc:~/${PATH_TO_PROJECT}$ node --experimental-modules dist/spec/src/ioc
(node:15907) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '${PROJECT_ROOT}/dist/spec/src/ioc' imported from ${PROJECT_ROOT}/
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
    at Loader.resolve (internal/modules/esm/loader.js:73:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:149:40)
    at Loader.import (internal/modules/esm/loader.js:133:28)
    at internal/modules/cjs/loader.js:830:27
    at processTicksAndRejections (internal/process/task_queues.js:85:5) {
  code: 'ERR_MODULE_NOT_FOUND'
}
salathiel@salathiel-genese-pc:~/${PATH_TO_PROJECT}$ node --experimental-modules dist/spec/src/ioc.js
(node:16155) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '${PROJECT_ROOT}/dist/spec/src/observe' imported from ${PROJECT_ROOT}/dist/spec/src/ioc.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
    at Loader.resolve (internal/modules/esm/loader.js:73:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:149:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
    at link (internal/modules/esm/module_job.js:42:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

さて、なぜこれが迷惑なのかわかりません...

現時点では、TypeScriptはパスを書き換えません。 確かに面倒ですが、現在、 .js拡張機能を自分で追加できます。

@DanielRosenwasser https://github.com/microsoft/TypeScript/issues/16577#issuecomment -309169829

オプションの背後に実装するのはどうですか? --rewrite-pathsrewritePaths: true )のように?

@ viT-1当面の回避策は次のとおりです: https ://github.com/microsoft/TypeScript/issues/16577#issuecomment -507504210

@MicahZoltu SystemJSバンドル(tsconfig outFileオプション)でユースケースを解決します

私は人々がこれについて書いたすべてのコメントを読んだわけではありませんが、なぜ私が.jsを何億回も書かなければならないのか分かりません。 コンピューターにやってもらいたい。

@richardkazuomiller私たちは皆そうしていますが、 @ DanielRosenwasserhttps://github.com/microsoft/TypeScript/issues/16577#issuecomment -448747209で、今のところそうする気はないと述べています(この問題がまだ誤解を招くように開いていることに驚いています上記のステートメントの後、非常に長い間)。 コンピューターにそれを実行させたい場合は、インポートパスの書き換えを処理するためにバンドラーまたはサードパーティのツールを使用することを検討してください。

誰が私にこの問題を終わらせたいですか?

閉じないでください。TypeScriptチームがESMインポートにどのように対応し、代わりにMIMEタイプに依存する拡張機能を使用できるようになるかを確認するのを待っています。 現時点では、これはJavaScriptで可能ですが、TypeScriptでは不可能です。 (詳細については、以前のコメントを参照してください。)

@TomasHubelbauerこれが、構成ファイルにフラグを提案した理由です。これは、すべての拡張子のないインポートに.js(またはその他の構成済み)拡張子を追加する必要があることを示している可能性があります。 これはオプトインになるため、デフォルトがfalseになる可能性があり、既存のプロジェクトまたは異なるニーズを持つプロジェクトがそのまま機能します。

前に言ったように:

TSのどのバージョンがそれを追加したかはわかりませんが、 ' ./file.js'などのインポートが機能するようになりました(ファイルが実際にfile.tsであっても)。
TypeScriptはファイルを正常に解決し、完全な.jsインポートをターゲットに出力します。

有効なJavaScriptは有効なTypeScriptであるため、これは理にかなっています。 あなたができるので:

import foo from './bar.js'

... JSでは、TSでも実行できるはずです。 そうすれば、拡張機能が正しいので、ネイティブES6モジュールを使用する問題を解決できます。


また、ブラウザが./foo/barのインポートを確認すると、実際にそれを要求することも忘れないでください。 何も提供されなかったという事実は、サーバーによるものでした。 /foo/barのリクエストが$ /foo/bar.jsで満たされるように構成できます。 これが良い解決策、あるいは良い考えであるとは言わないが、技術的にはうまくいくだろう。

設定ファイルのフラグ。拡張子のないすべてのインポートに.js(またはその他の設定済み)拡張子を追加する必要があることを示している可能性があります

これにより、ほとんどの場合が解決されます。 TypeScriptチームは、この構成オプションのPRを検討する用意がありますか?

NodeJSは、相対パスモジュールの解決に関して、_デフォルトで_ブラウザと同じように動作するようになりました。 デフォルトでは、 .js拡張子を推測しなくなりました。 これは、TSCの現在の動作により、すべてのランタイムコンテキストで無効なJSが発行されることを意味します。 ESMのブラウザとNodeJSの動作の両方が明確になっているため、この問題に対処する必要があるように思われます。

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

esmの新しいリゾルバーには、新しい解決モードが必要ですmoduleResolution: nodeは、実際には、「古いバージョンのノード」と呼べるcjsリゾルバーにすぎません。 新しいesmリゾルバーをターゲットにする場合は、より適切に一致させるために新しい解決モードが必要になります。 特に、ノードは既存のすべての構成で古いリゾルバーを完全にサポートしているためです。 (注意:このような新しいリゾルバーを_デフォルト_にするのは難しいでしょう)

けれど! それについては_意見の相違_があり、_一部の人々は意見を事実として述べることを選択します_が、期待される拡張動作を返す--es-module-specifier-resolution=nodeフラグがまだあり、フラグが付けられていないにもかかわらず、ドキュメントが言うように、まだデフォルトになる可能性があります、ノード内のesモジュールは_本質的にまだ実験的です_。

また、元のリクエストを思い出させるために、インポートを書き換えません。 これまで。 まったく。 指定子入力===指定子出力。 指定子は構造の意図を記述し、ある意図された構造から別の意図された構造に暗黙的にマッピングすることは私たちの目標ではありません。 このように考えることもできますconst varFoo = "./Foo"; import(varFoo)と書いた場合、必要に応じて、そこに拡張機能を追加しますか? いいえ、それはばかげています。すべての形式の動的入力を処理するには、実行時に動的インポートをラップする必要があります。突然、組み込みのプラットフォームローダーの上にある独自のモジュールローダーになりました。 代わりに、拡張機能を省略したときに適切にエラーが発生するリゾルバーモードを提供します(これは、間違いなく、すでにlintルールを見つけることができます)。

このスレッドを見つけて、入力ソースに拡張機能を持たせたくない場合、および(ノードes)モジュールをターゲットにするときに出力を引き続き使用する必要がある場合は、 https://github.com/でフィードバックを提供する必要があります。

突然、私たちは自分たちのモジュールローダーになりました

tscは、何があっても機能モジュールローダーである必要はありませんか? インポート元のモジュールが見つからない場合は、インポートに対してタイプチェックを行うことはできません。 さまざまなモジュールローダーがすべて、広く互換性のある方法で動作するか、少なくとも、対応するのにかなり苦痛がない、予測可能な異なる方法で動作することを確認したいと思います。

NodeJSは、相対パスモジュールの解決に関して、デフォルトでブラウザと同じように動作するようになりました。 デフォルトでは、.js拡張子を推測しなくなりました。 これは、TSCの現在の動作により、すべてのランタイムコンテキストで無効なJSが発行されることを意味します。

TypeScriptがすでにサポートしているような指定子で.jsファイル拡張子を使用するもう1つの理由ではありませんか? これは、拡張機能のないインポートでtscがエラーになった場合に役立つことを除いて、すべてを解決します。

何があっても、tscは機能モジュールローダーである必要はありませんか? インポート元のモジュールが見つからない場合は、インポートに対してタイプチェックを行うことはできません。 さまざまなモジュールローダーがすべて、広く互換性のある方法で動作するか、少なくとも、対応するのにかなり苦痛がない、予測可能な異なる方法で動作することを確認したいと思います。

ランタイムローダーの実装を提供することは目的としていません。ターゲットとするランタイムローダーを反映するコンパイル時の分析だけです。 ランタイムコンポーネントがないと、すべてのインポートを再マップすることはできません。ランタイムコンポーネントは、持っていないか、持つことを目的としていません。

何があっても、tscは機能モジュールローダーである必要はありませんか?

実行時ではありません。 tscは、選択したランタイムが指定子を解決し、ビルド時にそれを実装する方法を理解する必要がありますが、ランタイムは純粋に環境に任されています。

次のように考えることもできます。constvarFoo= "./Foo"; import(varFoo)必要に応じて、そこに拡張機能を追加しますか?

@weswighamこれは動的インポートに関する強力な議論ですが、静的インポートでそれを行うことができるとは思いませんか? どちらの戦略も同じである必要があるという議論は理解できますが、静的インポートは動的インポートとは非常に異なる役割を果たし、静的な戦略を変えることはまったく_不合理_ではないと思います。インポートの書き換えと動的なインポートの書き換え。

TypeScriptがすでにサポートしているような指定子で.jsファイル拡張子を使用するもう1つの理由ではありませんか? これは、拡張機能のないインポートでtscがエラーになった場合に役立つことを除いて、すべてを解決します。

@justinfagnaniこれには2つの問題があります。

  1. インポートで.js拡張子を指定すると、TSをネイティブに実行するランタイム(TS-Nodeなど)は機能しなくなります。
  2. インポートに.js拡張子を含めると、コンパイラ(IMO)に嘘をつきます。

(2)に関して、2つのTSファイルa.tsb.tsがあり、 a.tsimport ... from './b.js'を実行する場合、コンパイラに「兄弟ファイルがあります」と伝えています。 b.jsという名前です。このステートメントは正しくありません。さらに悪いことに、 .b.tsb.jsの両方がある場合(実際には互いに派生物ではない可能性があります)、明示的に拡張機能を含めたとしても、どちらを参照しているのかがあいまいになります。

私は、ユーザーが(ユーザーとして)実際に何を望んでいるかをコンパイラーに伝える必要があり、それは「Xの名前と拡張子を持つ任意のファイルをインポートする」( import ... from './foo'の場合)のいずれかであると考えています。 )または「このファイルを具体的にインポートする」( import ... from './foo.ext'の場合)。 コンパイラがTSファイルをインポートしていることを検出し、コンパイラが.jsファイルを出力し始めた場合、コンパイラはインポートを更新して適切なファイルを正しくインポートする必要があると思います。 これは、importステートメントで.ts.jsに変更することを意味する場合があります。

@justinfagnaniこれには2つの問題があります。

  1. インポートで.js拡張子を指定すると、TSをネイティブに実行するランタイム(TS-Nodeなど)は機能しなくなります。

これはTS-Nodeのバグです。 tscの動作と一致していません。

  1. インポートに.js拡張子を含めると、コンパイラ(IMO)に嘘をつきます。

それは実際には反対です-あなたは実際に何がインポートされるかについて真実を語っています。 .tsファイルではなく、 .jsファイルをインポートします。 また、 .d.ts / .jsペアと.tsファイルの間に目に見える違いはないはずです。 それらは交換可能です。 これを実現する唯一の適切な方法は、 .jsファイルをインポートすることです。コンパイル後の.tsファイルはどうなりますか。

@justinfagnani

また、.d.ts /.jsペアと.tsファイルの間に目に見える違いはないはずです。

これは常に正しいとは限りません。 JS MIMEタイプですべてのJS、TS、およびDTSを提供するようにサーバーを構成し、JavaScriptでそれらをすべて個別にインポートすると、ランタイムはそれらすべてをJSとして忠実に実行します。 ESMは拡張機能をまったく気にしません。

そのため、TSユーザーは実際に.ts拡張子を含めるように強制する必要があり、拡張子のないファイルまたはその名前を実際にインポートしない限り、拡張子のないものはエラーになります。 そして、TSはインポートを出力で.jsに書き換えます。 また、JSファイル(TSによって生成されたものではない)が存在する場合、それもエラーになります。

これはTS-Nodeのバグです。 tscの動作と一致していません。

これはNodeJSローダーの制限であり、TS-Nodeのバグではありません: https ://github.com/TypeStrong/ts-node/issues/783#issuecomment -507437929

これは常に正しいとは限りません。 JS MIMEタイプですべてのJS、TS、およびDTSを提供するようにサーバーを構成し、JavaScriptでそれらをすべて個別にインポートすると、ランタイムはそれらすべてをJSとして忠実に実行します。 ESMは拡張機能をまったく気にしません。

私はそれをよく知っていますが、ブラウザもTypeScriptを実行しません。 環境が実際にロードするファイルがJavaScriptファイルであることはほぼ普遍的に真実です。

私のポイントは、 .js / .d.tsのペアがすでにある場合、たとえばサードパーティのパッケージから、 .jsファイルをインポートすると、 tsc.d.tsファイルを参照して、タイプをロードします。 つまり、 .js / .d.tsペアは.tsファイルのように動作します。これは、変更せずにJavaScriptからTypeScriptに透過的に移植できるためです。移植されるファイルのインポート。

これはTS-Nodeのバグです。 tscの動作と一致していません。

これはNodeJSローダーの制限であり、TS-Nodeのバグではありません:TypeStrong / ts-node#783(コメント)

TS-Nodeがtscの動作から逸脱しているのはまだバグです。 そのため、 tscとTS-Nodeの両方で機能しない.tsファイルが作成されます。また、TS-Nodeが従うべき標準セッターとしてtscを強く検討します。 。

私のポイントは、たとえばサードパーティのパッケージから.js / .d.tsペアがすでにある場合、.jsファイルをインポートすると、tscは.d.tsファイルを参照してタイプをロードするということです。 つまり、.js / .d.tsペアは.tsファイルのように機能します。これは、移植されるファイルのインポートを変更せずにJavaScriptからTypeScriptに透過的に移植できるためです。

外部の_package_をロードする場合は、名前付きモジュールからエントリポイントファイルへのマッピングを行う何らかのランタイムパッケージローダー(ブラウザの名前付きインポートマップなど)が必要になります。 ただし、相対的な.js / .d.tsのペアがある場合は、一般的にあなたの主張は正しいと思います。 その場合、 import ... from './foo.d.ts'またはimport ... from './foo.js'のどちらを実行する必要があるのか​​、私は危機に瀕しています。

.d.tsファイルは、基本的に、マップ元の拡張子に関する情報を含まない構造を説明するヘッダーです(通常、同じ名前で異なる拡張子を持つ複数のファイルを同じ場所に配置するべきではないという前提で、ビルド時にエラーが発生します)-今日でも、関連するランタイム「ソース」は.jsまたは.jsxjsx: preserveを使用)である可能性があります。 大まかに言って、送信時にインポートで.d.ts参照を.jsに置き換えて、それが機能すると想定することはできません...

tscがより広いものに関してあまり意見が分かれないことが正確に重要です
ビルドと解決の仮定。

それが複雑な境界上のマルチツールであることを考えると、それは予想されるでしょう
その構成により、ユーザーが望むように動作することができます。

解像度の変更を公開しないように非常に慎重な努力が払われてきました
tscコンパイルプロセスの一部-これ自体が意見を強制します
ユーザーと彼らのワークフローの摩擦を引き起こします。

2019年11月27日水曜日16:48ウェズリーウィガム[email protected]
書きました:

.d.tsファイルは、基本的に、以下を含む構造を説明するヘッダーです。
それがどの拡張子からマッピングされているかについての情報はありません(
通常、同じ名前のファイルを複数持つべきではありませんが、
同じ場所にあるさまざまな拡張子)-今日でも、関連する
ランタイムの「ソース」は、.jsまたは.jsx(jsx:preserveを使用)の場合があります。 あなたは出来る
大まかに言って、送信時にインポートで.d.ts参照を.jsに置き換えないでください
そしてそれが機能すると仮定します...


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/microsoft/TypeScript/issues/16577?email_source=notifications&email_token=AAESFSQS2DQ23RR5KN3RTZ3QV3TLXA5CNFSM4DPRQTY2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAESFSUAP2YO23ZFHCOWVQLQV3TLXANCNFSM4DPRQTYQ

このシナリオをどのように処理するかはわかりませんが、同じことに関連する疑問がありました。

htmlファイルに次のようなインポートマップがあります。

<script type="importmap-shim">
      {
        "imports": {
          "@root/":"../../../",
         }
      }
</script>

そして、次のようなファイルをインポートするtsファイルがあります。

import '@root/components/page-main/page-main.js';

現在、この設定はブラウザでうまく機能します。 しかし、VSCodeでナビゲート/使用するにはどうすればよいですか? つまり、インポートをCtrlキーを押しながらクリックしてファイルに移動し、オートコンプリートを取得し、defと入力します。

また、tscがインポート拡張機能を.tsから.jsに書き換えないことを考えると、ビルド時に同じことを行うために使用できる他の推奨ツール/パッケージはありますか? ありがとう。

(ESモジュールとインポートマップにhttps://github.com/guybedford/es-module-shimsを使用しています)

しかし、VSCodeでナビゲート/使用するにはどうすればよいですか?

pathsコンパイラオプションを検索します。

また、tscがインポート拡張機能を.tsから.jsに書き換えないことを考えると、ビルド時に同じことを行うために使用できる他の推奨ツール/パッケージはありますか? ありがとう。

.jsを使用するだけで、ビルド時に.tsファイルを参照している場合でも正常に機能します。

@tvvigneshhttps ://github.com/Zoltu/typescript-transformer-append-js-extension/コンパイル時に拡張機能のないインポートを.jsに書き換えます。 私は個人的に「TSファイルに.jsを入れるだけ」のファンではありません。そうすると、コードがts-nodeで実行されなくなるからです。 ts-nodeでコードを実行する必要がない場合は、.jsを使用すると機能します。

しかし、VSCodeでナビゲート/使用するにはどうすればよいですか?

pathsコンパイラオプションを検索します。

また、tscがインポート拡張機能を.tsから.jsに書き換えないことを考えると、ビルド時に同じことを行うために使用できる他の推奨ツール/パッケージはありますか? ありがとう。

.jsを使用するだけで、ビルド時に.tsファイルを参照している場合でも正常に機能します。

早速お返事をいただきありがとうございます。 tsconfig.jsonでパスオプションをすでに設定しましたが、それでもctrl + clickでナビゲートできません。

これはtsconfig.jsonの私のパスオプションです

"paths": {
            "*": ["www/node_modules/*"],
            "@modules/*": ["www/node_modules/*"],
            "@root/*": ["www/*"]
        }

.jsを使用するだけで、ビルド時に.tsファイルを参照している場合でも正常に機能します。

何千もの輸入品がある場合、これは非常に非現実的です。

.jsを使用する」の問題は、TypeScriptが.mjsファイルを出力すると、プログラムが機能しないことです。 これは、ブラウザで動作するタイプスクリプトまたはノードJSで動作するタイプスクリプトを記述している状況に陥ることを意味します。 両方で機能するTypeScriptを作成することはできなくなりました。

ここでの議論は、「それはTypeScriptのせいではなく、ブラウザとNodeJSが分岐している」というものだと思います。

ノード13.2は.js拡張機能を問題なくサポートしています。

@justinfagnani ESモジュールの場合? NodeJSは.mjs拡張子が付いている場合にのみESモジュールをロードすると思いました。そうでない場合、ファイルはCommonJSとして扱われましたか?

このスレッド全体が少し見当違いだと思います。 ファイル拡張子を明示的に書き込むと、この問題全体が解決されます。 JavaScriptファイルをインポートする場合は、.js拡張子を記述します。 TypeScriptファイルをインポートする場合は、.ts拡張子を記述します。 これは標準で許可されており、TypeScriptコンパイラはそれをすべて同じようによく理解しています。 唯一の問題は、コンパイラが.ts拡張子がエラーであると述べていることです。 これは純粋なトランスパイルには影響しませんが、タイプエラーにすぎません。 TypeScriptでオーサリングしているので、明らかに.tsファイル拡張子が有効であるため、TypeScriptはこれを修正する必要があります。 この問題を回避するために、Deno.jsにはVSコード拡張機能があります: https ://marketplace.visualstudio.com/items?itemName = justjavac.vscode-deno

WebAssemblyの登場により、Webアプリケーションはますます多くのファイルタイプのインポートを開始する予定です。 .wasm、.js、.ts、.rs、.cなどのファイルをインポートするかどうかを明示的に示すことがますます重要になります。

私が書いたスクリプトを実際に使った人はいますか?

https://github.com/microsoft/TypeScript/issues/16577#issuecomment -310426634

もしそうなら、フィードバックはありますか?

@QuantumInformation私はあなたのスクリプトを使用していませんが、私が書いたTypeScriptトランスフォーマープラグインは基本的に同じことをします。 😊https://github.com/Zoltu/typescript-transformer-append-js-extension/

まず第一に、私はそれを実装するようにtypescriptを説得することを再び試みるつもりはありません、私はそれを理解します、あなたはそれをしません。
私はコメントを読んでいて疑問に思っています:パスに.jsを追加するとすべてが解決すると言っている人たち全員-本当にサードパーティのパッケージを使用していませんか? インポートに拡張機能を追加して、node_modulesの内容を修正するにはどうすればよいですか?

@MicahZoltuああいい

どう言う意味ですか? パスを使用する場合は、node_modulesからインポートするファイルのファイル拡張子を明示的に記述します。 しかし、それは通常、とにかく裸の輸入品ではないでしょうか?

相対パスを指定すると、それはむき出しになりません。 ただし、インポートしているパッケージの内部インポートについて話しているので、たとえばrxjsを見てください。

@Draccoz誰かがimport { ... } from './foo'のようなTypeScriptを作成し、それをNPMパッケージとして公開すると、ESモジュールをターゲットにしている場合でも、ユーザーはそのライブラリをブラウザで直接使用できないというのがポイントだと思います。 ここでのMicrosoftの主張は、ブラウザで動作することを期待してそのようなコードを配布している場合、パッケージは間違っているということだと思います。

node_modulesに存在するファイルの拡張子を記述します。 JavaScriptファイルの場合import * as stuff from 'rxjs/path/to/file.js'; 、TypeScriptファイルを配布した場合はimport * as stuff from 'rxjs/path/to/file.ts'; 。 私が間違っていなければ、これは今すぐに機能します

@lastmjsはい。ただし、 rxjs/path/to/file.tsimport foo from './bar' $が含まれている場合はどうなりますか? サードパーティのライブラリであるため、ファイルを変更できないため、これを変更することはできません。

そのため、どこでも明示的な拡張機能を使用するようにプッシュする必要がありますが、そうです。 私のツール(https://github.com/lastmjs/zwitterion)は、拡張子が省略されているファイルの一時的な解決策として、この書き換えを行います。

ええ、私のポイントはまさにそれでした-拡張機能を追加するだけでは、変更できないサードパーティのライブラリは修正されないので、それは解決策ではありません。
私もMicrosoftポイントを取得しているので、これ以上プッシュしません(この問題を開いたままにしておくと、TSがこれを解決するのを待つのではなく、パッケージメンテナがビルドを調整するのを妨げる不必要な希望を与えるという事実を除けば)ビルドツールとしてtypescriptのみを使用し、他の依存関係は使用しないでください。

ええ、でも明らかに希望はまだ多くの人にとって良いことです

image

それでも、それらのコメントを通じて、実装されないことが何度か述べられたのに、なぜそれを開いたままにしておくのですか?

誰かがimport {...} from './ foo'のようにTypeScriptを記述し、それをNPMパッケージとして公開した場合

多くの人がコンパイルされていないTSをNPMパッケージで公開していますか? 私はこれを自分の内部使用のために見ていました。 私はプロジェクト間で共有される共通コードのライブラリを作成しており、NPMがそれらをパッケージ化するための合理的な方法であると考えました。私たちのチームはTSに排他的に移行したので、depsをコンパイルする必要はありません。 ただし、最も一般的な使用例は、個別の型指定を使用してJSにパッケージをビルドし、 modulesまたはmainをJSにポイントし、 typesを型指定にポイントすることです。

コンパイルされていないTSをNPMに公開するための規則はありますか? もしそうなら、これはどこかに文書化されていますか? これは元の問題からOTをさまよっていると思いますが、「サードパーティのTypeScript」(パッケージ)がサポートされているユースケース/目標であるかどうかを知る必要があるため、答えに関連していると思います。

@ thw0rted明確ではないことをお詫びします、私は意味しました:

...誰かがimport { ... } from './foo'のようなTypeScriptを作成し、それを今日TSCを使用してJSにトランスパイルし、そのJSをNPMパッケージとして公開した場合...

実装されない場合は、MSに任せて問題を解決します。

ああ、私は今それを取得します。 はい、( target: ES2018を使用して)トランスパイルすると、発行されたJSは拡張機能をインポートステートメントから除外しますが、コンシューマーがすべてをwebpack / babelに入れており、不足している拡張機能を埋めている必要があるため、機能します。私のため。 私は今スピードアップしています。 私の「パッケージ」が最初にwebpackを経由しないと、ブラウザでネイティブに機能しないことすら思いつかなかった。

ええ、これは難しいものです。

@ thw0rted webpack / babelを使用していないため、ボックスから.jsを解決するのは問題です。
いくつかの解決策/回避策は、デフォルトの解決ソース用にWebサーバーを構成することです。

他の人が言ったことを繰り返して申し訳ありませんが、これは私が毎日扱っていることなので、私の一方的な2セントの別のものを投入したいと思います。

TypeScriptは特定の環境(Node.js、Webpackなど)に対応する必要はないことは知っていますが、特別に構成されていない限り、拡張機能が常に必要な環境がたくさんあるので、私はしません。それらは無視されるべきだと思います。 インポートはNodeのフラグの背後になくなり、インポートパスはWeb上のURLパス名と一致する必要があります。 URLの末尾に.jsを付ける必要はありませんが、これは事実上の標準です。

Microsoftのいい人たちが本当にファイル拡張子をデフォルトにしたくないのなら、私はそれについて議論しません。 あなたはおそらく私より賢いですが、同じファイル内の他のインポートに基づいて拡張機能が必要かどうかを推測する代わりに、プロジェクト全体で設定できるので、最初のIntellisenseオートコンプリートで機能する場合は確かに幸せですインポートがファイルに追加されました!

それまでの間、これを修正するVSCodeプラグインを知っている人はいますか? eslintにインポート/拡張機能を追加することは、これに対処するために私ができる最善のことです。

現在、.js拡張子なしimport行を記述し、 sedを使用して出力ファイルに.js拡張子を追加しています。
https://github.com/yoursunny/NDNts/blob/9f50fcec245b33c7649fa815bbb3dd404eee160e/mk/build.sh#L12 -L14
出力ファイルが変更された後は一致しなくなるため、本番ビルド中にSourceMapを削除する必要があります。

ts-jestが壊れているため、.tsソースファイルに.js拡張子を書き込むことができません。
コンパイルされた.jsファイルでJestを実行することは可能ですが、 Coverallsを壊します。

@yoursunnyはい、sedはバリアントです(私も使用しましたが、importmapファイルマッピングで構成できるconfigのため、 replace-in-fileを好みます)、生成されたjsファイルの文字列を置き換えますが、臭いはよくありません=)拡張機能を追加すると、変換プラグインを使用したttypescriptの便利な機能/オプションになります(例:@MicahZoltuによるtypescript-transform-paths )。

@richardkazuomillerこの部分は真実ではありません:

Microsoftのいい人たちが本当にファイル拡張子を付けたくないのなら、デフォルトにします

TypeScriptのみ:

  1. Node-requireスタイルのモジュール解決を可能にします(ファイル拡張子を必要とするNode-importスタイルの解決を可能にするためにこれを拡張する必要があります)。
  2. 同じコンパイルユニットで、コンパイラによって生成される前であっても、.jsファイルを.js /.d.tsペアに解決します。
  3. インポート指定子を_まったく変更しません_。

したがって、これらすべての解決策は、拡張子が.jsの.jsファイルをインポートすることです。 TypeScriptは正しい.tsファイルに解決され、インポート指定子は変更されないため、ブラウザーとノード> = 13.2でのみ機能します。

@yoursunnyts-jestに対してバグを報告しましたか? ここでは、事実上のTypeScript標準から逸脱しています。 また、.jsファイルのソースマップを利用できない場合は、Coverallsのバグのようです。

ts-jestに対してバグを報告しましたか? ここでは、事実上のTypeScript標準から逸脱しています。

いいえ、ts-jestの解決がどのように機能するかを完全には理解していないためです。

また、.jsファイルのソースマップを利用できない場合は、Coverallsのバグのようです。

Coverallsは、ビルドプロセスからlcovレポートを受け取り、GitHubにコミットされたファイルを使用してコードカバレッジを表示します。
出力.jsファイルをGitHubにコミットしません。 .jsファイルで単体テストを実行すると、lcovレポートはGitHubに存在しない.jsファイルを参照します。
したがって、Coverallsはソースファイルを見つけることができません。 カバレッジ率は表示されますが、カバーされていない行を表示することはできません。

新しい時代がやってきた!

新しくリリースされたNode.jsv13とすべての主要なブラウザーは、すぐに使用できるネイティブESモジュールをサポートします。TypeScriptがこれらの環境を簡単な方法でサポートするのは素晴らしいことです。

最も基本的なユースケース(単純な静的ファイルサーバーを介して提供されるWebサイト)の最も簡単な解決策は、 "appendJsExtension": trueなどの新しいコンパイラオプションを追加することです。

@mjbvz閉じたVSCodeのリポジトリの問題は少し異なります。オートコンプリートを使用してインポートステートメントを自動的に追加することです。 VS Codeがこれを行うと、 .js拡張子なしでimportステートメントが追加され、ランタイムが失敗するまでこれを見落とすのは簡単です。

ただし、TypeScriptが"appendJsExtension": trueなどのオプションを追加する場合、それはそれほど重要ではなく、ソースに.jsがなくてもTSコードを記述できます。

おそらくVSCodeプラグインには、自動完了されたインポートステートメントでの.js拡張機能の自動追加を有効/無効にするオプションが必要ですか?

@mjbvz VS Code / Intellisenseの問題は関連していますが、重複として閉じるべきではありません。 この問題が最終的にWONTFIXとしてクローズされた場合、実際にはVSCodeの問題の重要性が増します。

1つのポイントが見落とされており、JS拡張機能が特別な場合のソリューションがこれをどのように解決するかを理解していません:ESMの場合、拡張機能に特別なステータスはなく、サーバーがブラウザにサービスを提供している限り、拡張機能のないファイルでも完全に問題ありません適切なtext / javascriptMIMEタイプ。 つまり、次のようなコードです。

import something from './javascript-code.png';
import something2 from './javascript-code2.js';
import something3 from './javascript-code3.ts';

これは、ファイル(拡張子に関係なく)にJavaScriptコードが含まれ、JavaScriptMIMEタイプでブラウザーに提供される限りすべて有効です。

TypeScriptはJavaScriptのタイプセーフなスーパーセットである必要があるため、上記のようなインポートを許可する方法がわかりません。コードは有効なJavaScriptであり、TypeScriptがそれを受け入れない場合は、安全なスーパーセットではなくなるためです。 JavaScriptの、それは正しくありませんか?

では、JS拡張が暗示されているソリューション、または許可されている唯一のソリューションがこれを削減できるとは思わないのでしょうか。 さらに、TSおよびDTS拡張機能IMOでさえ、特殊なケースにすることはできません。これは、通常はそうではありませんが、ESMに関する限り、TypeScriptコードやブラウザーへのサーバーではなく、JavaScriptコードを含む可能性があるためです。 、適切なMIMEタイプで提供される場合。

私はこの面で何かが欠けていますか? TypeScriptがコードインポートで任意の(欠落しているものを含む)拡張機能のサポートを実装しない可能性はありますか?また、 file.tsfileが与えられた場合、TypeScriptはモジュールインポートでTS拡張機能を想定し続けることができますか? (拡張子なし)その後、競合が発生しますか?

WebおよびServiceWorkerは、ESモジュールのインポート/エクスポートのサポートも受けています

私は、 @ trusktrのアイデアをコンパイラオプションとして実装するというアイデアを完全にサポートし、支持します。 webpackやrollupのようなバンドラーを排除したいというわけではありません。 しかし、このような機能を使用すると、フープを飛び越えたり、厄介な回避策を使用したりせずに、単純なTypescriptプロジェクトをコンパイルするだけで、バンドラーのセットアップに費やす多くの手間と時間を取り除くことができると思います。

これをTypescriptコンパイラのオプションと考えてください。 <3

コンパイルされた個々のjsファイルをwebpackや--outFileなしで、あらゆる種類のモジュールシステムを使用してブラウザで実行できる方法を知っている人はいますか?

私の問題はこれです:私が取り組んでいるかなり大きなTypeScriptプロジェクトは、 ts-loaderを使用してwebpackでバンドルされたjsファイルにコンパイルするのに約35秒かかります。
これを最適化できる唯一の方法は、コンパイル時間を20秒に短縮するtranspileOnlyを使用することでしたが、それでも低速であり、型チェックが緩んでいます。
webpackを取り除くには、outFileを使用して約14秒かかる可能性がありますが、それでも私には遅すぎます。 incrementalを使用しても違いはありませんでした。

コンパイル時間を数秒にする唯一の方法は、1tsファイルごとに1つのjsファイルを発行し、 incrementalフラグを使用することでした。 この場合、tsは実際に変更されたファイルのみを検出してコンパイルすると思います。 問題は、これを試したモジュールターゲット(system、amd、es6)のいずれのブラウザーでも実行できなかったことです。
tsconfig.jsonpathsマッピングを使用していますが、コンパイルされたjsファイルで発生するエラーは、主にこれらのエイリアスを解決できないことに関連しています。

これを達成する方法はありますか?

@andrewvarga現在、コンパイルしたすべてのTypeScriptを、単一のファイルにバンドルしたりコンパイルしたりせずに、ブラウザーで直接実行しています。 これを行う最も簡単な方法は次のとおりです。

  1. TypeScriptファイルのすべてのインポートに.js拡張子が付いていることを確認してください。
  2. 必要に応じて、依存関係のnpmパッケージ名のインポートを解決する開発サーバーを実行します。 es-dev-serverは私が知っている中で最も単純です。
  3. tsc --watchを実行します(tsconfigでモジュールがesnextであることを確認してください)

それでおしまい。 TypeScriptでインポート用の.js拡張機能を作成するだけの場合は、ブラウザー用にファイルを修正するために他のツールは必要ありません。

@justinfagnaniメイト、あなたは最も重要な情報を忘れました-型はjsdoc形式でなければなりません、ネイティブJavaScriptを介したtypescriptの抽象化は、パーサーを失敗させます。

@Draccoz tscは、TypeScriptではなくJavaScriptを出力します。

@andrewvargaバンドルせずにトランスパイルすることを私が知っている最も簡単な方法は、私のプロジェクトZwitterionです。 静的ファイルサーバーの代わりになるように設計されているため、開発方法を変更する必要はありません。 スクリプト要素であっても、明示的なファイル拡張子(JavaScriptの場合は.js、TypeScriptの場合は.ts)を使用してインポートおよびエクスポートできます。 非常にパフォーマンスが高く、ファイルが変更されたときにキャッシュと自動リロードを実行します。 ただし、静的分析(タイプエラー)についてはエディターに依存する必要があります

@andrewvarga https://github.com/Zoltu/typescript-transformer-append-js-extension/を使用し、最新のすべてのブラウザー(Safari、新しいIEを除く)に読み込まれるネイティブESモジュールをターゲットにしています。

ランタイムNPMの依存関係がかなり制限されている場合は、バンドルせずにes-modules-shimを使用してそれらをロードできます。 私が作成したreactテンプレートを見ることができます。これは、これらすべてが連携して機能していることを示しています: https ://github.com/Zoltu/react-es2015-template

@MicahZoltu SafariはESモジュールをサポートしていますが、実際には、caniuseと個人的な経験に基づいています: https ://caniuse.com/#search = modules

@justinfagnani awww申し訳ありませんが、「コンパイルされたTypeScript」の部分を見逃しました。jsdoctypescriptについて話していると思いました。

いろいろなコツをありがとうございました!

私が見つけたのは、webpackにhard-source-webpack-plugin npmモジュールを使用し、ts-loaderオプションでtranspileOnly: trueを使用することで、ビルド時間を約4〜5秒に短縮できることです。
もちろん、これはタイプスクリプトエラーを無視するので、ビルド、ブラウザでの試行、潜在的なエラーをIDEに依存することをすばやく繰り返す場合にのみ役立ちますが、開発中に非常に役立つと思います。

TSエラーと高速コンパイルの両方を取得するには、ブラウザでモジュールを実行するしか方法はないと思いますが、インポートマップとjs拡張機能がサポートされていないため、これは困難でした。
@justinfagnani @MicahZoltuありがとうございます、私はそれらのオプションを試してみます。 一般的に、私はもう1つのnpmモジュールの使用を避けたいと思いますが、それは避けられないようです。

systemjsを使用して動作させようとしましたが、マップのインポートでスタックしました。

@andrewvargaimportmapを使用した私の簡単な例でSystemJを試すことができます。
私の重い例(systemjsとesmの代替)を試すこともできますが、esm importmapsはネイティブではサポートされていないため、モジュールを手動で解決する必要があります(gulp-replace)。またはes-module- shimsを試すことができます。

したがって、 tscを唯一のコンパイラとして使用している場合、モジュールタイプとしてesnextまたはes2015をターゲットにします。 ブラウザで出力を直接使用する方法はありますか?

https://github.com/alshdavid-sandbox/typescript-only-compiler

このスレッドの残りの部分を正しく理解していれば、この行from "./module.js"と言うように変更すれば、Typescriptはコードをコンパイルするのに完全に満足しているはずです。 次に、コンパイルされたindex.jsに有効なES6インポートステートメントが含まれ、すべて機能するはずです。

これは、ESインポートの方法がわからないか、:Pを気にしないライブラリをインポートしない限りです。

ファイルパスをインポートするために.jsを追加するGulpのプラグインを作成しました。 (また、ボーナスtsパス解像度)。

Gulpを使用したのは、基本的に単純な後処理ステップをtscコンパイラー(ウォッチモードと通常モードの両方)にアタッチできる他のタスクランナーがわからないためです。 Webpackとrollupはどちらも排他的にバンドルされており、esモジュールを発行したいと思います。

それは機能しますが、全体を再構築しているように見えるため、見るのが遅いです。

https://github.com/alshdavid-sandbox/typescript-only-compiler/tree/gulp

ノードチームが拡張機能のないインポートに反対することを決定したため、これはますます重要になっています
https://github.com/nodejs/modules/issues/444

拡張機能のないインポートに対しても決定されたインポートマップの追加
https://github.com/WICG/import-maps/issues/194

ブラウザまたはノードでtypescriptコンパイル済みesモジュールを使用する場合は、typescriptによって拡張機能を追加する必要がありますか? (内部モジュールの場合)および外部モジュールの場合は手動ですか? @weswigham

@chyzwarも、TypeScriptソースに.js拡張機能を書き込むだけで、コンパイルされた出力に正しい拡張機能が含まれ、モジュールはブラウザーとノードで機能します。 追加の変換ツールやtscで何かをする必要はありません。

開発者は次のことを行う方が簡単です。TypeScriptソースファイルの場合は、.ts拡張子を記述します。 JavaScriptソースファイルの場合は、.js拡張子を記述します。 また、ブラウザで正しくコンパイルおよび実行されます(.tsにはapplication / javascript MIMEタイプが必要です)。 拡張子はソースファイルの種類と一致する必要があります。 tscおよびESモジュールはそれを処理できます(少なくともブラウザーのESモジュール、できればNode.jsも同じように動作します)

@justinfagnani tscはこれにかなり満足しており、ここで「私たちの問題ではない」と言うのは公正ですが、ここでは何が正しいかについてのコンセンサスがないようです。

tsc、vscode、webpack、ts-nodeの間では、ネイティブで利用できるようになったばかりの標準(現在利用可能なブラウザーとノード)に対して、実際によく一致するものはありません。

例1

最新のjavascriptパッケージを作成し、typescriptで作成し、タイプを削除してecmascriptモジュールとして配布したいと思います(インポートステートメントとエクスポートステートメントを保持します)。

例2

vscodeのモジュールを使用して静的Webサイトを構築しています。デフォルトでは、最初のインポートごとに拡張機能なしで自動インポートされるため、これを手動で調整する必要があります。

このような場合、tscはこれを処理でき、フルタイピングを使用してtypescriptからesモジュールディストリビューションを使用することをサポートする記述子ファイルをエクスポートすることもできます(すばらしい)。

しかし、ソースに対してテストコードを実行したい場合は、ts-nodeを使用できますが、ここではts-nodeは満足できません。

同様に、tsc、vscode、およびwebpackが進化して、次のことを実行するようになりました。

  1. 拡張機能なしのvscode自動インポート
  2. tscは、tsファイルを意味するものとしてjsファイルへのインポートを喜んで書き換えます
  3. webpackは、検索するデフォルトの拡張機能に対してここでさまざまな魔法を実行します

4つの実装(chrome、firefox、safari、node)はすべて、インポートパスがファイルに直接解決できるものを指していることを期待しているので、疑問に思うべきことはすべてありますか。

インポートに.jsを追加することは、決定的な解決策ではなく、一時的な回避策である必要があります。 どちらかといえば、それはハックのように感じます。 コンパイラをだます方法。 そして、コンパイラーを裏切ることを試みることは、私見に従うための恐ろしいイデオロギーです。 Typescriptを初めて使用する人にとって、これがどれほど混乱しているに違いないかを想像することしかできません。 Javascript開発者が_better_コードを書くのに役立つ言語。

すでに述べたように、インポートに.jsを追加すると、TypeScriptがそれらを出力し、すべてが機能します(少なくともコード内で)。 tscがブラウザで機能しないために拡張機能を追加する必要がある理由は、開発者によって引き起こされたランタイムエラーを修正するようにTypeScriptに要求するようなものです-わかりましたが、開発者が自分で修正できないのはなぜですか?
誤解しないでください。tscが私の唯一の開発者依存関係になりたいのですが、いくつかのことが起こらず、夢のままになります。

私はtscが私の唯一の開発者依存関係であることを望んでいますが、いくつかのことが起こらず、夢として残るでしょう。

Typescriptチームからのコメントを含め、#3469に関する数年にわたる数のほぼ同一のコメントを見たに違いありません。 「これはタイプチェッカーです。1つのことをうまく行うはずです。ツールチェーン全体を置き換えることは期待できません...」3年かかりましたが、ビルドモードが追加されました。これは、適切なケースが作成されたためです。進むべき正しい方向。

Webpackとrollupはどちらも排他的にバンドルされており、esモジュールを発行したいと思います。

@alshdavid Rollupは、出力形式をesmに設定し、 preserveModulestrueに設定すると機能する場合があります: https ://rollupjs.org/guide/en/#preservemodules

おそらく「拡張機能のない」インポートは原罪であり、ブラウザの動作方法と互換性がありません

次に、ソースコードを修正し、 .js拡張機能を含めます。今日ソースコードに.js拡張機能を追加すると、すべてが機能します。ブラウザは満足し、typescriptは不可知論者です。バンドラーは気にしません

おそらく、拡張機能がないことがソースコードの欠陥であり、古いツールがそれを補っていたのです。

typescriptソースコードのインポートで.js拡張子を書くことは、まったくナンセンスです。 動作しており、出力の拡張子は保持されますが、VSCodeまたは使用しているエディターのESLintルール(またはTypeScript)の「ファイルを解決できませんでした」エラーで失敗する可能性があります。 そのtypescriptソースコードに対してテストしているときは言うまでもありません。 次に、テストツールはそのでたらめな動作についても知る必要があります。 ファイルを解決できないというエラーがスローされることはほぼ間違いありません。

基本例

src/index.ts
src/foo.ts
test/index.ts

src / foo.ts

export default (a: number) => a + 100;

src / index.ts

// okay, editor (without ESLint) doesn't report error here
import foo from './foo.js';

export default () => {
  console.log(foo(123));
}

test / index.ts

// errm... ts or js ext?! .ts should be the one that make sense
// and that's how the testing too will expect it to be, otherwise will throw
// but then it will detect some weird `.js` ext in the source files...
// which again won't be able to resolve... complete bullshit. 
import main from '../src/index.ts';
import foo from '../src/foo.ts';

test('some boolshit', () => {
  main();
});

test('about foo', () => {
  foo(20);
});

「でたらめ」な使い方で申し訳ありませんが、それは真実です。

コンパイラがインポートで拡張子( .ts )を見つけて、それを.jsに変換する(またはオプションで出力拡張子を指定できるようにする)という基本的なオプションを実装するのはそれほど難しいことではないと思います。なれ)。 拡張機能がない場合は、拡張機能を保持しないでください(半電流動作?)。

typescriptソースコードのインポートで.js拡張子を書くことは完全にナンセンスです。 動作しており、出力の拡張子は保持されますが、VSCodeまたは使用しているエディターのESLintルール(またはTypeScript)の「ファイルを解決できませんでした」エラーで失敗する可能性があります。

これは真実ではありません。 ESLint、TypeScript、VS Code、および私がこのメソッドで使用した他のすべてのTypeScript関連ツールは_ちょうど機能します_。 これはハックではなく、非常に合理的な理由があります。インポートするファイルは実際には.jsファイルであり、インポートされたファイルがローカルの一部であるという理由だけで拡張子が変更されないようにする必要があります。プロジェクト、またはサードパーティパッケージの一部としてプリコンパイルされています。

繰り返しますが、私はすべてのTypeScriptコードをこのように記述し、このスレッドで発生するすべての問題を解決します。 出力は、ブラウザーとノードでうまく機能します。 それはでたらめではありません、それはただ機能します、_今日_。

いいえ、ちがいます。 少なくとも、出力ディレクトリがdistまたはbuildまたはlibなどである最も一般的なケースでは、コンパイルされたファイルは同じディレクトリになく、存在しないだけです。そこに( src/内)-テスト中もエディターでのコーディング中もありません。

上記のsrc/index.ts./foo.jsがある/表示されてインポ​​ートされても、私には意味がありません。もちろん、js / jsonファイルをインポートするつもりなら、まったく問題ありません。 しかし、本当に別のタイプスクリプトソースファイル( ./foo.ts )を意味するときに./foo.jsを書くのは、残酷です。 それは誤解を招き、混乱を招き、間違いなく間違っています。

上記のtest/index.tsをJestで実行すると、 ./foo.tsしかないため、 ./foo.jsを見つけられない/解決できないというエラーで失敗することはほぼ間違いありません。

すべてを脇に置いておくと、 .jsの拡張子は許可されますが、 .ts $の拡張子は許可されないのはなぜですか(tsはエディターでエラーを報告します)。 それは基本的で、単純で、愚かな矛盾です。 TypeScriptの「理由だけで」他の多くの問題。

.js拡張子で終わることが実際に可能であるのに、なぜこの問題がそのように名付けられているのかという論理を実際に失いました。 問題は完全に正反対だと思います- .tsで終わらせることはできません(3.7以降)

なぜ輸入の.ts拡張が完全に禁止されているのですか?!

そして明確にしましょう。 私は開発時間と経験について話している。 コンパイルされた出力で.js拡張子を保持できる理由と、エラーを報告せずに.tsファイルのインポートに.js extを追加できる理由を理解しました。それで大丈夫です。

TypeScriptはJavaScriptのスーパーセットですが、JavaScriptではありません。 JavaScriptはTypeScriptのコンパイルターゲットです。

そのことを念頭に置いて、TSがJSにコンパイルされるという知識にもかかわらず、TypeScriptコードは完全に自己完結型のマナーで動作することを期待します。

.tsファイルをインポートしようとするときに.jsを書き込むと、ターゲットのコンパイルタイプがわかっていることを前提とし、コンパイルターゲットが常にJavaScriptであると想定します。

TypeScriptをWebアセンブリバイナリにコンパイルするか、Denoやts-nodeなどの代替ランタイムを使用してTypeScriptコードを実行するとどうなりますか。

.jsで終わるインポートステートメントは、このようなコンテキストでは意味がありません。

インポートパスに.tsと入力するように強制されるか、TypeScriptソースファイルを想定して拡張子を指定しないでください。

typescriptが、フローのような単なる構文糖衣ではなく、独自の拡張機能を発明したのは悲しいことです。

@phaux異なるフォルダにある場合でも、同じ拡張子でソースファイルとdistファイルが混在するプロジェクトで作業することは絶対にありません。 これは、すべてのファイルindex.jsという名前を付けるようなもので、異なるフォルダにあるファイルだけに名前を付けます...

この問題(TypeScriptよりも大きい)は、Visual Studio CodeのIntelliSenseがWebブラウザーおよびノー​​ドで機能するのをブロックしているようです。これには、インポート指定子に完全な(相対)ファイルパスが必要です。 これがないと、生成されたimportステートメントは、WebPackやTypeScript自体のようなトランスパイラーとバンドラーでのみ機能します。

VSCodeチームの回答は、自動インポートの提案を提供するコードによって拡張機能を追加する必要があるというものでした。 私はそれがTypeScript言語サーバーだと思います(ここで議論されているtscではありません)。

実際に物事を知っている人は、VSCodeがTypeScript言語サーバーから自動インポートの提案を取得することを確認(または修正)できますか?

状況は少し複雑で微妙な違いがあるため、「。js」拡張子は最初は多くの人々のエレガントな直感や理想に反しますが、typescriptが承認されたブラウザ標準や出荷された実装から大きく逸脱することは賢明で混乱する可能性があります

したがって、おそらく現在のパラダイムを次のように考えます。
typescriptインポートは、実行時にインポートされるものを記述します。つまり、インポートは「src」ではなく「dist」ディレクトリで実行されます。たとえば、 fetch呼び出しなどです。このアイデアを許容できる場合、残りは次のようになります。シンプルで一貫性のある

nodeがcommonjsの場合のように、typescriptが拡張子のないインポートに「.js」を盲目的にアタッチすることは確かに悪い考えのようです(ノードesmサポートには今日のtypescriptと同じ方法で「.js」が必要です) –盲目的に「.js」をアタッチします真に拡張子のないjavascriptファイル、またはcssやjsonなどの他のファイルタイプをインポートするなど、新しい問題が発生します。拡張子が意味のあるものになり、特別な解析ロジックが必要になり、ブラウザとtypescriptのセマンティクスに大きな違いが生じます。 fetch呼び出しを同じ方法で書き直すには、おそらくimportは同じままである必要がありますか?

しかし、私は疑問に思います–typescriptが ".ts"拡張子を ".js"に変換することは比較的無害ですか?

もちろん、それでは拡張子が「 .ts 」のjavascriptファイルをインポートできなくなりますが、それは私たちが許容できるファンキーな魔法の1つでしょうか。 一方、これはブラウザとタイプスクリプトのセマンティクスのファンキーで魔法のような特異な違いであり、開発者は学習して理解する必要があります(確かに奇妙なゴッチャを作成します)。したがって、私の本能は、物事を今日の状態のままにすることです。

一方、現状のままにしておくと、魔法は単にtypescriptに再配置され、「。js」インポートを対応する「.ts」ソースファイルに関連付ける必要があります。これは、より合理的な場所のように思えます。ブラウザのセマンティクスを踏みにじる代わりに、typescriptの内部にある魔法を収容する

🥃追跡

@ rconnamacher@ TomasHubelbauer

この問題(TypeScriptよりも大きい)は、Visual Studio CodeのIntelliSenseがWebブラウザーおよびノー​​ドで機能するのをブロックしているようです。これには、インポート指定子に完全な(相対)ファイルパスが必要です。 これがないと、生成されたimportステートメントは、WebPackやTypeScript自体のように、トランスパイラーとバンドラーでのみ機能します。

ここには少し混乱があると思います。今日、vscodeとintellisenseでうまく機能し、ブラウザーとノードで機能し、esmまたはcommonjsで機能するtypescriptライブラリまたはアプリを作成することは非常に可能です。真に普遍的なソリューションが今日可能です。

私はこれを展示するいくつかのオープンライブラリに取り組んできました– renrakucynicredcrypto権威主義

私にメールを送ってください、そして私はもっと説明したいと思います

:wave:チェイス

もう1つのポイントは、アクセスしているファイルが混乱することです。 .js.tsのファイルが並んでいる場合、モジュールの解決後にtscが何を見るかについてはすでにあいまいさがあります。

/folder
  a.ts
  a.js
  index.ts

index.tsの場合、 moduleResolution: 'node'を使用する場合

// points to a.ts
import * as a from './a` 

// points to a.ts
import * as a from './a.js` 

// compiler emits error
import * as a from './a.ts` 

.jsファイルと.tsファイルが並んでいる場合、モジュールの解決後にtscが何を見るかについてはすでにあいまいさがあります。

OK、確かに、ある種ですが、 a.jsa.tsのトランスパイルバージョン以外のものである場合、何かが壊滅的に間違っており、TypeScriptのせいではありません。

@ thw0rted単一のJSバンドルファイルにコンパイルしている場合、TypeScriptは入力TypeScriptファイルに対応するJSを生成せず、単一のバンドルファイルのみを生成します。 その場合、JSファイルと同じ名前のTSファイルがまったく対応していないことは完全に合法です。

それは「違法」ではありませんが、それが良い考えであるという意味ではありません。 実際にこれが必要な場所の具体例はありますか?

バンドラーやローダーを使用せずに、最新のブラウザーで直接使用できるJavaScriptを出力する方法でTypeScriptを使用すると便利です。

例として:
https://github.com/alshdavid/tsc-website

しかし、私は問題の痛みを感じます。 TypeScriptチームは、モジュール解決を実装することを望んでいません。 これは、TypeScriptコンパイラがコンパイル時にpathsを実際の相対パスに変換できないのと同じ理由です。

インポートを.tsから.jsに変換するか、拡張機能なしでインポートに.jsを追加することは、TypeScriptチームがモジュール解決を実装することを意味し、それは範囲外です。

これに対する解決策は、TypeScriptチームが拡張機能を導入する方法を提供して、これらを実装できるようにすることです。

これに対する解決策は、TypeScriptチームが拡張機能を導入する方法を提供して、これらを実装できるようにすることです。

彼らはそうします、それはtscを介して公開されません(コンパイラのプログラムによる呼び出しを介してのみ)。 幸いなことに、誰かがコアコンパイラの周りにラッパーを作成しました。このラッパーは、構成による拡張機能をサポートしていることを除けば、 tscのように_正確に_機能します。 このtscラッパーを使用すると、 https://github.com/Zoltu/typescript-transformer-append-js-extension/などの拡張機能を使用して、 .js拡張機能を自動追加できます。

@alshdavid GitHubの例は、インポートに.js拡張子を含めるだけで、バンドラーのないブラウザーで機能します。 私はそれを修正するためにPRを提出しました。

@alshdavid私のサンプルプロジェクト(SystemJSを使用したモダンおよびIE11のesm)に興味があるかもしれません。
しかし、私はesmモジュールを手動で解決することを余儀なくされています=(

原則として、すべてのimport.jsを入れても問題はありませんが、残念ながら、一部のツールとのやり取りが不十分になります。 たとえば、ts-nodeチョーク: https://github.com/TypeStrong/ts-node/issues/783。 これが誰の責任であるかについて明確な合意はないようです-TypeScriptが.js拡張機能(状況によっては)を発行するか、TypeScriptソースを使用して翻訳を行うすべてのツール。 そして、誰もがお金を払っている限り、ユーザーは、相互運用性の非互換性を回避するために、十分に文書化されていないプラグインや厄介なサービスワーカーに苦しんでいます。

これに関する更新はありますか? 正直なところ、外部モジュールローダーやWebpackのようなバンドラーがなければ、TypeScriptを通常どおりに使用することは不可能だとは信じられませ。 これはとても奇妙で、私にとっても苛立たしいことのようです。 TypeScriptを完全に機能させるために外部モジュールを使用する必要ある場合は、それを開始する必要があります。

私はこれをElectronアプリで使用しようとしています。そのため、Webバンドラーを使用する理由がわかりません。また、必要がない場合は外部モジュールローダーをインストールしたくありません。 しかし、これは私を怒らせています。 基本的なTypeScript + Electronのセットアップを実行することさえできませんが、どちらもそこにある最良のソリューションであるとどこでも賞賛されています。 正直言って、それはクレイジーです。 何かが足りないのかどうかはわかりませんが、適切な解決策を見つけることができないのはイライラするだけではありません。

そして、それが本当に私ではない場合、なぜこの問題が3年間修正されなかったのか理解できません...

私は最近typescriptチュートリアルを完了し、それからいくつかのtsファイルを作成しようとしたときにこの問題に遭遇しました。 私はこのjs-tsの世界にまったく慣れていないので、何かが間違っていたり、誤解を招いたり、誤った情報を与えられたりした場合は、ご容赦ください。

私がしたことは、インポート中に

tsファイルに.js拡張子を付けるだけで、インテリセンスを確認すると、tscを使用してトランスパイルしたときにも機能し、生成された出力ファイルに.js拡張子も追加されました。

以下は私がしたことです。
tsc -p tsconfig.json

{{
"compilerOptions":{
// "モジュール": "amd"、
"モジュール": "es6"、
"ターゲット": "es6"、
"noImplicitAny":false、
"removeComments":true、
"preserveConstEnums":false、
// "outFile": "js"、
"outDir": "js"、
"sourceMap":false
}、
"含む": [
「testscript.ts」
]
}

それは私のために働いたが。

私の疑問は、インポート元のsvgwrapper.jsがないためです。
なぜ/どのように機能しましたか? (拡張は考慮されていないと思います)

参考までにスクリーンショットを添付します。

ts-js-ext-issue

@yogeshjogこれはまさにtscがどのように機能するかであり、機能するはずです。 生成されるファイル名でモジュールをインポートします。 インポートされたモジュールが元々 .tsファイルとして書き込まれたか.d.ts / .jsペアとして書き込まれたかは、インポートするモジュールからは観察できません。

@yogeshjogこれはまさにtscがどのように機能するかであり、機能するはずです。 生成されるファイル名でモジュールをインポートします。 インポートされたモジュールが元々 .tsファイルとして書き込まれたか.d.ts / .jsペアとして書き込まれたかは、インポートするモジュールからは観察できません。

ありがとう! 明確化のための@justinfagnani👍

生成されるファイル名でモジュールをインポートします。

ただし、TypeScriptでは拡張子を省略できますが、ECMAScriptでは許可されていません。 VSCodeで自動インポート機能を使用する場合、最も厄介な拡張機能も省略されます。 あなたはいくつかのJSを書き、TSはそれが大丈夫だと言って、それからそれは実行時にクラッシュします。

ただし、TypeScriptでは拡張子を省略できます

ノード解決を使用する場合。 tsconfigは、少なくともこれについて警告する他の解決モードを許可するように設定されていますが、チームは、モードを追加する前に、ネイティブモジュールのサポートを解決させていると理解しています。

ECMAScriptでは許可されていません。

ECMAScriptは、インポート指定子については何も述べていません。 これは、HTMLやNodeなどのホスト環境に任されています。 TypeScriptは、モジュールをロードするときにノード解決をサポートし、コンパイラ_input_ではなくコンパイラ_output_に対して解決を解釈します。 このように、指定子はコンパイル後に機能し、コンパイルされたモジュールをインポートしようとしているかどうかに関係なく機能します。

TypeScriptはパス検索を実行して'./foo' info './foo.js'を変換するノード解決を使用するため、 './foo'は有効です。 ただし、ノード解決は'./foo.ts''./foo.js' $に変換しないため、 './foo.ts'は無効です。

しかし、それはノードの解像度の範囲内です。 HTMLやノードのネイティブモジュールサポートなどの別の環境を使用しようとしている場合、TypeScriptとホストは何が有効かについて意見が一致しません。

うまくいけば、ネイティブモジュールのサポートが十分に解決され、TypeScriptが別の解像度設定を追加できるようになります。

@leontepeバンドラー/ローダーは必要ありません。 https://github.com/Zoltu/typescript-transformer-append-js-extension/ (私の好みのソリューション)を使用するか、すべてのインポートステートメントに.jsを追加することができます(注意:これはコードをts-nodeで失敗させます)。

@leontepeバンドラー/ローダーは必要ありません。 https://github.com/Zoltu/typescript-transformer-append-js-extension/ (私の好みのソリューション)を使用するか、すべてのインポートステートメントに.jsを追加することができます(注意:これはコードをts-nodeで失敗させます)。

@MicahZoltuええと、ありがとうございますが、それでも「箱から出して」機能するだけではないことに少しイライラします。 @phauxが言ったように、VSCodeはユーザーに拡張機能なしでインポートステートメントを作成することを提案しており、それは実行時に機能しません。 私はここでTypeScriptチームの能力に真剣に疑問を投げかけています。さもないと、この間ずっと何か問題があり、まったく愚かです。 しかし、誰が知っていますか...

編集:この時点でJavaScript + Babel用のTypeScriptを削除することを真剣に検討しています。

私はElectronアプリケーションを作成していませんが、ノードスタイルの解決を行う可能性はありますか?ここでは、固定された順序でいくつかのことを試行するインポートを解決しようとするアルゴリズムがありますか? すべてのソースがローカルリソースからロードされていることを考えると、問題ないようです...

たぶん、TSに新しいモジュール解像度を追加する時が来ましたか? Node.jsは現在ネイティブESMをサポートしていますが、相対パスに明示的な拡張機能がないと、 --experimental-specifier-resolution=nodeフラグを使用する必要があります。これはちょっと面倒です。 Denoとブラウザもあります。 理想的には、次のようなものがあるはずです。
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

次にTypescript:

import foo from './foo.ts'; // no ts(2691) here

Javascriptにコンパイルします:

import foo from './foo.js';

「厳密」:trueは多くの作業を意味します!
2020年、まだ修正されていない、ばかげている。

この問題が私たちのチームもブロックしていると言ってチャイムを鳴らしてください😢

ネイティブモジュールにビルドされ、ノードやwebpackで使用できる単一のソースを使用できるようにしたいと考えています。 TSコードのインポートに手動で.jsを挿入すると、Webpackに問題があるようです。 ただし、インポートに.tsファイル拡張子を付けると、webpackを機能させることができますが、もちろんtypescriptは文句を言います。 ファイル拡張子がないと、ネイティブモジュールがなくなります。 したがって、ブラウザとバンドラーを満足させる組み合わせはないようです。 インポートで.tsを記述し、それを出力で.jsにすることができれば、問題は解決されると思います(そして、deno compatも取得します)。 @ evg656eのようなものは、それが機能するはずだと示唆しています。

@EisenbergEffectこれについてWebPackに対して提出されたバグはありますか? WebPackの問題が通常のtscから逸脱しているように聞こえます。

@justinfagnani問題がwebpak、ts-loader、または他の場所にあるかどうかはわかりません。 最適なビルドセットアップを導入するために多くの時間を費やしましたが、すべてのチェックボックスをオンにしたソリューションは見つかりませんでした。 カスタムトランスフォーマーやビルド後の手順でそれを行う方法はおそらくありますが、ダウンストリームの開発者に悪影響を与える可能性があるため、非標準のセットアップを採用することには消極的です。

@EisenbergEffect WebPackのTypeScriptローダーでtscのように$ .js拡張子を介してTypeScriptファイルをインポートできない場合は、バグです。 あなたが言ったように、この振る舞いはWebPackとtscで同じソースをビルドすることを妨げます。

たぶん、TSに新しいモジュール解像度を追加する時が来ましたか? Node.jsは現在ネイティブESMをサポートしていますが、相対パスに明示的な拡張機能がないと、 --experimental-specifier-resolution=nodeフラグを使用する必要があります。これはちょっと面倒です。 Denoとブラウザもあります。 理想的には、次のようなものがあるはずです。
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

次にTypescript:

import foo from './foo.ts'; // no ts(2691) here

Javascriptにコンパイルします:

import foo from './foo.js';

人々(たとえば、私)は、Node.js、Deno、およびWeb間で同時に1つのコードを機能させたいと考えています。 これはTypeScript / JavaScriptプログラミングにとって素晴らしいマイルストーンになると思います。

vscodeを使用していて暫定的な解決策が必要な場合は、これをsettings.jsonに追加すると、問題が解決するようです。

"typescript.preferences.importModuleSpecifierEnding": "js"

インポートパスに.jsを追加します(これにより、src内の*.tsファイルがエラーなしで解決されますが、トランスパイル時に.jsが保持されます)。 バンドラーなしでtscを使用する場合に便利です。

tscソリューションを待つ間、これに対するローテク修正は次のようになります。

  1. すべてのソースファイルを一時フォルダにコピーします
  2. ビルドする前に、インポートとエクスポートの拡張機能を削除します

他の人が使用できる場合に備えて、このワンライナーを共有したいと思いました。 src /フォルダーをtmp /にコピーし、そこでファイルを変更します。

npx shx cp -r ./src/ ./tmp/ && npx rexreplace "(^§s*?(?:import|export).*?from§s+?(['\"]).*?)§.ts§2" €1€2 './tmp/**/*.{ts,js,tsx,jsx}'

package.jsonのビルドスクリプトの一部として( yarn add --dev shx rexreplaceを実行した後)、次のようになります。

"scripts":{
  "build": "yarn build-esm && yarn build-tsc",
  "buil-esm": "...Whatever you normally do...",
  "build-tsc": "shx mkdir -p tmp && shx cp -r ./src/* ./tmp && rexreplace \"(^§s*?(?:import|export).*?from§s+?(['\\\"]).*?)§.ts§2\" €1€2 './tmp/**/*.{ts,js,tsx,jsx}' && tsc src/index.ts && shx rm -r ./tmp"
}

私は現在、Jestを満足させるために、TypeScriptソースのインポートパスから.jsをオフにしています。
次に、 .jsを追加する後処理ステップがあります。
この方法では、ソースマップはサポートされていません。

tsc -b tsconfig-solution.json -w --listEmittedFiles \
  | node mk/build-post.js

build-post.js後処理スクリプトは次のことを行います。

.jsimportexportの相対パスに追加します

例えば、

export { X } from "./first";
import { Y } from "./second";

になります

export { X } from "./first.js";
import { Y } from "./second.js";

私はどこでもindex.tsを使用しないことに注意してください。代わりに、Denoの規則に従ってmod.tsを使用します。 したがって、 /index.jsを追加する場合を考慮する必要はありません。

CommonJSパッケージのimportrequireに変更します

私のコードは、モジュールモードでノード^ 12.17と^ 14.1で実行されます。 ESモジュールのみを公開しています。
ただし、多くの依存関係では、 "main"フィールドにCommonJSがあります。
したがって、NodeJS組み込みモジュールを除いて、これらをCommonJSに変更する必要があります。

例えば、

import { Server as WsServer } from "ws";

になります

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { __importDefault } = require("tslib");

const { Server: WsServer } = require("ws");

しかし、webpackはこれらのrequireに不満を持っているので、次を使用する必要があります。

/// #if false
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { __importDefault } = require("tslib");
/// #endif

/// #if false
const { Server: WsServer } = require("ws");
/*
/// #else
import { Server as WsServer } from "ws";
/// #endif
/// #if false
*/
/// #endif

webpackでは、プロジェクトをインポートするパッケージでifdef-loaderを使用する必要があります。そうすると、webpackは元のimport行を認識します。

私たちもこれに見舞われており、報告されてから3年後にこれがどのように修正されないのか理解できません。
WebStormを使用しているため、VSCode固有の設定は機能しません。
別のスクリプトを使用して出力を修正するのはばかげています。
これは、サードパーティのツールを使用しなくても機能するはずです。

+1

これは、asp.net core 3.1 Webサイトを使用した私の回避策です(おそらく、より低いバージョンで動作します)
startup.csの場合:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            var rewriteOptions = new RewriteOptions();
            rewriteOptions.AddRewrite(@"^js/(.+)", "js/$1.js", skipRemainingRules: true);

            app.UseRewriter(rewriteOptions);

            app.UseStaticFiles();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }

書き換えミドルウェアは、フォルダー/ jsを対象とするすべてのリクエストに拡張子「.js」を追加します。
警告:ここではミドルウェアの順序が重要です。UseStaticFilesはUseRewriterの後に配置する必要があります。そうしないと、機能しません。

ここにいるみんなと同じように、私は箱から出してすぐに解決策を好むでしょうが、それまでは...

たぶん、TSに新しいモジュール解像度を追加する時が来ましたか? Node.jsは現在ネイティブESMをサポートしていますが、相対パスに明示的な拡張機能がないと、 --experimental-specifier-resolution=nodeフラグを使用する必要があります。これはちょっと面倒です。 Denoとブラウザもあります。 理想的には、次のようなものがあるはずです。
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

次にTypescript:

import foo from './foo.ts'; // no ts(2691) here

Javascriptにコンパイルします:

import foo from './foo.js';

eslint-plugin-nodenode/file-extension-in-importルールをlinting configに設定し、インポートステートメントに拡張機能を手動で追加し(その方が良いため)、TypeScriptで"moduleResolution": "node"を追加しました。 configと私が見ることができるのはts(2691)だけです。

うまくいけば、 @ evg656eが言ったことを実装する価値があるかもしれません。

これがまだ問題だとは信じられません。

使用する場合
"baseUrl": ".", "paths": { "/*": ["./*"] },

次のようにabsoulteモジュールのインポートを行うことができます。
`インポートwsfrom" / hey / connection ";

しかし、「。js」拡張子を追加すると、突然、コンパイラはconnection.ts宣言を検出できなくなり、次のように表示されます。

Could not find a declaration file for module '/hey/connection'. '/home/tobi/Documents/JITcom/Code/Libs/Test_Browser/hey/connection.js' implicitly has an 'any' type.

相対パスを使用すると、すべて正常に機能します。

これを修正してください

私もこれを修正したいと思っています。

ありがとう。

これがまだ問題であるのはばかげています! :00

私はついにTypeScriptに切り替えることにしました。これは、私が最初に遭遇した問題の1つでした。 それはNodeのネイティブ実装のモジュール解決を破ります、そして私は拡張子なしで名前を受け入れるのにより柔軟であるように思われるesmパッケージを使用するか、(奇妙なことに)インポートパスで.js拡張子を使用することによってのみそれを回避することができましたインポートが.tsまたは.tsxファイルを参照している場合でも、.tsファイル内。 TypeScriptコンパイラがそれを受け入れる理由はわかりませんが、少なくともビルド出力には.js拡張子が含まれています。 しかし、ひどくハッキーなソリューション。

最近はクライアントサイドでtypescriptをあまり使用しておらず、コードの品質にあまり影響を与えず、作業が簡単になりました。 おそらくJavaScriptには1ポイントのオプション型があり、この問題はもう問題ではありません。

JestとWebpackを満足させるために、インポート行の拡張機能は省略しています。
コンパイルするとき、 tsc --listEmittedFilesを呼び出し、出力を後処理スクリプトにパイプします。 このスクリプトは.js拡張機能を追加して、ノード(モジュールモード)を幸せにします。
https://github.com/yoursunny/NDNts/blob/fa6b2eb68a9f32a6a2e24e5475275f803236b8f8/mk/build-post.js

@kj

(奇妙なことに)インポートが.tsまたは.tsxファイルを参照している場合でも、.tsファイル内のインポートパスで.js拡張子を使用します。 TypeScriptコンパイラがそれを受け入れる理由はわかりませんが、少なくともビルド出力には.js拡張子が含まれています。 しかし、ひどくハッキーなソリューション。

それは奇妙ではなく、間違いなくハッキーではなく、ブラウザとノードのネイティブモジュールの解決で完全に機能します。

インポートするリソースは、.jsファイルです。 タイプは、.tsファイルまたは.d.tsファイルのいずれかになります。 .d.tsファイルは.jsモジュールの兄弟である必要はなく、.d.tsファイルと.jsファイルの間に1対1の関係がある必要もありません。

.jsモジュールのインポートは、tscが選択できた最も信頼性が高く安定したオプションです。 そうしないと、型をインポートして、tscがそれらを実際のモジュールパスに書き換える正しい方法を知らない場合があります。

@justinfagnaniああ、それは理にかなっていると思います。 私は、TypeScriptがここで行っていることがハッキーであることを意味するのではなく(私はそのような主張をする立場にありません)、私が行っていることは典型的ではないかもしれないと感じただけです。 私はそれを間違った方法で考えていたと思います。 モジュールをインポートするのはTypeScriptではなく、ビルド出力を評価するものです(または私は誤解していますか)? その場合、なぜこのように機能するのかがわかります。

インポートするリソースは、.jsファイルです。

ここで構築されたモジュールを参照していますか? ソースディレクトリの.jsファイルではなく、ビルドバージョンの.tsモジュールですか?

モジュールパスで拡張子.tsまたは.tsxを明示的に指定した場合、出力が.jsに置き換わるということではないでしょうか。

@kjで何が起こっているのか誤解されているのではないかと思います。 コードをコンパイルせずに.ts拡張子を指定すると、tsファイルを参照します。 ただし、tscを使用してコンパイルすると、tsファイルの内容が現在の環境(ノードまたはブラウザー)で実行可能なjsファイルに変換されます。

@ mkay581であることは理解していますが、foo.tsファイルに次の行があると言います。

import { Component } from './Component.js';

私が参照している「Component.js」は、実際にはファイルシステム上の「Component.tsx」です(TypeScriptがファイルの最終的なトランスパイルバージョンを参照していると理解していない限り、.jsファイルはありませんか?)。 TypeScriptはこれを問題なく受け入れ、同じインポート行が出力に表示されます(.js拡張子はNodeまたはブラウザーで機能します)。

従来のTypeScriptの方法(AFAIK)は、拡張子なしでそのインポート行を次のように指定することでした。

import { Component } from './Component';

トランスパイルされた.jsファイルのインポート行に「./Component」の.js拡張子が含まれていないことを除いて、これも明らかに正常にコンパイルされます。これは、特定の環境で必要です(私はまだ仕様のように聞こえますが、必ず読んでください)。

一方、ソースファイルの実際のファイル名で行を指定すると、次のようになります。

import { Component } from './Component.tsx';

次に、TypeScriptはパスを認識せず、ファイル拡張子なしでインポート行を試す必要があることを提案します(思い出すと、今はコンピューターにいません)。

したがって、最初の例は少し奇妙に感じます。TypeScriptを書いているので、.tsまたは.tsx拡張子を付けてインポートできると期待していますが、拡張子のないパスのみを受け入れます( ESモジュールシステムの他の実装とは相容れません)または.js拡張子は、そのようなソースファイルがないため、出力ファイルのみを参照できます。

@justinfagnani

インポートするリソースは、.jsファイルです。

tscがどのように機能するかはわかりませんが、それは私には正しく聞こえません。 コードを書くとき、まだ.jsファイルはありません。 それを作成するのはコンパイラの仕事です。

TSはJSの上にある抽象化レイヤーとして機能し、.jsファイルはコンパイルステップの出力です。 それらがその特定の拡張機能でそこにあることを期待することは、抽象化、IMOを壊すようです。

言い換えると、CまたはC ++を使用している場合、コードに#include .oファイルを含めない場合は、 .hまたは多くても.cを含めます。 .cpp

Typescriptでのこの動作についての合理的な説明を喜んで受け入れますが、何かが足りない場合を除いて、これはそうではないようです。

@kj

それは奇妙ではなく、間違いなくハッキーではありません

まったくそう思わない。 私にとって、それは奇妙でハッキーな定義そのものです。 😛ここで行っているのは、架空のファイルを参照していることです。 存在が保証されていないファイル。 (たとえば、コードをバンドルする場合、AssemblyScriptを使用する場合、またはdenoを使用する場合)出力形式を想定しています。 しかし、不可知論的なコード(サードパーティのモジュールなど)を作成する場合、それは_危険_なことです。

@borfast @frziはい、それは基本的に私がそれについて感じた方法です、そして私はこれに満足していないのは私だけではないのを見てうれしいです。 私はTypeScriptにあまりにも新しい仮定をしすぎないようにしようとしています!

@frzi

ここで行っているのは、架空のファイルを参照することです。 存在が保証されていないファイル

仮説ではありませんが、tscはそれを生成することを知っています。 tscを使用する場合、存在することが保証されます。

別の見方をすれば、.tsファイルをインポートすると、コンパイル後に存在しないファイルをインポートすることになります。

コードをバンドルするとき

バンドラーはtscの後に実行されます

@kjは.tsxファイルについて言及しました、そしてそれらは私のポイントをさらに家に追いやる。 .tsxは、そのモジュールのコンパイラに_locally_、モジュールにJSXが含まれていることを通知するためにのみ存在します。 モジュールのインポーターは、ファイルにJSXが含まれていることを知る必要はなく、コンパイル後にはわかりません。 ファイルは、.tsx、.ts、および.js /.d.tsのペア間でシームレスに移植できます。

.tsファイルをインポートするとします。

import {Component} from './component.ts';

次に、コンポーネントにJSXを使用するため、名前をcomponent.tsxに変更します。 すべてのインポートが失敗する必要がありますか? .tsから.js / .d.tsに移行するとしますが、インポートは再び失敗する必要がありますか?

@borfast

TSはJSの上にある抽象化レイヤーとして機能し、.jsファイルはコンパイルステップの出力です。 それらがその特定の拡張機能でそこにあることを期待することは、抽象化、IMOを壊すようです。

抽象化は、ここで示唆するほど完全ではありません。 TSプロジェクトの内部または外部から.jsファイルをインポートできます。 プロジェクト内のどこにでも存在する.d.tsファイルを使用して.jsファイルにタイプを追加できます。 .jsファイルは、コンパイル後の実際のファイルです。 他のすべてはコンパイラを支援するだけです。

@justinfagnani私はあなたが言っていることに少し迷っていますが、なぜTypeScriptは、.tsまたは.tsxを使用してインポートパスを指定すると、そのモジュールの.jsファイルが生成されると想定できないのですか?したがって、出力で後者の拡張子を置き換える必要がありますか?

@justinfagnani

仮説ではありませんが、tscはそれを生成することを_知っています_。 tscを使用する場合、存在することが保証されます。

しかし、ここにはあなたが認めていない対称性があります。

あなたが言及するこの「保証」は、両方の方法を保持します。 あなたが言うように、「tsc _knows_それが[jsファイル]を生成する」場合、それは同様に有効な質問です:「それでは、なぜtscはこの保証に基づいて行動せず、_knows_である.js拡張子を適用するのですか?コンパイルされたjsにありませんか?」

「tscがjsファイルを保証する」という事実の解釈は双方向です。

だから私は同意します、 @ justinfagnani 、あなたの解釈は特定の観点から有効です。 しかし、反対の解釈は、「したがって、tscは_その知識に基づいて行動し_、開発者のためにこのプロセスを実行する必要がある」というものです。 そして、最初からこの議論全体について私を悩ませているのは、この解釈がどのように「否定的に」受け取られているかということです。 それは無理です。

結局のところ、この議論は_論理的な決定ではなく、審美的な決定_に関するものです。 そして、私の希望は、美的_意見_(論理的推論ではない)にふさわしい、増幅的で融通の利く声のトーンが、その批判者によってこの問題に影響を与えることです。

要するに、OPの質問は完全に有効な解釈であると認めてください—おそらくあなた自身の質問と一緒に。 厳しい議論の必要はありません。

ありがとう

@justinfagnani

別の見方をすれば、.tsファイルをインポートすると、コンパイル後に存在しないファイルをインポートすることになります。

もちろん、 .hファイルがCプログラムの実行可能ファイルとともに配布されないように、そうではありません。 それがまさにポイントです。コンパイルされたファイルではなく、ソースファイルを含めるようにコンパイラに指示します。

わかりました、私はこの会話でスパムになりすぎて、それをさらに無視することができません。
importステートメントはtypescriptの一部ではなく、それを実行したJavaScript環境の一部です。 さて、ここでのキーワードはJavaScript環境です。これが、パスを解決するものだからです。 ランタイムで.tsファイルをインポートして実行する単一のアプリを見せてください(確かに、いくつかあるかもしれませんが、それらは私がハッキーと呼ぶものです)。
TypeScriptでは、ソースファイル内でネイティブJavaScriptを使用できるため、 .js拡張機能を追加できます。 node.jsのブラウザはどちらも.tsファイルを実行せず、 ts-nodeでも.tsファイルをその場でトランスパイルし、結果をハードドライブに書き留めるのではなく、メモリに保持します(ハッキーではありません)。 ?)。

ここで、適切なtsc修正は次のようになります。

  • .tsファイルがあります
  • 別のファイルで参照します
  • tscは、その.tsファイルを.jsファイルに変換します
  • 次に、tscは.ts .jsファイルで書き換えます(それがどのようにトランスパイルされたかを正確に知っているので、正しく更新できます)

問題:「最新のWeb開発」は実際のWeb開発ではなく、node.jsの方法でインポートし、拡張子(およびファイルパス全体)をスキップします。 tscは出力がどうなるかを認識しなくなりました。 my-awesome-module/testをインポートするcozは、 node-modules/my-awesome-moduleのファイルtest.jsから始まり、 index.jsファイルまで何でもかまいません。 node-modules/my-awesome-moduletestフォルダー内で、$ ./local-mocks/my-awesome-module/mock.jsonなどの非jsファイルを使用したローカルリライトで終了します。

ここで問題が発生します。tscは、特定のプロジェクトのファンキーなwebpack / rollup / super-awesome-new-and-shiny-bundler構成をどのように知ることができますか?

繰り返しますが、私はtscがインポートパスを書き直すことに全力を注いでいますが、それは単純なプロジェクトでのみ機能し、単純なプロジェクトでのみ機能するようにします(単純なプレゼンテーションページでも、過剰に設計されたwebpack構成と反応するため、少数派です)。簡単なカスタムスクリプトで実行できる場合は、時間を費やします。

繰り返しますが、私はtscがインポートパスを書き直すことに全力を注いでいますが、それは単純なプロジェクトでのみ機能し、単純なプロジェクトでのみ機能するようにします(単純なプレゼンテーションページでも、過剰に設計されたwebpack構成と反応するため、少数派です)。簡単なカスタムスクリプトで実行できる場合は、時間を費やします。

Webpackを使用せず、tscを使用するだけの単純なプロジェクトで、どのように実行しますか?

私はみんなのコメントを読んでいますが、ここでのタイプスクリプトの使用に対する期待の根本的な不一致のようです。

.tsソースファイルが.jsファイルを参照している場合、問題はすでに始まっています。

Typescriptは、.jsファイルではなくソース.tsファイルを〜実行〜コンパイルするために構築されました。 開発者がプロ​​ジェクトでTypeScriptを使用したい場合は、_entire_プロジェクトをtypescriptに変換し、孤立した.jsファイルを残さずにそれらを参照する必要があります。 また、jsファイルの内容をTypescript構文に変更する時間がない場合は、jsファイルの名前をtsファイルに変更するだけです(またはTSのパスマッピングを使用してインポートを.jsファイルにマップします)。 問題が解決しました。 :man_shrugging:

編集:「実行」を「コンパイル」に修正しました。これは私が意味したことですが、それがどのように異なって解釈されたかを見ることができます。

@ mkay581 TypeScriptは、JSファイルを出力するためだけに、何かを実行することを意図したものではありませんでした。

@valeriob Simpleプロジェクトには、バンドルする必要のないファイルがせいぜい数個しかありません。 最近のブラウザにはインポートが組み込まれているので、それを回避する必要はありません。 次に、ブラウザでナビゲーションイベントをリッスンし、各イベントを一致するルートにマッピングするのと同じくらい簡単です。各ルートfetchでデータをインポートし、返された後はコンパイルされていないテンプレートエンジン(lit- html、HyperHTML、またはMustache、Handlebars、Pugなどの古いもの)。 完了しました。Webpack、フレームワーク、またはユーティリティライブラリを作成する必要はありません。リスナー、正規表現、フェッチ、Promise、シンプルなjsテンプレートエンジンも必要ありません。

@Draccozに感謝します。この単純なシナリオを機能させる方法を教えていただけますか? https://github.com/valeriob/Typescript_Non_SPA
これは、JSライブラリ(例としてrxjs)を参照する単純な.tsファイルであり、htmlページのモジュールとして使用したいと思います。

@valeriobこれは本来あるべきほど些細なことではありません。 サードパーティのライブラリのほとんどは、ESモジュールと互換性があると宣言していても、ブラウザの世界にはありません。
RxJSは、ネイティブフローに移行するときに私が最も興味を持っていたものですが、このチケットが解決されるのを待ってから、自分で実装することを決定します(面白い...)。
私が設計していたアーキテクチャでは、最初はsedを使用してすべてのインポートを修正しましたが、その後、パスを書き換える単純な開発サーバーを使用するようになりました。 私のコンセプトは、rxjs、typescript、lit-html(4つのフォルダーを持つnode_modulesと超高速CIテスト/ビルド)を除いて、アプリに外部依存関係を持たないことです。 TSがパスを書き直した場合、とにかく約90行のコードですが、サーバーが不要になります。 これはオープンソースです。リンクが必要な場合は、プロフィールの組織に質問するか確認してください。

単純なページに関しては、URLを押す->データをフェッチする->表示する->繰り返すなど、実際にはライブラリを必要としないページを参照していました。

Jsにはベースライブラリがないため、Jsでライブラリを使用する必要がないのは純粋なファンタジーです。

単純なシナリオは私がリンクしたシナリオであり、機能していません。 また、これはpplの最も一般的なシナリオであり、クレイジーなWebpack /コンパイルの世界に飛び込みたくないので、実際のメリットがなく複雑になり、オプションが大幅に制限され、開発者がアプリを作成するよりもツールと戦うようになり、開発者の速度が低下します。ループ。

この問題が存在し、多くの開発者の生産性にとって重要な懸念事項であることを否定するために、ここで行われている多くの精神体操。

それが_問題であってはならない_と説明しても、_問題は解決されません_。 ソフトウェアは、ユーザーに独自の実装モデルを課すのではなく、ユーザーのメンタルモデルに準拠する必要があります。 (UXのもの)

@borfastのように、ユーザーがtscをCのようなコンパイラとして概念化している場合、 tscの実装の詳細に関係なく、これに対応する必要がある特権メンタルモードです。

OPの質問には、レポの他のすべての問題よりも多く、200以上の賛成があります。

この問題はコミュニティの投票に値します。 投票を開始することを検討してください。

ほとんどのユーザーがtscにインポートを書き直したい場合は、それが正しい答えです。 少なくとも、それは物事を見るUXの方法です。

それよりもさらに簡単です。言語としてのtypescriptがJavaScriptのスーパーセットである場合、tscの出力(単一の出力ファイルスイッチでなくても)はJavaScript自体で消化できるはずです。

@weoreferenceは、複数の環境(node.js、ブラウザー)、複数のバンドラー構成の可能性( webpack、rollup、parcel、その他のバンドラー)確かに、TypeScriptチームはあなたの側でいっぱいになると思います。

あなたがそうする気がないか、それが難しすぎると思うなら、誰も実際に説明できない機能を作成するように彼らに頼むのをやめてください。

@Draccoz 、あなたはあなたの車が10 Km / hより速くそれを運転できるようにギアをシフトしたいのですが、ギアトレインがどのように機能するかを学ぶようにメーカーから頼まれたことはないと確信しています。

バンドラーなどの問題に関しては、なぜそれがこれを妨げるのですか?

ほら、私はESモジュールを使いたいだけで、BabelとWebpackの狂気のすべてに対処したくはありません。 なぜこれは、ファイル拡張子を.jsに変更するだけのオプションのコンパイラオプションではないのですか? この動作がユーザーが設定した他の構成オプションと競合する場合は、自動的に無効にするか、警告/エラーを表示してtscの実行時にコンパイルを停止し、ユーザーが構成を変更する必要があることを認識できるようにする必要があります。

なぜこれが不可能なのか、私にはよくわかりません。

@Draccozこんにちは:)まあ、私が見るように、あなたは2つのことを求めています:

  1. 実装方法

  2. 開発者である私が、特定の環境でインポートの名前を特定の方法で変更することをtscに通知する方法

これが私の考えです。

  1. @borfastの返信をご覧ください。 それは「高次」の答えですが、簡潔です:)

  2. たぶん、「renameImports」:trueなどのフラグをtsc / tsconfigに渡すか、tscによって取得されるその他のシグナルを渡すことができます。 より高い精度が必要な場合は、フラグをブール値にするのではなく、次のような文字列を使用する必要があります。

standardImportExtension: 'js'

したがって、ファイル拡張子のないすべてのインポートはデフォルトで.jsになります

結論:
この機能は、Q2(インポート名前変更スキーム)がQ1(つまり、tsc)によって事前に認識されている必要があると想定しているため、実装が難しいように思われます。 しかし、実際にはありません。 人間の開発者である私は、webpack /ブラウザなどがどのように機能するかを知らなくても、この「世界の知識」をtscに簡単に提供できます。 これはすべて単純なフラグで行われます。

@borfast Transmissionはユーザーからの質問ではなく、メーカーから車が提供されました。ユーザーはこれが新機能であることに同意し、使用を開始しました。申し訳ありませんが、これは適切な議論ではありません。 ユーザー-あなたの自動車メーカーの例と比較すると、「私の車は、10万マイルの範囲とジェットの最高速度到達速度を備えた完全な電気自動車になりたいです。それを達成する方法は気にしません。それだけです-期間。
@weoreferenceは私の質問で少し誤解しています。 私は質問していました:パスが何を指しているのかをtscに理解させる方法は? 直接jsファイルですか? それとも、中にindex.tsが入っているフォルダですか? それとも、 mainフィールドを保持するpackage.jsonを持つモジュールですか? またはesnextフィールド? または、非標準である他のものはありますか? それとも、webpackによって書き直されたパスですか? またはロールアップ? もしそうなら、設定はどこにありますか? 多分それは別のバンドラーですか? あまり知られていない? そして、上記の文で私が考えていなかった他のユースケースは何ですか?

たぶん、「renameImports」:trueなどのフラグをtsc / tsconfigに渡すか、tscによって取得されるその他のシグナルを渡すことができます。

@weoreferenceは、パスマッピングでこれをまだ実行できませんか? TSconfigファイルのpathsオプションを使用すると、インポートパスをJSファイルにマップするためのコントロールが提供されます。 通訳を間違えたらごめんなさい。

@Draccoz返信ありがとうございます、はっきりさせてください

そして、上記の文で私が考えていなかった他のユースケースは何ですか?

そうです、tscがこれらすべての環境/ビルドツールの組み合わせについての知識を持つことは非常に難しいでしょう。

しかし、tscには、開発者が_ほとんどの_ユースケースをカバーするのに役立つ単純なユーティリティがあります。これは、私が説明した「standardImportExtension」構成値です。

もちろん、ここに「保証」の問題があります。 このスレッドの前半で、tscは、コンパイルされたjsが実際に[一部の環境で]実行されることを「保証」する必要があると主張されていました。

ええと...多分これはあまりにも難しいコミットメントでした。 実際、tscがjsが[一部の環境で]実行されることを保証することは非常に困難です。これは、先ほど説明したように、現在のjsランドスケープでその環境を定義するのが非常に難しいためです。

しかし、@ borfastによって提案された単純なフラグユーティリティは、 tscを試している新しいユーザーが遭遇するjsインポートエラーの_ほとんど_を解決します。

あなたが言及するように、これらすべての考慮事項に含まれる高度な使用法---

直接jsファイルですか? それとも、index.tsが入っているフォルダですか? それとも、メインフィールドを保持するpackage.jsonを持つモジュールですか? またはesnextフィールド? または、非標準である他のものはありますか? それとも、webpackによって書き直されたパスですか? またはロールアップ? もしそうなら、設定はどこにありますか? 多分それは別のバンドラーですか?

—まあ、その使用法は、実際にカスタムユーザースクリプト、バンドラー、その他のツールに任せることができます。

しかし、高度な使用法を解決するのが難しいという理由だけで、簡単なケースを解決することを避けるべきであるという意味ではありません。

そして最も簡単なケースは、インポートに.js拡張子を追加することです。 これを解決でき、解決する必要があります。

@weoreferenceなので、質問をしたり、役立つように努めたりしたことに対して、あなたは反対票を投じました。その後、あなたはその質問を無視します。 実際に生産的な解決策に進むのではなく、ただ議論したいだけのようです。 あなたはそうしようとするすべての人の試みに反対票を投じました。 このスレッドに関する最後のメッセージ。 みなさん、スパムをお詫びします。

@weoreferenceは、 @ DanielRosenwasserのコメントで、この会話の最初を見てください。 彼はなぜ彼らがそれを実行しないのかを説明します(「現時点で」?役に立たない希望を与える)。 彼の発言の後、typescriptの誰もこのトピックについてこれ以上コメントしませんでした。 私にとって、この議論は締めくくられるべきであり、マイクロソフトは公式に彼らの立場を述べるべきです。 限目。
補足として、個人的にはその機能がすべてですが、LOTを単純化するでしょう。 タイプスクリプトチームの議論も理解しているので、希望を失いました。

@weoreference

仮説ではありませんが、tscはそれを生成することを知っています。 tscを使用する場合、存在することが保証されます。

しかし、ここにはあなたが認めていない対称性があります。

あなたが言及するこの「保証」は、両方の方法を保持します。 あなたが言うように、「tscは[jsファイル]を生成することを知っている」場合、同様に有効な質問です。「では、なぜtscはこの保証に基づいて行動せず、知っている.js拡張子を適用するのですか?コンパイルされたjsにありませんか?」

対称性は実際には保持されません。 「.js拡張子を適用する」ほど単純ではありません。tscは指定子を解決して書き直す必要があり、解決は型宣言に依存する場合があります。 TypeScriptとBabelはシングルモジュールコンパイルモード(tscのisolatedModules)をサポートしており、この場合、JavaScriptの代わりに型をインポートすると、tscは型宣言をロードして、対応する.jsファイルの場所を決定する必要があります。指定子。 一貫性を保ち、エッジケースがないようにするには、コンパイル前に存在するか、現在のプロジェクトの既知の結果である.jsファイルのインポートのみをサポートするのが最も簡単です。

@ justinfagnani @ Draccozありがとうございます。 はい、わかりました。

私の最後のコメント:「難しいケースを解決できないからといって、簡単なケースを解決できないわけではありません。」

ありがとう

私はTypeScriptがここで仕様に反している(そして無効なJavaScriptを生成している)と仮定してきましたが、インポートパスがファイル名と正確に一致することを実際に要求する仕様のどこにも見つかりません(拡張子付き)。 消化するのは非常に難しいので、完全に自信はありませんが、仕様では「FromClause」の「ModuleSpecifier」が「StringLiteral」である必要があることがわかります。 非常に緩い定義のようですが、ECMAScriptが存在する多くの異なる環境でモジュール解決の柔軟性を可能にするためかもしれません。 私がこれを正しく読んでいるかどうか誰かが確認できますか? もしこれが本当なら、TypeScriptがこれを処理する方法に対する私のスタンスを和らげる必要があるでしょう。 ただし、TypeScript、Node、およびWebの間の相互運用性を高めたいと思います。 現在の状況は理想的ではありません。

私はこれを読んだ後にこの問題に行き着きました。 その問題は、ノードのシステムがES仕様のために(厳密に一致するファイル名で)動作するという印象を与えましたが、私はそれを読み間違えた(ES仕様を参照していなかった)ので、おそらくどちらのノードも、 TypeScriptも実際には「間違った」ことをしていません。 次に、この問題は、実際には、異なる環境間でモジュールを解決するための同等に有効なアプローチ間の非互換性に関するものです。 それでも、明らかにTypeScriptの主なターゲット環境はNodeとWebであり、Nodeは理論的にはアプローチを変更できますが、ブラウザーが変更される可能性は低いと思います。したがって、この問題は依然として有効だと思います。

編集:モジュールの解像度が「ホスト定義」であることを指定しているように見えるのは、仕様のこのセクションかもしれないと思いますか?

@kj関連する仕様テキストはHTML仕様にあります: https ://html.spec.whatwg.org/multipage/webappapis.html#resolve -a-module-specifier

インポート指定子は完全なURLまたは絶対パスまたは相対パスでなければならないことを示しています。 指定子がURLとして解析されない場合(通常はhttp://またはhttps://で始まる)、または/./ 、または../で始まる場合

他のパス検索や解決は行われません。 つまり、指定子はモジュールの完全なURLに解決する必要があり、サーバーで必要な場合は拡張子を含める必要があります。 サーバーには、拡張子のないURLに対する応答を返すオプションがあります。

Nodeがモジュールに対してより制限的な解決アルゴリズムを採用した理由は、Webとの互換性を高めるためです。そのため、npmに公開されたモジュールは、ブラウザーでネイティブに実行するために追加のツールを必要としません。 パッケージ名によるインポートは依然として非常に重要な機能であるため、Nodeはそれをサポートしますが、 Import Mapsプロポーザル(DenoおよびSystemJSがすでにサポートしている)との互換性を目指しています。

結局のところ、 .js拡張機能を使用したインポートに対するtscのサポートは、ノードブラウザーとWebブラウザーの両方で完全に機能します。 追加のツールなしで問題を引き起こすのは、実際には拡張機能のないインポートです。 ただし、通常、パッケージ名のノード解決をサポートするツールは、クラスrequire()スタイルの解決を使用し、相対パスを解決し、それらの拡張機能も追加します。 これはes-dev-serverが行うことです。

@justinfagnaniに感謝します。 したがって、少なくともブラウザでは、サーバーがそれをどのように実装するかによって異なります。 それを知っておくのは良いことです。 これはまだかなり直感的で混乱を招き、コミュニティの利益のためにプロジェクト間でより多くの収束が必要であると私は信じていますが、それがどのように見えるかはもうわかりません。

編集:今のところ、これで十分です(特に上記の説明を考えると、私はそれでより快適に感じます):

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

このオプションがTypeScriptのドキュメントで参照されているかどうかはわかりませんが、参照されていない場合は、混乱を避けるために使用する必要があります。 ' site:typescriptlang.org specifier-resolution'または ' site:staging -typescript.orgspecifier-resolution'のいずれかを検索しているようには見えません。 ただし、これはNodeではまだかなり新しいので、それほど驚くことではありません。

@justinfagnani .js拡張機能は、誰かがイデオロギー的な立場をとる場合を除いて、ほとんどの場合に機能することに同意します(例:https://github.com/TypeStrong/ts-node/issues/783、あなたが精通している)。

@quantuminformationのスクリプトの依存関係のないバージョンをここで作成しました。 そのバージョンには、まだ.jsで終わっていないモジュールのみを置き換える正規表現も含まれています。

同じ必要性

importステートメントで.jsを使用してESM互換性のために.js拡張機能を実現することは、私にとってはうまくいきません。 TSファイルをインポートして拡張子を省略すると、正常にコンパイルされます。 インポートに.js拡張子を追加すると、TSコンパイラから多くのエラー(存在してはならない)が発生します。

この機能が開発されていない主な理由は、さまざまなバンドラーとの互換性の難しさ/不可能性によるものと思われますが、Node.jsとバンドラーはECMAScriptでモジュールがサポートされていないため、独自のモジュールスキームを開発しました。 ESMができたので、一部の人が考えるほど不十分ですが、それは前進の道です。 ESMおよびWebコンポーネントで開発されるコードが増えると、バンドラーの使用が減少し、TSとESMの間のこの問題点により摩擦が大きくなります。 最初のサポートにバグがあり、すべてのユースケースを考慮していなくても、サポートを開始できればよいでしょう。

より良い解決策が見つかるまで、これはビルドタスクとして使用する依存関係のないノードスクリプトです

package.jsonで構成します。

  ..
    "scripts": {
        "build": "node build.js",
   ...

//build.js
import { execSync} from "child_process"
import * as util from "util"
import * as fs from "fs"
import * as path from "path"

//function to recurse dirs finding files
function fromDir(startPath, filter, callback) {

    //console.log('Starting from dir '+startPath+'/');

    if (!fs.existsSync(startPath)) {
        console.log("no dir ", startPath);
        return;
    }

    var files = fs.readdirSync(startPath);
    for (var i = 0; i < files.length; i++) {
        var filename = path.join(startPath, files[i]);
        var stat = fs.lstatSync(filename);
        if (stat.isDirectory()) {
            fromDir(filename, filter, callback); //recurse
        }
        else if (filter.test(filename)) callback(filename);
    };
};

//this add .js to lines like:  import .* from "\.  <-- only imports from ./ or ../ are touched
function addDotJsToLocalImports(filename) {
    var buf = fs.readFileSync(filename);
    let replaced = buf.toString().replace(/(import .* from\s+['"])(?!.*\.js['"])(\..*?)(?=['"])/g, '$1$2.js')
    if (replaced !== buf.toString()) {
        fs.writeFileSync(filename, replaced)
        console.log("fixed imports at "+filename )
    }
}

//------------------------
//---BUILD TASK START 
//------------------------

execSync("npx tsc --build -verbose", { stdio: 'inherit' })

//add .js to generated imports so tsconfig.json module:"ES2020" works with node
//see: https://github.com/microsoft/TypeScript/issues/16577
fromDir("./dist", /\.js$/, addDotJsToLocalImports)

https://github.com/microsoft/TypeScript/issues/16577#issuecomment-310426634に基づく

この号が開かれた3年前に彼らが何をしていたかを誰かが覚えていますか?

非バンドルソリューションは、拡張子として.jsを使用してWeb分散プロジェクトを作成することです。

その100%が機能します。 より大きな問題は、WebとNode.jsをターゲットとするモジュールを作成しようとすることですが、それは一般的にJSの問題です。

やるべきことがあれば、 --moduleResolution=webを追加することになりますが、それはここでのこの問題の範囲ではありません。

.js拡張子を追加するには、このビルド後のスクリプトを作成する必要がありました。

fix-ts-imports

#!/usr/bin/env sh

# Fixes JavaScript module imports generated by TypeScript without extension.
# Converts
# import {} from './module'
# into
# import {} from './module.js'
#
# EXAMPLE
# ./fix-ts-imports

ProjectDir="$(cd "$(dirname "$0")/.." && pwd)"

fix() {(
        local pkg="$1"
        shift

        find "$pkg" -type f -iname '*.js' -not -ipath '*/node_modules/*' -print0 \
        | while read -r -d '' file; do
                sed -i '' -E 's|(import .+ from ['\''"]\.?\./.+[^.][^j][^s])(['\''"])|\1.js\2|g' "$file"
        done
)}

if test $# -eq 0; then
        set -- "$ProjectDir"
fi

for pkg; do
        fix "$pkg"
done

私はJavaScriptで同様のスクリプトを持っています:
https://github.com/yoursunny/NDNts/blob/743644226fe18d48e599181e87ad571a2708a773/mk/build-post.js

次のように呼び出されます。

tsc -b mk/tsconfig-solution.json -w --listEmittedFiles \
  | node mk/build-post.js

この種のスクリプトの主な欠点は、ソースマップが壊れて、デバッグの効果が低下することです。

ソースで最新のツールと.js拡張機能を使用すると、すべてがノードとブラウザーでうまく機能します

  • typescript
  • esモジュール
  • 巻き上げる

開発者が古いワークフローのなじみのあるランドマークにしがみついているので、ここで問題を抱えている人々が実際にes-modulesとノード解決の壊れたハイブリッドで立ち往生していると推測できます-おそらくwebpackが原因です...

—おそらくwebpackのせいです...

そしてそう—猫は袋から出ています。

ソースで最新のツールと.js拡張機能を使用すると、すべてがノードとブラウザーでうまく機能します

_ほとんど_はうまく機能し、ソースファイルはすべてエクスポートで.js拡張子を持つ必要があることに同意します。 私の経験では、これでうまく機能しないのはts-nodeです。これは、 .js拡張機能のサポートを頑固に拒否しているためです。 はい、ノードを実行する前に変換前の手順を追加できます。 .jsのインポートは機能しますが、 .tsコードを実行したり、ノードとブラウザで直接テストしたりする場合は、あなたは現在ほとんど運が悪いです。 (明確にするために、これはts-nodeのバグであり、TypeScriptのバグではないと思います)。

@ chase-moskalに感謝します。

リポジトリとtsconfigファイルをリファクタリングしました。
import {something} from './something.js'
投げない
typescript force overwrite error TS5055: Cannot write file because it would overwrite input file
もう、 fix-ts-importsハックはもう必要ありません。

250以上のコメントでは、明確さはほとんどありませんでした。 要約する:

バックグラウンド

ブラウザモジュール

ブラウザは、相対URLを含むURLに従ってEcmaScriptモジュールを解決します。 ( WHATWG

Node.jsモジュール

Node.jsは、複数のフォールバックとpackage.jsonファイルの解析を含むはるかに複雑なアルゴリズムを介してモジュール(EcmaScriptとNode.js固有のCommonJSの両方)を解決します。 ( Node.js )これはカスタマイズできます。たとえば、フルパスが必要な--experimental-specifier-resolution=explicitを使用します。

TypeScriptモジュール

TypeScriptには、複数の利用可能なモジュール解決アルゴリズムと、これらをさらにカスタマイズするためのさまざまなオプションがあります。 ( TypeScript )目的は、ユーザーが生成された出力で使用されるものと同じモジュール指定子を記述し、baseUrlやpathMappingsなどのオプションを使用してtscの解像度を調整することです。

実際には、ほとんどのユーザーはNode moduleResolutionを使用し、Node.js環境または互換性のあるバンドラーを対象としています。 このリクエストは、バンドラーのないブラウザをターゲットにしているユーザーに焦点を当てています。

tsノードモジュールの解像度

どうやら、ts-nodeは拡張子の付いたモジュール識別子をサポートしていません。 理由は不明ですが、Node.jsとTypeScriptの両方がそうであるため、ts-nodeは表面上はそれらの融合です。

事実

事実1:.js拡張子を使用できます

より広い互換性(つまりブラウザ)のために、今日は.js拡張子を使用できます。 ts-node(IMOバグ)の奇妙な例外を除いて、フルパス(つまり、拡張子を含む)を指定することで、すべてが現在機能します。

事実2:「拡張機能の追加」ほど単純ではありません

この要求は、「モジュール識別子をファイルパスに変換する」としてより適切に要約されます。 たとえば./example./example/index.jsになり、 'lodash''.node_modules/lodash/index.js'になります。

アンビエントモジュール宣言のように、解決されたファイルパスすら存在しない場合があることに注意してください。

declare module "lodash" {
}

おそらく、モジュールの書き換えは、現在のプロジェクト/コンパイルのTSモジュールに限定されています。

いずれにせよ、現在、TSの設計パラメーターの1つに違反しており、他のモジュールが現在のモジュールの出力に影響を与えています。

結論

Webで機能するモジュール識別子のパスを使用することができます。 (例: ./foo/index.js ./foo 。)

(実際には、とにかくブラウザをターゲットとするバンドラーが必要になる可能性があります。つまり、npmパッケージが使用されている場合です。)

@pauldraper 「ファクト2」には重要な問題があります。

この要求は、「モジュール識別子をファイルパスに変換する」としてより適切に要約されます。 たとえば、。/ exampleは./example/index.jsになり、「lodash」は「node_modules / lodash /index.js」になります。

パッケージが別の場所にインストールされているときに使用できるパスではない可能性があるため、コンパイル時にパッケージ外の指定子を解決する必要はありません。 一意のパッケージをインストールするたびに、ノードモジュールの解決を実行する必要があります。 そうでなければ、 import {} from './node_modules/lodash/index.js'を作成して公開し、それで済ますことができます。

@justinfagnani 、同意しますが、これはモジュール識別子が抽象的であり、tscの外部でモジュールの場所を操作していることを示しています。 そして、そのtscは、そのような操作に関与する必要はありません。

この要求は、「モジュール識別子をファイルパスに変換する」としてより適切に要約されます。 たとえば、。/ exampleは./example/index.jsになり、「lodash」は「.node_modules / lodash /index.js」になります。
アンビエントモジュール宣言のように、解決されたファイルパスすら存在しない場合があることに注意してください。

それはこの要求が何であるかではありません。 コードを発行するときに拡張機能を追加することです。 タイプ「モジュール」と互換性のあるモジュールを、追加のハッキーなビルド手順なしで記述したいと思います。 lodashのような外部モジュールは、CommonJであるため、.jsがなくても引き続き機能します。

例:

// ./src/moduleA.ts
export const test = 2;
// ./src/moduleB.ts
import {test} from './moduleA'



md5-ec0300a1c6d92a03c70699d0e52c0072



```js
// ./lib/moduleB.js
import {test} from './moduleA.js'

上記に加えて、typescriptはpackage.jsonの「exports」と「type」をサポートしていません。 私が管理しているプロジェクトには、真のESMへの道はありません。

このリクエストは、バンドラーのないブラウザをターゲットにしているユーザーに焦点を当てています。

それは正しくありません。 ブラウザ用にTS / JSを作成することはめったにありません。主にサーバー側のコードで作業します。また、ノードでESM読み込みを使用し、モジュールの読み込みにバンドラーや追加のコードに依存しないため、これも必要です。

lodashのような外部モジュールは、CommonJであるため、.jsがなくても引き続き機能します。

そうでない限り。

放出されたとき。

./moduleA.jsの可能性があります。 それとも./moduleA/index.jsかもしれませんね? Node.jsモジュールの解決により、いくつかのパスが許可されます。

そうでない限り。

これらが機能しない場合の例を教えてください。 Node.jsは、CommonJSから名前付きエクスポートをインポートするためのサポートを開始しました。
https://nodejs.org/api/esm.html#esm_import_statements

./moduleA.jsの場合があります。 または、。/ moduleA / index.jsかもしれませんね? Node.jsモジュールの解決により、いくつかのパスが許可されます。

ESMモードではありません。 index.jsは、現在のようにサポートされなくなります。 ESMローダーはpackage.jsonメタデータ「exports」と「type」を読み取ります。
https://nodejs.org/api/esm.html#esm_mandatory_file_extensions

typescript + node.jsベースのプロジェクトでは、より優れたネイティブESMストーリーが必要です。 これは、ツール(typescript)またはnode.jsで発生する可能性があります。問題は、何をすべきかについてのコンセンサスが不足していることです。

誤解を招く可能性があるため、削除されたノードPRへのリンクを編集します。

このページは役に立ちましたか?
0 / 5 - 0 評価