Новый механизм JSX трансформации в React 17 Release Candidate

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
В React 17 Release Candidate появляется новый способ трансформации JSX. С ним, в бандле, не понадобится сам Реакт, хотя для использования хуков он всё ещё нужен. Это и есть основной бенефит нового механизма. Под катом краткий перевод статьи в блоге ReactJS.



Что такое JSX Трансформация


Так как браузеры не понимают JSX “из коробки”, разработчики полагаются на компиляторы типа Babel или Typescript что бы трансформировать JSX в обычный JS. В React 17 Release Candidate появился новый, опциональный механизм трасформации JSX в JS.
Вот его преимущества:

  • Использование JSX без импорта Реакт
  • В зависимости от настроек бандл может слегка уменьшиться
  • В будущем будут доступны фичи для упрощения работы с реактом


(Возможно я не совсем точно перевёл — вот оригинал: It will enable future improvements that reduce the number of concepts you need to learn React)

Апгрейд никак не меняет сам JSX и все компиляторы как работали так и будут работать. Нет никаких планов по отказу от них. Планируется поддержка нового механизма JSX Transform для старых версий Реакт: 16.х, 15.х, 14.х, вот здесь инструкции для апгрейда.

Что изменилось


Старая JSX трасформация работала следующим образом:
Код
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}

Трасформировался в
import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}


Но это не супер и вот почему:
  • Так как JSX компилируется в React.createElement, React должен быть в области видимости
  • Есть несколько вариантов улучшить скорость и упростить, которые блокирует React.createElement


Что бы это решить в React 17 появляются две новые точки входа предназначенные для использования другими инструментами такими как Babel и Typescript и теперь вместо трансформации в React.createElement импортируются и вызываются новые функции из пакета React.

Предположим ваш код выглядел вот так:
function App() {
  return <h1>Hello World</h1>;
}


После новой трансорфмации он будет выглядеть вот так:
// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}

Новый механизм не импортирует React, хотя он всё ещё нужен для работы хуков.

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

Как апгрейдить


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

Для апгрейда нужны две вещи:
  • Версия Реакт с поддержкой новой трансформации. Пока что это только 17, но в будущем 16.х, 15.х и 14.х
  • Совместимый компилятор (см. ниже)


Create React App
Create React App поддержка будет в релизе v4.0 сейчас он в бета тестировании (на 22.09.20)

Next.js
Next.js v9.5.3+ уже использует новую Реакт трансформацию для совместимых версий.

Gatsby
Gatsby v2.24.5+ уже использует новую Реакт трансформацию для совместимых версий.

примечание
Если у вас в Gatsby вот такая ошибка после апгрейда на 17.0.0-rc.2, запустите npm update


Ручная настройка Babel
Поддержка с версии v7.9.0 и выше

Если вы используете babel/plugin-transform-react-jsx:

# npm
npm update @babel/core @babel/plugin-transform-react-jsx
# yarn
yarn upgrade @babel/core @babel/plugin-transform-react-jsx

Если вы используете babel/preset-react:

# npm
npm update @babel/core @babel/preset-react
# yarn
yarn upgrade @babel/core @babel/preset-react

Сейчас для трансформации JSX, в babel/plugin-transform-react-jsx и в babel/preset-react, по умолчанию включена опция {«runtime»: «classic»} это старая версия трансформации. Для включения новой трансформации нужна опция {«runtime»: «automatic»}

Если вы используете babel/preset-react
{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}

Если вы используете babel/plugin-transform-react-jsx
{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}

Начиная с версии Babel 8, «automatic» будет значением по умолчанию для обоих плагинов. Вот здесь более подробная документация @babel/plugin-transform-react-jsx and @babel/preset-react.

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


ESLint
Если у вас плагин eslint-plugin-react, то правила react/jsx-uses-react и react/react-in-jsx-scope больше не нужны и их можно удалить.

{
  // ...
  "rules": {
    // ...
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off"
  }
}


TypeScript
Поддержка JSX трансформации с версии 4.1 beta.

Flow
Поддержка JSX трансформации с версии 0.126.0 и выше

Как убрать неиспользуемые импорты React


Поскольку новая JSX трансформация автоматически импортирует react/jsx-runtime, React больше не нужен в области видимости для использования JSX. Неиспользуемые импорты это не критично, но если хотите удалить, рекомендуется использовать скрипт codemod.
cd your_project
npx react-codemod update-react-imports


В результате:
  • Удалятся все неиспользуемые импорты React
  • Изменятся все импорты типа import React from «react» на именованные import { useState } from «react». Это предпочтительный способ импорта. Codemod не затронет импорты типа import * as React from «react», это тоже валидный импорт и в 17 версии он будет работать, но в дальнейшем мы будем просить избавляться от него


Код
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}


Будет заменён на
function App() {
  return <h1>Hello World</h1>;
}


Если вы используете что то другое в реакте (например хук), то в коде появится именованный импорт:
Код
import React from 'react';

function App() {
  const [text, setText] = React.useState('Hello World');
  return <h1>{text}</h1>;
}


Заменится на код
import { useState } from 'react';

function App() {
  const [text, setText] = useState('Hello World');
  return <h1>{text}</h1>;
}


Удаление неиспользуемого импорта поможет подготовиться к следующим версиям Реакта (не 17) в которых будет поддержка ES модулей и не будет дефолтного экспорта.

Благодарности



Мы благодарим команды Babel, TypeScript, Create React App, Next.js, Gatsby, ESLint, и Flow за их помощь в интеграции нового механизма JSX трансформации. Мы также благодарим сообщество Реакт за их отзывы и обсуждения RFC
Источник: https://habr.com/ru/post/521930/


Интересные статьи

Интересные статьи

Первый прототип подводного дата-центра компания Microsoft разработала и погрузила под воду еще в 2015 году. Его нарекли Leona Philpot, а сам проект получил название Natick. Пе...
В современных фронтенд-приложениях технология CSS-in-JS пользуется определённой популярностью. Всё дело в том, что она даёт разработчикам механизм работы со стилями, который удобнее обычного CSS....
Всё новое — это хорошо забытое старое (а лучше очень хорошо забытое старое). Следить за новыми уязвимостями, конечно же, правильно, но и о старых забывать не стоит. Тем более, когда о них позволя...
Аддитивное производство металлических деталей становится все более востребовано, и неудивительно: по сравнению с традиционными промышленными технологиями, такими как литье, порошковая металлургия...
Систему Shenango планируют использовать в дата-центрах. / фото Marco Verch CC BY По данным одного из провайдеров, дата-центры используют всего 20–40% доступных вычислительных мощностей. При...