Блог на ReactJS #1. Компоненты. npm, jsx, webpack, webpack-dev-server

Этот урок входит в цикл "Блог на React". Это первый урок из цикла про ReactJS. Будем делать блог (для себя выбрал тематику - Африка). В первую очередь скачиваем и устанавливаем последнюю версию node.js + npm Или устанавливаем из репозиториев (если у вас linux). На Ubuntu в консоли: sudo apt-get update sudo apt-get install nodejs Проверить, установилось ли всё правильно, можно запустив команды: node -v npm -v

Если версии пакетов отобразятся, то, значит, они установлены, и Вы можете пропустить этот блок. Но если отображается ошибка(пакеты не найдены), то пути к этим пакетам нужно добавить в глобальные переменные вручную. В Ubuntu самый простой способ: sudo ln -s /absolute/node/path/node /usr/bin/node sudo ln -s /absolute/npm/path/npm /usr/bin/npm В Windows нужно добавить эти пакеты в переменную PATH Для этого Пуск -> User accounts -> Change my enviroment variables -> New.../Edit... Path -> New -> D:\absolute\node\path

Двигаемся дальше. Выбираем/создаём директорию для будущего проекта и устанавливаем первые пакеты: npm init Можно пропустить все запросы нажав несколько раз Enter Устанавливаем пакеты (для окружения разработки):
npm install --save react react-dom
npm install --save-dev webpack webpack-dev-server
npm install --save-dev babel-loader babel-core babel-preset-es2015 babel-preset-react Создаём первый компонент: main.jsx
1
2
3
4
5
6
7
import React from 'react';
  
class Main extends React.PureComponent {
  render() {
    return <h1>Hello</h1>;
  }
}
Немного о синтаксисе. Что такое JSX. JSX - напоминает смесь ES6 и HTML. Мы имеем import, const, let, class (и т.д.) из ES6, но ещё мы можем вернуть HTML просто сделав:
1
2
3
4
5
6
//Кавычки или нечто подобное не требуется
return (
   <div>
      <p>Текст абзаца</p>
   </div>
);
О компонентах. Компонент в React помогает разбить UI на несколько независимых частей и работать с ними, как с изолированными друг от друга объектами. В React три основных вида компонента:
  • Функция - это миниатюрный компонент, в котором нет state. Компонент-функция выполняет роль render (т.е. она и исполняется в случае изменений). В целом, она даёт наименьшую нагрузку и предпочтительнее компонентов ниже.
  • React.Component - перед выполнением render проверяет все props, state и вложенные в них элементы. Если что-то отличается, произойдёт render. Т.е. перед каждым render проходится всё дерево ваших переменных от props, state;
  • React.PureComponent - перед выполнением проверяет только верхний уровень вложенности props, state. Если что-то изменяет данные внутри переменных, но не меняет ссылку на этот объект, то render не произойдёт.
Более детально ознакомимся с ними позже. Теперь давайте дополним наш компонент выводом в DOM-элемент: main.jsx
1
2
3
4
5
6
7
8
9
10
import React from 'react';
import ReactDOM from 'react-dom';
  
class Main extends React.PureComponent {
  render() {
    return <h1>Hello</h1>;
  }
}
 
ReactDOM.render(<Main />, document.getElementById('main'));
Создадим HTML-документ index.html
1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="main"></div>
  </body>
</html>
Теперь, чтобы это заработало в браузере, нам нужно:
  • Перевести JSX в понятный браузеру Javascript
  • Связать HTML и полученный JS
  • Как-то получить эти связанные элементы (в виде сайта) через браузер
Связываем всё с помощью Webpack Webpack - сборщик приложений. Он помогает пройти по нужным исходным файлам, как-то их обработать и собрать в единое приложение. Для указания ему необходимых шагов придётся написать конфигурационный файл. К счастью, такими конфигами полнится интернет, и вот вам ещё один для данного примера: webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var path = require('path');
var webpack = require('webpack');
  
module.exports = {
  entry: './main.jsx',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015', 'react']
        }
      }
    ]
  },
};
Из конфига видно, что все файлы jsx будут собраны в один файл bundle.js, чтобы после сборки наши компоненты заработали, нужно добавить этот скомпилированный JS-файл в index.html index.html
1
2
3
4
5
6
7
8
9
10
11
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="main"></div>
    <script src="bundle.js"></script>
  </body>
</html>
Теперь, чтобы запустить сборку проекта нужно выполнить: node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --progress --colors После завершения сборки в браузере можно будет увидеть наш проект по URL: http://localhost:8080/ Также webpack-dev-server следит за изменениями файлов и автоматически пересобирает проект (и даже перезагружает страницу). Проверим. Когда webpack-dev-server работает (наш проект доступен по http://localhost:8080/), изменим файл main.jsx. Запишем Hello world вместо Hello. main.jsx
1
2
3
4
5
6
7
8
9
10
import React from 'react';
import ReactDOM from 'react-dom';
  
class Main extends React.PureComponent {
  render() {
    return <h1>Hello world</h1>;
  }
}
 
ReactDOM.render(<Main />, document.getElementById('main'));
Обратите внимание! При сохранении файла webpack-dev-server сам все пересоберёт и перезапустит(без ручного перезапуска команды), окно в браузере автоматически обновится. Также вы можете заметить, что наш bundle.js уже занимает больше 1МБ. Это плата за использование сторонних библиотек (react, react-dom в данном случае). Не огорчайтесь, этот размер можно уменьшить, т.к. это только dev-сборка. Сборка для prod-серверов будет ощутимо легче (но чуда ожидать не стоит, вес будет больше, по сравнению с чистым JS)
В следующем уроке из этого цикла мы соберём несколько компонентов, научимся настраивать webpack-dev-server, создадим более удобные команды для сборки приложения (через npm run), разберём props и state. Спасибо за внимание.
Если статья Вам показалась незаконченной или Вы знаете как её улучшить, пожалуйста сообщите мне e@gohtml.ru