Tslint: no-implicit-dependencies:パスマッピングをサポート

作成日 2017年10月20日  ·  18コメント  ·  ソース: palantir/tslint

バグレポート

  • __TSLintバージョン__:5.8.0
  • __TypeScriptバージョン__:2.7.0-dev.20171020
  • __TSLintの実行__:CLI

リンティングされているTypeScriptコード

src / a.ts

import { x } from "foo";

types / foo.d.ts

export const x = 0;

tsconfig.json

{
    "compilerOptions": {
        "paths": {
            "*": "types/*"
        }
    }
}

tslint.json構成の場合:

{
    "rules": {
        "no-implicit-dependencies": true
    }
}

実際の動作

ERROR: /home/andy/sample/tslint/src/a.ts[1, 19]: Module 'foo' is not listed as dependency in package.json

予想される行動

エラーはありません。 インポートがnode_modules何かに解決されない場合、このルールはそれを無視する必要があると思います。

最も参考になるコメント

このルールは、独自のソースコードにエイリアスを使用する場合(npmパッケージからインポートしない場合)は機能しません。 相対パスの代わりに絶対パスを使用すると非常に便利です。
tsconfig.jsonでは、Angularアプリケーションの場合、次を追加するだけです。

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

次に、次のようなインポートを実行できます。

import {FooService} from '~/core';
import {Environment} from '~/env';

このケースを解決するには、この問題を再度開く必要があるかもしれません(node_modulesは必要なく、tsconfig.jsonファイルのみが必要です)。
私はこのルールに感謝しているので、それを無効にするのは残念です。

全てのコメント18件

インポートがnode_modules内の何かに解決されない場合、このルールはそれを無視する必要があると思います。

ルールはモジュールを解決しようとしません。 つまり、すべての依存関係をインストールする必要がありますが、peerDependenciesやoptionalDependenciesでは実際には不可能です。 現在の実装では、何もインストールせずに新しいクローンを作成できます。 私はそれがほとんどのコード品質ツールが行うことだと思います。

パスマッピングを理解しているので、それらはコンパイル時にのみ存在します。 実行時に、ノード/ webpack /を正しく取得するためにモジュールをインストールする必要があります。
つまり、パスマッピングは、コンパイル中に省略されるタイプのみのインポートがある場合にのみ関連します。 この場合、ルールはおそらくあなたにとって正しい選択ではありません。

私たちの場合、通常package.jsonはまったくないので、このルールを無効にする必要があると思います。 ありがとう!

私の場合、パスマッピングを使用して同時に作業している個別のタイプスクリプトプロジェクトを「インポート」しています。

"compilerOptions": {
    ...
    "paths": {
        "tsbase": ["../tsBaseProject/src"],
        "tslibrary": ["../tsProjectLibrary/src"]
    }
}

モジュールのようにプロジェクトで使用できるようにします。
それらをホワイトリストに登録する方法はありますか?

@marcoquパスマッピングは、コンパイル時にのみ関連します。 実行時に、これらのモジュールはnode_modulesに存在する必要があります。 それらをdependenciesまたはpeerDependenciesとしてpackage.jsonに追加することをお勧めします

セカンダリプロジェクトを「インポート」するメインソースをコンパイルすると、プロジェクト内の実際のフォルダーであるかのように、すべてが1つのバンドルにコンパイルされます。 node_modulesフォルダーにそれらを置く必要はありません。
明確にするために、セカンダリプロジェクトフォルダには、型宣言だけでなく、実際の.tsファイルがあります。

no-submodule-importsのようにホワイトリストを追加するための+1

また、相対的なインポートを回避するために、ベースディレクトリへのパスエイリアス「〜」を定義するユースケースもあります。 このエイリアスは、後でwebpack、fuse-boxなどによって解決されます。5.8以降、tslintはこのために多くの偽のエラーを吐き出します...

彼が言ったこと^^

アップグレードした後、上記と同じ理由で、これらのエラーが何百も発生します。 一種の無意味なルール。

このルールは、独自のソースコードにエイリアスを使用する場合(npmパッケージからインポートしない場合)は機能しません。 相対パスの代わりに絶対パスを使用すると非常に便利です。
tsconfig.jsonでは、Angularアプリケーションの場合、次を追加するだけです。

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

