# Первые шаги

*ОБНОВЛЕНИЕ 2018: Вышло* [*второе издание*](https://maxfarseer.gitbooks.io/redux-course-ru-v2/content/) *(современный код и версии пакетов, данное издание УСТАРЕЛО)*

*На* [*канале*](http://bit.ly/2IqH74P) *так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы,* [*присоединяйтесь*](http://bit.ly/2IqH74P)*!*

## Первые шаги

Для сборки нашего кода будем использовать [Webpack](https://webpack.github.io/).

```
npm i webpack webpack-dev-middleware webpack-hot-middleware --save-dev
```

Флаг --save-dev - добавит пакет webpack (и парочку вспомогательных) в список зависимостей нашего проекта.

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

*webpack.config.js*

```javascript
var path = require('path')
var webpack = require('webpack')

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './src/index'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ]
}
```

Даже для тех, кто не знаком с webpack'ом, этот конфиг покажется вполне понятным. В entry - указывается откуда webpack'у начинать сборку, а в output - куда сгенерировать. В devtool указываем, что нам нужен source-map для отладки кода с парой настроек ([cheap, module, eval](https://webpack.github.io/docs/configuration.html#devtool)).

Интерес пытливого читателя может вызвать строка `'webpack-hot-middleware/client'` ([NPM](https://www.npmjs.com/package/webpack-hot-middleware)), которая нужна нам для поддержки *hot-reload*, вместе с одним из плагинов - *webpack.HotModuleReplacementPlugin*

### Server

Нам понадобится сервер для разработки, для этого мы можем использовать webpack-dev-server, либо быстро развернем свой. В данном руководстве рассматривается второй вариант.

Для начала установим express

```
npm i express --save-dev
```

и создадим наш web-сервер на его основе.

*server.js*

```javascript
var webpack = require('webpack')
var webpackDevMiddleware = require('webpack-dev-middleware')
var webpackHotMiddleware = require('webpack-hot-middleware')
var config = require('./webpack.config')

var app = new (require('express'))()
var port = 3000

var compiler = webpack(config)
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }))
app.use(webpackHotMiddleware(compiler))

app.get("/", function(req, res) {
  res.sendFile(__dirname + '/index.html')
})

app.listen(port, function(error) {
  if (error) {
    console.error(error)
  } else {
    console.info("==> 🌎  Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port)
  }
})
```

Обратите внимание, на строку

```javascript
app.use(webpackHotMiddleware(compiler))
```

На этом шаге добавляется немного магии к нашему серверу, а именно: сервер теперь принимает уведомления, когда главный js скрипт собран и вызывает обновления модулей нашего приложения, в остальном cервер всего навсего отдает нам index.html, в котором мы подключаем файл, сгенерированный webpack'ом.

*index.html*

```markup
<!DOCTYPE html>
<html>
  <head>
    <title>Redux [RU]Tutorial</title>
  </head>
  <body>
    <div id="root">
    </div>
    <script src="/static/bundle.js"></script>
  </body>
</html>
```

Добавим точку входа для webpack'а. Мы указали ее в нашем webpack.config.js в настройке entry - index.js

*src/index.js*

```javascript
document.getElementById('root').innerHTML = 'Привет, я готов.'
```

Проверим?

```
npm start
```

<http://localhost:3000/>

Отлично, кое-что уже завелось. Но если сейчас обновить код в файле `index.js` страница в браузере останется прежней. Хотя при этом в консоли мы увидим, что webpack что-то пересобрал.

### Hot Reload

Дело в том, что "модуль" `index.js` не умеет сообщать webpack'у каким образом он хотел бы обновиться. Сейчас, для простоты примера, достаточно добавить строку `module.hot.accept()`, которая сообщает webpack'у следующую информацию:"Я (*index.js*) умею hot-reload сам, для этого просто возьми и обнови меня в сгенерированном файле (*/static/bundle.js*)."

*src/index.js*

```javascript
document.getElementById('root').innerHTML = 'Привет, я готов!'
module.hot.accept()
```

Перезапустите сервер, обновите страницу браузера.

А теперь поменяйте текст, в index.js - он так же обновится на экране браузера. Браузер **не перезагрузит** страницу, как в случае с *live-reload*, а сразу отобразит только нужный кусочек. Это гораздо удобнее!

Конечно, постоянно указывать `module.hot.accept()` не удобно, и не разумно. Следующий шаг поможет нам избавиться от "ручной" настройки hot-reload для react.js кода.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-frontend.gitbook.io/redux-course-ru/chapter1/pervieshagi_md.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
