TS でのモジュール宣言

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-19 14:47:02457ブラウズ

ここでは、高品質の Typescript 宣言ファイルを作成する方法を学びます。 ReactJS でコーディングしていて、SVG ファイルをインポートしたいと考えていますが、IDE/tsc が文句を言っています。

[ts] cannot find module './logo.svg'

今こそ、Stackoverflow を使って簡単なコピーペーストの解決策を探しましょう。

しかし、ちょっと待って、これらのファイルとその機能を理解してみましょう。

モジュールとは何ですか?

TS/JS では、TS/JS で書かれたアプリをモジュール化するための多くのアプローチが行われてきました。現在、最高位に君臨しているのは ESM (別名 ES モジュール、ES6 モジュール) です。通常、私たちはそれらを構文で知っています:

Module declaration in TS

元の質問に答えると、ECMAScript 2015 に準拠した TS/JS では、トップレベルインポートまたはエクスポートを含むファイルはすべてモジュールと見なされます

トップレベルのインポートまたはエクスポートがない場合:

  1. どこでも入手できます。
  2. これらは スクリプト として扱われます。

モジュールを使用する理由

グローバルな名前空間汚染はもうありません。これは次のことを意味します:

  1. モジュールは独自のスコープ内で実行されます。
  2. エクスポートするつもりだったものはすべて明示的にエクスポートする必要があります。
  3. 消費者は、他人に公開したものを別のモジュールからインポートできます。

名前付きエクスポートとデフォルトのエクスポート

Module declaration in TS

モジュール解像度

TS モジュールの解決は、import または require ステートメントから文字列を取得し、その文字列がどのファイルを参照しているかを判断するプロセスです。

TS には 2 つの戦略があります:

  1. クラシック:
    • デフォルトのもの。
    • compilerOptions.module は「CommonJS」ではありません。
    • 下位互換性のために含まれています。
  2. ノード:
    • CommonJS モードで NodeJS がどのように動作するかを複製します。
    • .ts および .d.ts ファイルの追加チェック。

ところで、意図的または非意図的に変更する可能性のある場所が山ほどあります (moduleResolution、baseUrl、paths、rootDirs)。

モジュール解像度

  • TS がモジュール指定子 (import/export/require ステートメント内の文字列リテラル) をディスク上のファイルに解決する方法を制御します。
  • ターゲット ランタイムまたはバンドラーによって使用される モジュール リゾルバーと一致するように設定する必要があります

たとえば、ESM を利用するようにアプリを構築している場合 (コンパイルされたバージョンは ESM を使用しています)、compilerOptions.module で「NodeNext」を選択する必要があります。

Module declaration in TS

  • 相対パスのファイル拡張子を使用している限り、TS はそれを解決できます (例: import {} from "./a.js"; // ✅ すべての moduleResolution で動作します)。
  • ESM を使用するようにアプリをコンパイルする予定の場合は、ファイルの拡張子を指定する必要があり、拡張子なしにすることはできません (例: import {} from 'a.mjs';)。
  • index.ts ファイルがあると予想されるディレクトリをインポートすることもできます。

注: そのディレクトリ内に package.json がある場合。次に、TS はその main と type を使用してその型を取得します。

詳細については、こちらをご覧ください。

パス

基本的に、baseUrl が設定されている場合は相対的に、設定されている場合は tsconfig ファイルに対して相対的に、インポートをルックアップ場所*s* に再マッピングします。この最も一般的な使用例はパス エイリアスです:

[ts] cannot find module './logo.svg'

注意

これはランタイムにとっては何の意味もありません。つまり、あなたの親愛なるバンドラーまたはコンパイラーがそれらを正しくバンドルする必要があるということです。また、パスが存在しない場所を指している場合、NodeJS による実行時にアプリがクラッシュします。

ヒント

これの代わりに、package.json のインポート (別名サブパス インポート) を利用できます。

ベースURL

  • ベア指定子を解決するベースディレクトリ1 モジュール名
  • node_modules からの検索よりも優先度が高くなります。
  • パスを使用するときに設定する必要がなくなりました。

ルートディレクトリ

  • 単一のルートとして機能する多数の「仮想」ディレクトリ。
  • コンパイラは、あたかも 1 つのディレクトリにマージされたかのように、これらの「仮想」ディレクトリ内の相対モジュール インポートを解決できます。

コンパイルされたJS

発行された JS 出力に影響を与えるには、以下を変更できます。

  • コンパイラオプション.ターゲット:
    • どの JS 機能が古い JavaScript ランタイムで実行するように変換されるかを決定します。
    • このコンパイルされた TS コードをどのブラウザ/NodeJS/Electron で実行するかなど、アプリケーションの要件によって決まります。
  • コンパイラオプション.モジュール:
    • システム ランタイムが使用するモジュール。
    • 最新の NodeJS プロジェクトには「nodenext」を使用してください。最も近い package.json ファイルを読み取り、その「type」値を使用して、CommonJS と ESM のどちらを使用するかを決定します。
    • バンドラーでバンドルする場合は「esnext」を使用します。

Module declaration in TS

本題に戻る

そこで、TS がどのようなものかをまったく知らない (タイプを解決できない) .graphql ファイルまたはその他の拡張子をインポートしたいと考えています。これで、TS はインポートされた svg、graphql、またはその他のファイルがどのように見えるかを認識できるようになりました。


参照



  1. ベア指定子: 相対パスでも絶対パスでもないインポート ステートメント内のモジュール名。これらは通常、プロジェクトのnode_modulesまたはその他の構成された場所にあるパッケージの名前です。 ↩

以上がTS でのモジュール宣言の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。