Есть несколько вариантов импорта RxJS, которые подробно описаны в документации.

Вы можете импортировать все:

import Rx from "rxjs/Rx";
Rx.Observable.of(1, 2, 3).map(i => i.toString());

Вы можете импортировать только те методы, которые вам нужны, исправив Observable прототип:

import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/of";
import "rxjs/add/operator/map";
Observable.of(1, 2, 3).map(i => i.toString());

Или вы можете импортировать методы, которые будут вызываться напрямую, а не через прототип Observable:

import { Observable } from "rxjs/Observable";
import { of } from "rxjs/observable/of";
import { map } from "rxjs/operator/map";
const source = of(1, 2, 3);
const mapped = map.call(source, i => i.toString());

У каждого из этих вариантов есть свои преимущества и недостатки:

  • импорт всего прост и гарантирует, что все методы доступны, но происходит за счет импорта всего пакета размером 586 КБ (неминифицированный);
  • внесение исправлений Observable только теми методами, которые вы хотите использовать, приводит к меньшей сборке, но необходимо позаботиться о том, чтобы методы были импортированы до их использования и что все необходимые методы были импортированы;
  • импорт и вызов методов напрямую исключает возможность вызова метода, который не был пропатчен в прототип Observable, но происходит за счет более подробного кода и потерянной информации о типе (поскольку в этот момент Function.prototype.call возвращает any).

Имеет смысл принять один из вышеперечисленных вариантов в качестве общей политики для базы кода. Осуществлением такой политики можно управлять с помощью TSLint и некоторых настраиваемых правил.

Правила

Я составил небольшой набор собственных правил, связанных с импортом; они включены в пакет rxjs-tslint-rules.

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

Правила для политики Angular

Подход Angular заключается в прямом импорте методов и использовании call для их вызова в наблюдаемых экземплярах. Одна из мотиваций этого подхода - избежать нарушения клиентского кода между обновлениями Angular. Если Angular исправит Observable прототип и если клиенты будут полагаться на методы, присутствующие исключительно из-за исправления прототипа Angular, код клиента сломается, если Angular перестанет исправлять конкретный метод.

Комбинация правил выглядит так:

"rxjs-no-add": { "severity": "error" },
"rxjs-no-patched": { "severity": "error" },
"rxjs-no-wholesale": { "severity": "error" }

rxjs-no-add запрещает импорт этого патча Observable.prototype; rxjs-no-patched запрещает вызовы методов через прототип; и rxjs-no-wholesale запрещает импорт всей библиотеки RxJS.

Пользовательское правило, запрещающее неиспользуемые, импортированные напрямую методы, не требуется; просто используйте no-unused-variable правило TSLint.

Правила для политики "вставки в каждый файл"

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

Комбинация правил выглядит так:

"rxjs-add": { "severity": "error" },
"rxjs-no-unused-add": { "severity": "error" },
"rxjs-no-wholesale": { "severity": "error" }

rxjs-add гарантирует, что любые методы, используемые в модуле, импортируются в этот модуль; rxjs-no-unused-add запрещает импорт неиспользуемых методов; и rxjs-no-wholesale запрещает импорт всей библиотеки RxJS.

Правила политики исправления в одном файле

Другая распространенная политика - назначить конкретный файл и импортировать исправленные методы только в этот файл.

Комбинация правил выглядит так:

"rxjs-add": {
  "options": [{
    "file": "./source/patched-imports.ts"
  }],
  "severity": "error"
},
"rxjs-no-wholesale": { "severity": "error" }

rxjs-add гарантирует, что методы, которые используют исправление Observable.prototype, импортируются только в ./source/patched-imports.ts файл, и запрещает импорт методов, которые не используются; и rxjs-no-wholesale запрещает импорт всей библиотеки RxJS.

Конфигурация

Чтобы использовать настраиваемые правила, добавьте rxjs-tslint-rules в параметр extends в вашем tslint.json файле и добавьте правила, которые вы хотите использовать, в параметр rules:

{
  "extends": [
    "rxjs-tslint-rules"
  ],
  "rules": {
    "rxjs-add": { "severity": "error" },
    "rxjs-no-unused-add": { "severity": "error" },
    "rxjs-no-wholesale": { "severity": "error" }
  }
}

rxjs-tslint-rules не является самоуверенным и не содержит активных правил по умолчанию. Более подробно правила описаны в документации.

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

С выпуском RxJS версии 5.5.0 появилась другая альтернатива: импорт и использование конвейерных (также известных как lettable) операторов.

У конвейерных операторов есть несколько преимуществ, и если вы хотите переключиться на них, rxjs-tslint-rules можно использовать для принудительного применения политики только конвейерных операторов. Комбинация правил для политики подробно описана в моей статье RxJS: Общие сведения об операторах Lettable.

Этот пост также опубликован в моем личном блоге: ncjamieson.com.