次に、次のようなインポートを実行できます。

import {FooService} from '~/core';
import {Environment} from '~/env';

このケースを解決するには、この問題を再度開く必要があるかもしれません(node_modulesは必要なく、tsconfig.jsonファイルのみが必要です)。
私はこのルールに感謝しているので、それを無効にするのは残念です。

@ andy-msは、サポートパスを再検討してください(nxワークスペースで広く使用しています)。 これは本当に便利なルールですが、今のところ私はそれを無効にすることを余儀なくされています。

私はソースコードを調べてみましたが、修正はこれらの行のどこかに行く必要があります。 Typescriptがそれをどのように処理しているかを確認し、この関数まで追跡しました。 その論理を複製するのは間違いなく簡単なことではありません。 その関数を再利用できるかどうかはわかりませんが、確信が持てない議論がたくさんあります。

これも修正されることを望んでいます。 パスマッピングは非常に価値のある機能です。 リンクされたモジュールを回避策として使用しようとしましたが、それらもサポートされていません。

私はこの問題をある程度解決する回避策を見つけましたが、それがすべての人に役立つか、またはそれがまったく維持可能であるかは定かではありません。 とにかく、解決策は次のようになります。

tsconfig.jsonからのパスマップの名前で偽のパッケージをoptionalDependencies追加し、 npm install --no-optionalを使用して依存関係をインストールします。 残念ながら、これはyarn --ignore-optionalでは機能しません-それでもパッケージをフェッチしようとして失敗します。

したがって、 tsconfig.jsonパスは、次のようになります。

    "paths": {
        "~/*": ["src/*"],
        "some-path/*": ["whatever/*"]
    }

そして、次のようにpackage.jsonオプションです:

    "optionalDependencies": {
        "~": "tslint-hack",
        "some-path": "tslint-hack"
    },

npm install --no-optionalを使用して、本番環境と開発の依存関係を取得してインストールできるようにする必要があります。 これは明らかに、オプションの依存関係をインストールする必要がないことを前提としています。 また、パッケージ名として@を使用しても機能しませんでした。

このハックを使用することを選択した場合、 optional=false構成して.npmrcファイルをプロジェクトルートに追加するのが賢明である可能性があります。そのため、 npm installせずに実行に戻ることができます。 --no-optionalフラグ。

動作するはずの別の解決策は、実際に目的の名前でパッケージを作成し、 verdaccioなどを使用してプライベートレジストリに公開することです。 .npmrcまたは.yarnrcを使用して、モジュールごとにプライベートレジストリを構成できると信じています。そのため、保守性の点で優れているはずです。 ただし、これはテストされていません。

これが、このtslintルールを使用して、モジュールの解像度を維持したい人にとって少し役立つことを願っています。 しかし、それは適切な修正に代わるものではありません。

また、この問題が発生し、ソナーがこれをコードの臭いとして誤ってフラグ付けする結果になります。

tslintはすべてtypescriptに関するものであり、pathsは有効な(そして重要な)typescript設定であるため、これは有効な要求だと思います。

package.jsonとは異なるディレクトリにtslint.jsonどうなりますか?

- web
    - package.json
    - ClientApp
        - tslint.json

私は同様のセットアップに取り組んでいますが、このルールが原因でほとんどすべてのファイルでエラーが発生しています。 これに対する解決策はありますか?

この問題を回避するために私が見つけた方法は、次の構成オプションを使用することです。

"no-implicit-dependencies": [true, ["src", "app", "~"]]

提供されたパスをホワイトリストに登録します。 明らかに、これは重複を意味しますが、探している場合は簡単に修正できます。

カスタムパスのプレフィックスとして@シンボルを使用する私たちのために、現在の実装#4192の小さなバグを修正するためにPRを作成しました。

"no-implicit-dependencies": [true, ["@src", "@app", "~"]]

@ifiokjr srcエイリアスとして@していたので、インポートは@/components
@最初に解決するので@/componentsをインポートしようとしたため、 @を無視されたパスとして設定できませんでした。

エイリアスを~に変更し、tslintで上記の行を使用して、問題を解決しました

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