Tslint: no-implicit-dependencies: Поддержка сопоставления путей

Созданный на 20 окт. 2017  ·  18Комментарии  ·  Источник: palantir/tslint

Сообщение об ошибке

  • __TSLint версия__: 5.8.0
  • __TypeScript version__: 2.7.0-dev.20171020
  • __ Запуск TSLint через__: CLI

Линтинг кода TypeScript

src / a.ts

import { x } from "foo";

типы / 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. В текущей реализации вы можете создать новый клон, ничего не устанавливая. Я предполагаю, что это то, что делает большинство инструментов качества кода.

Насколько я понимаю, сопоставления путей существуют только во время компиляции. Во время выполнения вам все еще нужен модуль, установленный для node / webpack / что угодно, чтобы правильно его подобрать.
Это означает, что сопоставления путей актуальны только в том случае, если у вас есть импорт только типа, который исключается во время компиляции. В этом случае правило, вероятно, вам не подходит.

В нашем случае, как правило, package.json вообще нет, поэтому я думаю, что тогда мы должны просто отключить это правило. Спасибо!

В моем случае я «импортирую» отдельные проекты машинописного текста, над которыми я работаю одновременно, с использованием сопоставления путей:

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

так что я могу использовать их в проекте, как если бы они были модулями.
Есть ли способ внести их в белый список?

@marcoqu Отображения путей актуальны только во время компиляции. Во время выполнения эти модули должны существовать в node_modules. Я предлагаю добавить их как dependencies или peerDependencies в свой package.json.

Когда я компилирую основной источник, который «импортирует» вторичные проекты, все компилируется в единый пакет, как если бы они были настоящими папками в проекте. Мне не нужно, чтобы они были в папке node_modules.
Чтобы было ясно, во вторичных папках проекта у меня есть реальные файлы .ts, а не только объявления типов.

+1 за добавление белого списка, как в no-submodule-import

У нас также есть случай, когда мы используем случай, когда мы определяем псевдоним пути '~' к базовому каталогу, чтобы избежать относительного импорта. Этот псевдоним позже разрешается 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 обрабатывает это, и отследил это до этой функции . Определенно нелегко повторить эту логику. Я не уверен, можно ли использовать эту функцию повторно, есть масса аргументов, в которых я не уверен.

Я бы очень хотел, чтобы это тоже было исправлено. Отображение путей - очень важная функция. Я также пробовал использовать связанные модули в качестве обходного пути, но они тоже не поддерживаются.

Я нашел обходной путь, который несколько решает проблему для меня, но не уверен, что это подойдет для всех, или что он вообще обслуживается. Во всяком случае, решение выглядит следующим образом:

Добавьте поддельный пакет в optionalDependencies с именем карты путей из tsconfig.json и установите зависимости, используя 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 . Это, очевидно, предполагает, что вам не нужно устанавливать никаких дополнительных зависимостей. Также стоит упомянуть, что я не работал с @ качестве имени пакета.

Если вы решите использовать этот хак, то, вероятно, будет разумным добавить файл .npmrc в корень проекта с настроенным optional=false , чтобы вы могли вернуться к запуску npm install без флаг --no-optional .

Другое решение, которое _должно_ работать, - это фактически создать пакет с желаемым именем и опубликовать его в частном реестре, используя verdaccio или подобное. Я верю, что можно настроить частные реестры для каждого модуля с помощью .npmrc или .yarnrc , и как таковые должны быть лучше с точки зрения ремонтопригодности. Однако ничего из этого не проверено.

Надеюсь, это немного поможет тем, кто хочет использовать это правило tslint и сохранить разрешения своих модулей. Но это не замена правильному исправлению.

Также возникает эта проблема, из-за которой сонар неправильно отмечает это как запах кода.

Я думаю, что это действительный запрос, поскольку tslint - это все о машинописном тексте, а пути - допустимая (и важная) настройка машинописного текста.

Что делать, если у меня package.json в другом каталоге, чем tslint.json ?

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

Я работаю над подобной настройкой, и из-за этого правила я получаю ошибки почти во всех файлах. Любое решение для этого?

Я нашел способ обойти эту проблему с помощью следующего параметра конфигурации.

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

Он заносит в белый список предоставленные пути. Очевидно, это означает дублирование, но это быстрое решение, если вы его ищете.

Для тех из нас, кто использует символы @ качестве префиксов для пользовательских путей, я поднял PR, чтобы исправить небольшую ошибку в текущей реализации # 4192

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

@ifiokjr Я использовал @ качестве псевдонима src, поэтому мой импорт выглядел как @/components
Не удалось установить @ как игнорируемый путь, поскольку он пытался импортировать @/components как целый модуль вместо того, чтобы сначала разрешить @ .

Я изменил свой псевдоним на ~ и использовал строку выше в моем tslint, решив проблему

Была ли эта страница полезной?
0 / 5 - 0 рейтинги