Стандарты кодирования - очень важная часть проверок кода, но их сложно выполнить вручную.

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

Очень распространенная ошибка, наблюдаемая в приложениях Angular, - это импорт ненужных операторов RxJS, и мы можем автоматизировать ее исправление.

Взгляните на этот пример:

import {map} from ‘rxjs/operators';
...
const endpoint = 'http://some-url.tld/get-list-of-ids';
this.httpClient
    .get(endpoint)
    .pipe(
        map(response => response.id)
    )
    .subscribe(response => console.log(response));

Конечно, этот код работает без сбоев, и все работает, но если вы посмотрите на размер вашего приложения, он окажется больше, чем должен быть. Это потому, что включены все операторы RxJS.

Проблема здесь в импорте, и простое изменение загрузит только то, что необходимо.

import {map} from 'rxjs/operators/map';

Изменение здесь простое, но даже лучшая проверка кода не предотвратит случайного добавления какого-нибудь разработчика короткого импорта и БУМ! Ваше приложение на ~ 4 КБ больше.

Я знаю, что это не так уж важно, но если сложить много из этих 4 КБ, можно загрузить гораздо больше, чем нужно.

Давайте напишем правило TSLint для вашего проекта!

Я предполагаю, что у вас уже есть работающий проект с Typescript и TSLint.
Если нет, используйте новое сгенерированное Angular приложение - это всего лишь несколько шагов.

Подготовьте структуру папок и все необходимые файлы

Создайте папку. / tools / tslint-rules /.

Создайте файл. /tools/tslint-rules/tslint.json со следующим содержанием:

{
    "rulesDirectory": [
        "dist"
    ],
    "rules": {
        "disallow-rxjs-operators-full-import": true
    }
}

Вам также понадобится специальный файл. /tools/tslint-rules/tsconfig.json для создания правила:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "outDir": "./dist",
    "moduleResolution": "node",
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

и файл. /tools/tslint-rules/package.json:

{
  "name": "my-tslint-rules",
  "version": "0.0.0",
  "license": "MIT",
  "main": "tslint.json"
}

Теперь мы можем сказать TSLint использовать наши правила. Мы можем сделать это, добавив в основной tslint.json раздел extends:

{
    "extends": [
        "./tools/tslint-rules"
    ],
    ...
    "rules": {
        ...
    }
}

Расширяет точки раздела до файла package.json, в котором определен файл tslint.json в основном файле.

Рекомендуется также добавить сгенерированную папку. / tools / tslint-rules / dist в .gitignore и сохранить только оригинальные правила в машинописном тексте.

У нас есть шаблон, и давайте напишем правило.

Итак, давайте назовем наше правило как disallowFullImportRxjsOperatorsRule.ts.

export class Rule extends Lint.Rules.AbstractRule {
...
}

Вы можете заметить, что каждый файл с правилом должен иметь суффикс * Rule.ts и будет использоваться в нашем файле tslint как disallow-full-import-rxjs-operators .

Ниже вы можете увидеть уже реализованное правило:

Теперь вам нужно только собрать его с помощью компилятора машинописного текста.

./node_modules/.bin/tsc -p ./tools/tslint-rules/tsconfig.json

и когда вы запустите линтер для файлов с неправильным импортом, вы увидите такие ошибки, как

ERROR: /Users/.../src/app.service.ts[7, 1]: RxJS operators should be imported from their own scope.

Большой! Мы смогли найти неправильное место в нашем приложении. Исправить это вручную всегда возможно, но мы можем пойти еще дальше.

Автоматизировать замену

Метод addFailureAt () определяется как

addFailureAt(
    start: number,
    width: number,
    failure: string,
    fix?: Fix,
): void;
type Fix = Replacement | Replacement[];

Вы можете видеть, что последний параметр является необязательным и может обеспечивать одну или несколько замен. Чтобы включить эту замену, вам нужно запустить команду tslint с аргументом - fix.

Реализация такой замены может быть следующей:

Моя реализация не обязательно должна быть идеальной, но она служит определенной цели и работает во всех случаях, которые были у Erento.

Не бойтесь писать свои собственные правила.

Обновление:
После обсуждения в следующем PR https://github.com/mgechev/codelyzer/pull/498 я должен упомянуть, что это правило TSLint и фиксатор - хорошее решение для текущего версия RxJS (5.x), но она не будет работать в новом основном выпуске. В новой версии операторы следует импортировать только из rxjs / operator.