Рубрики
Без рубрики

Как постепенно добавить поток в существующее App App

Поток – это статический тип проверки типа для JavaScript. Этот пост предназначен для тех, кто слышал о потоке, но еще не пытался использовать его в рамках приложения RACT. Если это первый раз, когда вы слышали о потоке, я могу рекомендовать эти четыре поста

Поток это статический тип проверки для JavaScript. Этот пост предназначен для тех, у кого есть Слышал потока, но еще не пытался использовать его в приложении React. Если это первый раз, когда вы слышали о потоке, то я могу порекомендовать Эти четыре поста Preethi Kasireddy как отличное введение.

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

Поскольку настройка нового инструмента часто может быть самым сложным, в этом посте мы собираемся взять существующий проект и пройти через настройку добавления потока. Общее введение в синтаксис покрыт во-вторым из постов Preethi, и Документы потока также очень читаются.

Мы будем использовать это Пример репо , с двумя каталогами на пре- и поток. Использует Skyscanner’s Пользовательский Создать сценарий Access App Rackpack-React-Scripts в паре со своими пользовательскими Компоненты рюкзака Отказ Это направлено на создание примеров более сложных, чем одиночные фрагменты, но все еще можно читать, даже если вы не знакомы с ними.

Точная природа приложения неважно по сравнению с тем, чтобы увидеть разницу между его реализацией без и с Поток. Очень немногие файлы меняются здесь, но они часто являются наиболее расстраивающими, чтобы получить право!

Давайте пройдем по каждому шагу, а затем посмотрите на преобразование примерных компонентов.

Установите основные зависимости

Наряду с самим потоком установите Babel-Cli и Babel-предустановленный поток, так что Babel может удалить аннотации типа на компиляцию.

npm install flow-bin babel-cli babel-preset-flow --save-dev

Настройка Бабела

Для того, чтобы они вступили в силу, создайте .babelrc Файл или добавить к существующему .babelrc. Следующий конфиг .:

{
  "presets": ["flow"]
}

Настройка скриптов

Если вы используете какие-либо крючки, такие как скрипт предтолета, вы можете обновить их, а также добавлять основной поток Сценарий к вашему package.json :

"scripts": {
  "flow": "flow",
  "pretest": "npm run flow && npm run lint"
}

Генерировать FlowConfig

Если вы используете текущий поток в первый раз, вы можете генерировать шаблон .flowconfig Бег NPM Run Flow Init Отказ В нашем примере мы видим, мы продлить это Чтобы добавить следующее:

Игнорировать шаблоны

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

[ignore].*/node_modules/*.*/build/*

Добавить модули CSS

Если вы используете модули CSS, их тип необходимо указать, чтобы поток их понять, или вы получите эту ошибку:

Это делается в двух шагах. Сначала добавляется ниже к вашему .flowconfig. :

[libs]
./src/types/global.js  // this can be any path and filename you wish
[options]
module.name_mapper='^\(.*\)\.scss$' -> 'CSSModule'
module.system=haste

А вторых, тип модуля CSS создан в Файл ссылается в [libs] Отказ

// @flow
declare module CSSModule {
  declare var exports: { [key: string]: string };
  declare export default typeof exports;
}

Синхронизировать с другими привязками

В примере проекта ESLINT уже используется для обеспечения стандартного льмина. Существуют некоторые начальные шаги конфигурации, необходимые для того, чтобы ESLINT быть красиво играть с потоком, а некоторые более поздние из-за конкретных типов, используемых в этом проекте.

Для общего настройки следующее является добавлено нашему .eslintrc :

"extends": [
  "plugin:flowtype/recommended"
],
"plugins": [
  "flowtype"
]

Расширения, специфичные для этого примера, и ошибки, которые они избегают, будут покрыты к концу этого поста.

Поток набрал libdefs

Окончательный кусок установки – подготовиться к использованию libdefs создан с помощью набранный поток Пакет NPM. Это используется для создания определений для установленных узлов модулей, и по умолчанию создает эти файлы в набранный поток/ каталог.

Мы сделать Хотите совершить этот файл, но не хотят eslint Это создает проблему, так как раньше наш подтяжный скрипт в нашем package.json Установлено, чтобы использовать наш .gitignore знать, когда файлы ESLINT должны также игнорировать:

"lint:js": "eslint . --ignore-path .gitignore --ext .js,.jsx",

Теперь мы хотим изменить это, так как мы хотим ESLINT, чтобы также игнорировать созданный для создания набранный поток/ каталог. Мы можем изменить наш скрипт:

"lint:js": "eslint . --ext .js,.jsx",

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

Наконец, нам нужно установить Типы потоков . Мы делаем это по всему миру.

npm install flow-typed -g

libdefs могут быть полными определениями или заглушками, которые принимают любые типы. Список Полные определения поддерживается. Чтобы увидеть, есть ли доступный для пакета, который вы используете, используете

flow-typed install my-dependency@

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

flow-typed create-stub my-dependency@

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

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

Преобразование существующих компонентов

Это все общие настройки, сделанные, теперь мы можем посмотреть на преобразование наших примеров компонентов!

У нас есть два, условный компонент и функциональный компонент. В целом они создают баннер, чем есть текст и кнопка. Текст на баннере можно нажать, чтобы открыть поповертую, содержащую пулевую заостренный список.

Добавить определения

Для любого компонента первый шаг должен создать набранный поток Определения для любого импорта в компоненте мы работаем.

Например, Если бы у нас был только импорт

import React from 'react';
import BpkButton from 'bpk-component-button';

Тогда мы бы попробовали:

Набранный поток Установите BPK-компонент-кнопку @ на>

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

Кнопка CORECTION-CONECTOR CORECTION-STOUB CORECTOUB-STOUB @ NEW

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

Функциональные компоненты

В нашем примере без потока Мы используем Пропорпы Для некоторой проверки ограниченного типа и их способность определять дефолтныеProps для использования в разработке.

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

Чтобы преобразовать это для использования потока, мы можем сначала удалить Пропорпы Импорт и определения. //@flow Аннотация может затем быть добавлена к одной линии.

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

type Props = {
  strings: { [string_key: string]: string },
  onClose: Function,
  isOpen: boolean,
  target: Function,
};

Здесь последние три типа являются самосваивающимися. Как Строки это объект строк Объект как карта Был использован, проверяя каждую клавишу и значение в полученном объекте, чтобы проверить, что их типы совпадают, без необходимости указывать их точные строковые клавиши.

Определения типов оперных типов могут быть удалены вместе с его импортом. Поскольку defultproops не привязаны к этому импорт, они могут, и должны остаться. * См. Закрытие Comments Comments для любых ошибок, сообщенных на данный момент.

Теперь компонент должен выглядеть так:

Государственные компоненты

Учетные компоненты следуют на некоторых незначительных декларациях. Поскольку этот компонент более сложный, мы также посмотрим на объявление типов для некоторых дополнительных аспектов.

Как и прежде, сначала посмотрите на компонент перед добавлением потока Отказ

Реквизит и штат

Как и в функциональном компоненте, мы сначала удалите Пропорпы Определение и импорт, и добавьте //@flow Аннотация.

Сначала мы посмотрим на добавление типов для реквизитов и штата. Опять же, мы создадим типы для них:

type Props = {
  strings: { [string_key: string]: string },
  hideBannerClick: Function,
}; 
type State = {
  popoverIsOpen: boolean,
};

И укажите, что компонент будет использовать их:

class Banner extends Component {
  constructor(props: Props) {
    super(props);    
    this.state = {
      popoverIsOpen: false,
    };
  ...
  };
...
};

Далее мы ударим нашу первую разницу между функциями и компонентами для готовки, дефолтныеProps Отказ В функциональном компоненте они были объявлены, как мы привыкли, в гостевых компонентах внешние Banner.defaultprops Синтаксис удален, а вместо этого по умолчанию будут объявлены в классе:

class Banner extends Component {
  static defaultProps = {
    strings: defaultStrings,
  };
constructor(props: Props) {
...
// the below is removed
// Banner.defaultProps = {
//  strings: defaultStrings,
// };

Конструкторные объявления

StringWithDacholder объявлен в конструкторе. Здесь мы не смотрим на Почему Там объявлено (мы предположим, что есть веская причина), а скорее, чтобы увидеть, можно ли добавлять поток без каких-либо изменений в существующий код.

Если запустить в существующем состоянии, мы бы столкнулись с ошибкой Не может получить это .StringWithDorholder, потому что Свойство StringwitherHolder отсутствует в баннере [1] .

Чтобы исправить это, мы должны добавить одну строку внутри блока класса баннера, прямо и снаружи конструктора:

class Banner extends Component {
  constructor(props: Props) {
    super(props);    
    this.state = {
      popoverIsOpen: false,
    };
    this.stringWithPlaceholder = ...
  };
  stringWithPlaceholder: string;
...
};

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

На данный момент реквизит и состояние завершены. Давайте посмотрим на несколько быстрых дополнительных примеров проверки типа в пределах этого компонента. * См. Закрытие Comments Comments для любых ошибок, сообщенных на данный момент.

Возврат, события и типы узлов

ТоgglePopover Не принимает аргументов, поэтому простой пример указания возвращаемого значения можно увидеть:

togglePopover = (): void => {
  ...
};

KeyboardonlytogglePopover Возвращает ничего, но имеет один параметр. Это событие, в частности, событие KEYPRESS. SynthecticKeyboardEvent используется в качестве

keyboardOnlyTogglePopover = (e: SyntheticKeyboardEvent<>): void => {
  ...
};

Поповер определяется в Визуализация () и возвращает экземпляр ListPopover Функциональный компонент мы выглядели ранее. Мы можем указать его тип возврата в качестве реагирования Узел Отказ Однако, чтобы иметь возможность сделать это, мы должны сначала импортировать его, как это Не доступен по умолчанию Отказ Существует более одного способа импорта его, один из которых показан ниже:

import React, { Component } from 'react';
import type { Node } from 'react';
...
const Popover: Node = (
   document.getElementById('ListPopoverLink')}
  />
);

Тип Проверка импортированных компонентов React

Когда типы опоры были объявлены в компоненте, их можно использовать при использовании этого компонента в другом. Однако, если вы используете index.js Чтобы экспортировать первый компонент, затем поток, //@flow нужно будет добавить к индексу.

Например :

// @flow
import ListPopover from './ListPopover';
export default ListPopover;

Маркировка реквизит как необязательно

Опоры можно пометить как необязательно, используя Опора?: введите Синтаксис, например:

type Props = {  
  strings: { [string_key: string]: string },  
  hideBannerClick?: Function,
};

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

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

Eslint Extensions, реквизиты по умолчанию и реквизиты проверки. Решения ошибок

Два дополнения сделаны в нашу .eslintrc Отказ Для этого проекта специально вы можете просто принять их использование или прочитать детали ниже, если вы видите любую из трех ошибок:

  • x отсутствует в проверке проверки
  • Ошибка defaultprop "x" определено для Isrequired Proptype
  • Не может получить строки .xxx, потому что свойство XXX отсутствует в undefined

Добавлены правила с рассуждениями, являются:

"react/default-props-match-prop-types": [
  "error", { "allowRequiredDefaults": true }
]

При использовании объектов в качестве карт (в этом случае для «опоры строк) A Отсутствует в реквизиторе Vailation Ошибка возникает. Это Ошибка и так явно игнорируется здесь.

"react/default-props-match-prop-types": [  "error", { "allowRequiredDefaults": true }]

При использовании объектов в качестве сложных сложностей между ESLING, FLOWS и SPOR-типами входят в игру.

Строки это требуемая опора, передаваемая как объект строк. Тип потока проверяет, что для каждой записи в объекте клавиша String представляет собой строку, и значение является строкой. Это гораздо более ремонзуемо, чем при необходимости вычислить тип предпоставления каждого конкретного ключа.

Если опоры помечены по мере необходимости в потоке, то ESLINT будет приведен к ошибке: Ошибка DefaultProp «Строки», определенные для Isrequired Proptype Отказ

Если опора вручно помечается как необязательно, то поток ошибка с Не может получить строки .xxx, потому что свойство XXX отсутствует в undefined [1] Отказ

Это Известен и связан с Уточнение недействительности Поскольку JSX может преобразовать вызовы методов, поэтому поток не может быть уверен, что XXX не был переопределен.

Это оставляет нас с помощью исправления ошибки ESLINT. Вышеуказанные правила допускают определение defaultproops, когда тип потока – не помечен как необязательно. Поток поймет это и преобразует его в необязательно. Eslint отмечен «AuthoRequireddefaults»: правда , что означает, что, хотя Eslint видит опоры, поскольку требуется, это не будет ошибочно.

Последние мысли

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

Надеюсь, инструкции по настройке и примерам здесь доказывают полезны, если вы хотите попробовать вытекать.

Спасибо за прочтение ?

Вы также можете наслаждаться:

Оригинал: “https://www.freecodecamp.org/news/incrementally-add-flow-type-checking-react-261fee015f80/”