Как пользоваться Webpack 4, чтобы не перезагружать браузер в процессе разработки приложения


Содержание материала:

Как пользоваться Webpack 4, чтобы не перезагружать браузер в процессе разработки приложения

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

Для этих целей, вы можете использовать такие системы для автоматизации задач, как Grunt или Gulp, создавая цепочку таких преобразования, которые, например, минимизируют ваш CSS или JavaScript код, соединять в единый файл и т.д.

Подобные инструменты крайне популярны и очень полезны. Есть, тем не менее, другой способ произвести подобные действия, которые реализуется с помощью Webpack.

Именно об этом способе мы поговорим в статье.

Что такое Webpack?

Webpack можно охарактеризовать, как “сборщик модулей”. Он берет JavaScript модули с необходимыми зависимостями, и затем соединяет их вместе как можно более эффективным способом, на выходе создавая единый JS-файл. На первый взгляд – ничего особого, не так ли? Например, такие инструменты, как RequreJS позволяют делать подобные вещи вот уже много лет.

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

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

Установка Webpack

Как и большинству инструментов Web-разработчика, Webpack требует для своей работы установленный Node.js. Если Node.js у вас уже настроен, то все, что нужно сделать для установки Webpack – это выполнить следующую команду в консоли:

Данная команда установит Webpack глобально в вашей системе, что позволит запускать его из любого места. Далее, внутри директории нашего проекта, создадим файл index.html с начальной разметкой:

Важной частью этого кода является ссылка на файл bundle.js , который будет содержать в себе результат работы Webpack. Также обратите внимание на пустой элемент h2 – он нам пригодится позднее.

Теперь создадим пару файлов в корневой директории проекта. Имя первого файла будет main.js и он послужит входной точкой для приложения. Второй файл назовем, например, say-hello.js . В него мы поместим простой код модуля, который будет принимать имя человека, DOM-элемент и выводить приветственное сообщение.

После того, как мы создали наш небольшой модуль, вызовем его из main.js . Сделать это очень просто:

Если бы мы сейчас открыли в браузере наш HTML-файл, то никакого вывода сообщения не произойдёт, т.к. мы ни подключили файл main.js , ни произвели сборку зависимостей для браузера. Всё, что нам нужно сделать – это указать Webpack на main.js файл, чтобы он подтянул все зависимости. Если это сделать, то Webpack произведет сборку этих файлов в единый файл bundle.js , который мы сможем использовать в браузере.

Вернемся в терминал, и просто выполним такую команду:

Первый файл определяет начальную точку приложения, в которой Webpack будет искать все зависимости. Это сработает и в том случае, если в вызываемых зависимостях есть свои зависимости от других модулей – до тех пор, пока не подключатся абсолютно все необходимые модули. Таким образом, на выход получится один файл bundle.js со всем модулями.

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

Теперь откройте index.html в браузере, и вы увидите результат работы приложения.

Настройка Webpack

Как вы могли заметить, определять каждый раз входной и выходной файл для Webpack – это не слишком большое удовольствие. К счастью, Webpack прекрасно настраивается с помощью конфигурационного файла. Для этого создадим в корневой директории файл webpack.config.js со следующим содержимым:

После этого достаточно всего лишь ввести команду webpack и мы получим такой же результ.

Локальный сервер для разработки

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

А затем запустим сервер командой webpack-dev-server . Эта команда старует простой Web-сервер, который будет обслуживать текущую директорию нашего проекта. Откроем в браузере новую вкладку по ссылке http://localhost:8080/webpack-dev-server/, и, если всё сделано правильно, то мы увидим примерно следующее:

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

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

Загрузчики

Одной из самых важных особенностей Webpack, является возможность использовать Загрузчики. Загрузчики являются аналогами “задач” (tasks) в Grunt и Gulp. По существу, они принимают содержимое файлов, а затем преобразуют его необходимым образом и включают результат преобразования в общую сборку.

Например, нам бы хотелось использовать некоторые возможность ES2015 в нашем коде. ES2015 – это новая версия JavaScript, которая полностью не поддерживается в браузерах. Поэтому, нам необходимо использовать Загрузчик для трансформации нашего ES2015 кода в старый ES5, который работает во всех браузерах. Чтобы сделать это, мы будем использовать одни из самых популярных Загрузчиков – Babel, и в соответствии с инструкцией, установим его командой:

Но прежде не забудем инициализировать npm командой npm init .

После установки Babel, у нас будет не только Загрузчик, но и все нужные для работы зависимости, пресеты для ES2015, чтобы Babel знал тип JavaScript для преобразования. Теперь, когда Загрузчик установлен, нам необходимо указать Babel конфигурацию для его использования. Обновим файл webpack.config.js :

В этом коде есть несколько важных вещей, на которые стоит обратить внимание. Строчка с кодом test: /\.js$/ является регулярным выражением, которым мы указываем применение данного Загрузчика только к .js файлам. Подобно этому, мы исключаем директорию node_modules с помощью кода exclude: /node_modules/ . В строках кода loader и query всё ясно само по себе – используем загрузчик с именем Babel и применяем пресет для ES2015.

Остановим наш веб-сервер комбинацией клавиш Ctrl+C и снова выполним команду webpack-dev-server . Теперь протестируем работу Загрузчика и напишем немного ES6 кода. Изменим в файле main.js вызов модуля на присвоение возвращаемого результата в константу вместо переменной:

После сохранения, Webpack должен самостоятельно пересобрать наше приложение и обновить страницу в браузере. В результате, на первый взгляд, ничего не изменилось. Но если мы взглянем на содержимое файла bundle.js , то найдем, что написанный нами ES6 код преобразовался с помощью Babel в старый добрый JavaScript.

Во второй части…

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

При создании статьи были использованы следующие источники:

Организация и сборка приложения

Компоненты в отдельных файлах и Webpack

В предыдущих статьях все компоненты приложения Vue.js размещались в одном файле — веб-странице. Такой подход, возможно, будет прекрасно работать для небольших проектов. Однако в больших проектах этот подход менее оптимален. В частности, html-разметка компонента определяется в javascript, в итоге логика и конфигурация компонента спешивается с html-кодом. Также мы не можем определить стили, которые предназначены только для компонента. И, кроме того, мы не можем использовать различные инструменты для предобработки типа Pug, Babel, Webpack и т.д.

Другой способ, который более подходит для крупных проектов, представляет определение компонента в отдельном файле с расширением .vue , который будет содержать логику javascript, html-разметку и стили компонента. Затем с помощью таких инструментов как Webpack или Browserify выполняется построение проекта и создается один общий файл javascript.

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

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

Определим в этой папке новый файл index.html :

Блок div с будет представлять элемент, которые будет использоваться Vue, а весь код будет находиться в файле build.js.

Далее добавим в проект папку src , которая будет содержать собственно код приложения. Затем в этой папке создадим новый файл App.vue :

Этот файл будет представлять компонент App. Каждый компонент имеет три основные секции. Первая секция представляет шаблон компонента, который помещается в элемент . Шаблон собственно и представляет разметку компонента.

Вторая секция, которая помещается в элемент

То есть мы просто вынесли все части компонента в отдельные файлы. При этом в работе приложения ничего не изменится.

Сервер разработки webpack не создает и не перезагружает index.html

Я сейчас использую webpack v4 и пытаюсь добавить webpack-dev-server в свой проект. Проблема, с которой я здесь сталкиваюсь, заключается в том, что когда я запускаю команду webpack-dev-server my, она открывает локальный сервер в браузере по умолчанию, но не обслуживает скомпилированные ресурсы, а также не наблюдает за изменениями.

Я еще не реализовал горячую замену модуля.

Вот структура проекта

Пожалуйста, помогите мне решить проблему.

output.path используется для установки выходного каталога для вашего приложения.

Вы пытались вывести все в «app/dist/js» , вместо этого вы должны установить его в «app/dist» а затем вы можете выбрать конкретный путь вывода для ваших активов.

Топ-пост этого месяца:  GetBot.guru — почему так важна быстрая индексация страниц сайта в Яндексе и как ее можно ускорить

Чтобы вывести пакет javascript в папку с именем js, вы можете установить output.filename: «js/bundle.js» .

Для css вы можете установить filename: «css/style.css» в настройках MiniCssExtractPlugin .

В этом примере нет необходимости устанавливать publicPath (ресурсы будут обслуживаться из корня вашего локального сервера).

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

Также вам не нужны никакие опции devServer (по умолчанию используется http://localhost:8080/ ).

Вот решение (я немного упростил код), devServer будет хорошо работать даже с HTML-файлами.

Введение в Webpack для новичков

Webpack — это инструмент, позволяющий скомпилировать, например, JavaScript модули в единый JS-файл. Webpack также известен как сборщик модулей.

При большом количестве файлов он создает один объемный файл (или несколько файлов) для запуска вашего приложения.

Он также способен выполнять множество иных операций:

  • помогает собрать воедино ваши ресурсы
  • следит за изменениями и повторно выполняет задачи
  • может выполнить транспиляцию JavaScript следующего поколения до более старого стандарта JavaScript (ES5) с помощью Babel, что позволит использовать новейшие функции JavaScript, не беспокоясь о том, поддерживает их браузер или нет
  • может выполнить транспиляцию CoffeeScript в JavaScript
  • может конвертировать встроенные изображения в data:URI
  • позволяет использовать require() для CSS файлов
  • может запустить webpack-dev-server (в нём встроен локальный сервер и livereload (“живая перезагрузка браузера”))
  • может работать с Hot Module Replacement (замена горячего модуля)
  • может разделить выходной файл (output file) на несколько файлов, чтобы избежать медленной загрузки страницы из-за большого размера JS-файла
  • может выполнить Tree Shaking

Webpack не ограничивается одним лишь фронтендом, его также успешно применяют в бэкенд разработке на Node.js.

У Webpack есть предшественники, у которых он перенял многие идеи. Основное различие заключается в том, что те инструменты известны как task runners (такс-раннеры), в то время как Webpack ничто иное, как сборщик модулей.

Webpack — это более целенаправленный инструмент. Вам достаточно указать точку входа в ваше приложение (это может быть даже HTML-файл с тегами

Введение в Webpack для новичков

Что такое Webpack?


Webpack — это инструмент, позволяющий скомпилировать, например, JavaScript модули в единый JS-файл. Webpack также известен как сборщик модулей.

При большом количестве файлов он создает один объемный файл (или несколько файлов) для запуска вашего приложения.

Он также способен выполнять множество иных операций:

  • помогает собрать воедино ваши ресурсы
  • следит за изменениями и повторно выполняет задачи
  • может выполнить транспиляцию JavaScript следующего поколения до более старого стандарта JavaScript (ES5) с помощью Babel, что позволит использовать новейшие функции JavaScript, не беспокоясь о том, поддерживает их браузер или нет
  • может выполнить транспиляцию CoffeeScript в JavaScript
  • может конвертировать встроенные изображения в data:URI
  • позволяет использовать require() для CSS файлов
  • может запустить webpack-dev-server (в нём встроен локальный сервер и livereload (“живая перезагрузка браузера”))
  • может работать с Hot Module Replacement (замена горячего модуля)
  • может разделить выходной файл (output file) на несколько файлов, чтобы избежать медленной загрузки страницы из-за большого размера JS-файла
  • может выполнить Tree Shaking

Webpack не ограничивается одним лишь фронтендом, его также успешно применяют в бэкенд разработке на Node.js.

У Webpack есть предшественники, у которых он перенял многие идеи. Основное различие заключается в том, что те инструменты известны как task runners (такс-раннеры), в то время как Webpack ничто иное, как сборщик модулей.

Webpack — это более целенаправленный инструмент. Вам достаточно указать точку входа в ваше приложение (это может быть даже HTML-файл с тегами

Оптимизация производительности

React использует несколько умных подходов для минимизации количества дорогостоящих DOM-операций, необходимых для обновления пользовательского интерфейса. Для многих приложений, использование React приведёт к быстрому пользовательскому интерфейсу без особых усилий по оптимизации производительности. Тем не менее, существует несколько способов ускорить React-приложение.

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

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

Если вы не уверены в том, что процесс сборки настроен правильно, вы можете проверить это, установив React Developer Tools for Chrome. Если вы посетите сайт, работающий на React в продакшен-режиме, иконка будет с чёрным фоном:

Если вы посетите сайт с React в режиме разработки, у иконки будет красный фон:

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

Ниже вы можете найти инструкцию по сборке своего приложения для продакшена.

Create React App

Если ваш проект сделан с помощью Create React App, выполните:

Эта команда создаст продакшен-сборку вашего приложения в папке build/ вашего проекта.

Помните, что это необходимо только перед деплоем на продакшен. Для обычной разработки используйте npm start .

Мы предлагаем готовые для продакшена версии React и React DOM в виде отдельных файлов:

Помните, что для продакшена подходят только те файлы, которые заканчиваются на .production.min.js .

Для наиболее эффективной продакшен-сборки с Brunch, установите плагин terser-brunch .

Затем, для создания продакшен сборки, добавьте флаг -p к команде build :

Помните, что это нужно делать только для продакшен-сборки. Вам не нужно использовать флаг -p или применять этот плагин во время разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.

Для наиболее эффективной продакшен-сборки с Browserify, установите несколько плагинов:

При создании продакшен-сборки, убедитесь, что вы добавили эти пакеты для преобразования (порядок имеет значение):

  • Плагин envify обеспечивает правильную среду для сборки. Сделайте его глобальным ( -g ).
  • Плагин uglifyify удаляет импорты, добавленные при разработке. Сделайте его глобальным ( -g ).
  • Наконец, полученная сборка отправляется к terser для минификации (прочитайте, зачем это нужно).

Помните, что это нужно делать только для продакшен-сборки. Вам не следует использовать эти плагины в процессе разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.

Для наиболее эффективной продакшен-сборки с Rollup, установите несколько плагинов:

При создании продакшен-сборки, убедитесь, что вы добавили эти плагины (порядок имеет значение):

  • Плагин replace обеспечивает правильную среду для сборки.
  • Плагин commonjs обеспечивает поддержку CommonJS в Rollup.
  • Плагин terser сжимает и оптимизирует финальную сборку.

Полный пример настройки можно посмотреть здесь.

Помните, что это нужно делать только для продакшен-сборки. Вам не следует использовать плагин terser или плагин replace со значением ‘production’ в процессе разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.

Если вы используете Create React App, пожалуйста, следуйте инструкциям выше.
Этот раздел подойдёт для тех, кто самостоятельно настраивает webpack.

Webpack 4.0 и выше по умолчанию минифицирует код в продакшен-режиме.

Вы можете узнать об этом больше в документации webpack.

Помните, что это нужно делать только для продакшен-сборки. Вам не стоит использовать TerserPlugin в процессе разработки, потому что тогда скроются вспомогательные предупреждения React и замедлится процесс сборки.

Анализ производительности компонентов с помощью вкладки Chrome «Performance»

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

Для того, чтобы сделать это в Chrome:

Временно отключите все расширения Chrome, особенно React DevTools. Они могут существенно исказить результаты!

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

Откройте в инструментах разработчика Chrome вкладку Performance и нажмите Record.

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

События React будут сгруппированы под меткой User Timing.

Для более детального ознакомления, посмотрите эту статью от Бена Шварца (Ben Schwarz).

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

В настоящее время Chrome, Edge и IE единственные браузеры, которые поддерживают данную возможность, но мы используем стандарт User Timing API поэтому ожидайте, что больше браузеров добавят его поддержку.

Анализ производительности компонентов с помощью инструмента разработки «Profiler»

Пакеты react-dom версии 16.5+ и react-native версии 0.57+ предоставляют расширенные возможности анализа производительности в режиме разработки с помощью инструментов разработчика React Profiler. Обзор профайлера можно найти в посте блога «Введение в React Profiler». Пошаговое видео-руководство также доступно на YouTube.

Если вы ещё не установили инструменты разработчика React, вы можете найти их здесь:

Профилирование продакшен-пакета для react-dom также доступно как react-dom/profiling . Подробнее о том, как использовать этот пакет, читайте на fb.me/react-profiling

Виртуализация длинных списков

Если ваше приложение рендерит длинные списки данных (сотни или тысячи строк), мы рекомендуем использовать метод известный как «оконный доступ». Этот метод рендерит только небольшое подмножество строк в данный момент времени и может значительно сократить время, необходимое для повторного рендера компонентов, а также количество создаваемых DOM-узлов.

react-window и react-virtualized — это популярные библиотеки для оконного доступа. Они предоставляют несколько повторно используемых компонентов для отображения списков, сеток и табличных данных. Если вы хотите использовать что-то более специфическое для вашего конкретного случая, то вы можете создать собственный компонент с оконным доступом, как это сделано в Twitter.

React создаёт и поддерживает внутреннее представление отображаемого пользовательского интерфейса. Оно также включает React-элементы возвращаемые из ваших компонентов. Это представление позволяет React избегать создания DOM-узлов и не обращаться к текущим без необходимости, поскольку эти операции могут быть медленнее, чем операции с JavaScript-объектами. Иногда его называют «виртуальный DOM», но в React Native это работает точно так же.

Когда изменяются пропсы или состояние компонента, React решает нужно ли обновление DOM, сравнивая возвращённый элемент с ранее отрендеренным. Если они не равны, React обновит DOM.

Несмотря на то, что React обновляет только изменённые DOM-узлы, повторный рендеринг всё же занимает некоторое время. В большинстве случаев это не проблема, но если замедление заметно, то вы можете всё ускорить, переопределив метод жизненного цикла shouldComponentUpdate , который вызывается перед началом процесса ререндеринга. Реализация этой функции по умолчанию возвращает true , указывая React выполнить обновление:

Топ-пост этого месяца:  Парсер Wordstat для статистики запросов Яндекса зачем нужен, как пользоваться и сколько стоит

Если вы знаете ситуации, в которых ваш компонент не нуждается в обновлении, вы можете вернуть false из shouldComponentUpdate , чтобы пропустить весь процесс рендеринга, включая вызов render() и так далее ниже по иерархии.

В большинстве случаев вместо того, чтобы писать shouldComponentUpdate() вручную, вы можете наследоваться от React.PureComponent . Это эквивалентно реализации shouldComponentUpdate() с поверхностным сравнением текущих и предыдущих пропсов и состояния.

shouldComponentUpdate в действии

Вот поддерево компонентов. Для каждого из них SCU указывает что возвратил shouldComponentUpdate , а vDOMEq указывает эквивалентны ли отрендеренные React элементы. Наконец, цвет круга указывает требуется ли согласовать компонент или нет.

Поскольку shouldComponentUpdate возвратил false для поддерева с корнем C2, React не пытался отрендерить C2, следовательно не нужно вызывать shouldComponentUpdate на C4 и C5.

Для C1 и C3 shouldComponentUpdate возвратил true , поэтому React пришлось спуститься к листьям и проверить их. Для C6 shouldComponentUpdate вернул true , и поскольку отображаемые элементы не были эквивалентны, React должен был обновить DOM.

Последний интересный случай — C8. React должен был отрисовать этот компонент, но поскольку возвращаемые им React-элементы были равны ранее предоставленным, ему не нужно обновлять DOM.

Обратите внимание, что React должен был делать изменения только для C6. Для C8 этого удалось избежать сравнением отрендеренных React-элементов, а для поддеревьев C2 и C7 даже не пришлось сравнивать элементы, так как нас выручил shouldComponentUpdate и render не был вызван.

Если единственный случай изменения вашего компонента это когда переменная props.color или state.count изменяются, вы могли бы выполнить проверку в shouldComponentUpdate следующим образом:

В этом коде shouldComponentUpdate — это простая проверка на наличие каких-либо изменений в props.color или state.count . Если эти значения не изменяются, то компонент не обновляется. Если ваш компонент стал более сложным, вы можете использовать аналогичный паттерн «поверхностного сравнения» между всеми полями props и state , чтобы определить должен ли обновиться компонент. Этот механизм достаточно распространён, поэтому React предоставляет вспомогательную функцию для работы с ним — просто наследуйтесь от React.PureComponent . Поэтому, следующий код — это более простой способ добиться того же самого эффекта:

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

Это может стать проблемой для более сложных структур данных. Например, вы хотите, чтобы компонент ListOfWords отображал список слов, разделённых через запятую, с родительским компонентом WordAdder , который позволяет кликнуть на кнопку, чтобы добавить слово в список. Этот код работает неправильно:

Проблема в том, что PureComponent сделает сравнение по ссылке между старыми и новыми значениями this.props.words . Поскольку этот код мутирует массив words в методе handleClick компонента WordAdder , старые и новые значения this.props.words при сравнении по ссылке будут равны, даже если слова в массиве изменились. ListOfWords не будет обновляться, даже если он содержит новые слова, которые должны быть отрендерены.

Сила иммутабельных данных


Лучший способ решения этой проблемы — избегать мутирования значений, которые вы используете как свойства или состояние. К примеру, описанный выше метод handleClick можно переписать с помощью concat следующим образом:

ES6 поддерживает синтаксис расширения для массивов, который поможет сделать это проще. Если вы используете Create React App, то этот синтаксис доступен там по умолчанию.

Таким же образом вы можете переписать код, который мутирует объекты. К примеру, мы имеем объект с именем colormap и хотим написать функцию, которая изменяет colormap.right на ‘blue’ . Мы могли бы написать:

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

Функция updateColorMap теперь возвращает новый объект, вместо того, чтобы мутировать исходный. Метод Object.assign входит в ES6 и требует полифила.

JavaScript рассматривает предложение добавить синтаксис расширения свойств объекта для добавления свойств объекта, чтобы упростить его обновление без мутаций:

Если вы используете Create React App, то Object.assign и синтаксис расширения объектов доступны вам по умолчанию.

При работе с глубоко вложенными объектами, постоянное их обновление может запутать. Если вы столкнулись с такой проблемой, обратите внимание на Immer или immutability-helper. Эти библиотеки позволяют писать хорошо читаемый код, не теряя преимуществ иммутабельности.

Разбираемся с настройкой Webpack для любого проекта

Большинство разработчиков так или иначе взаимодействовали с webpack при работе с проектами на React, Angular или Vue. В большинстве подобных ситуаций хватает настроек по умолчанию, поэтому освоение самого webpack как правило откладывается на потом. И если это так для вас, это может быть не правильно, так как уже базовые знания настроек webpack могут значительно улучшить процесс разработки.

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

webpack – это мощный сборщик проектов, который может быть очень эффективным при правильном использовании.

Почему все используют webpack?

Альтернативой использованию webpack является использование комбинации менеджеров задач, таких как grunt или gulp, со сборщиком пакетов, подобным browserify. Но что заставляет разработчика выбирать webpack, а не использовать его альтернативы?

Webpack решает задачу сборки более интегрированным и естественным образом. В browserify для этого вам придется использовать gulp/grunt и длинный список дополнительных модификаторов и плагинов. Webpack предлагает достаточно обширный функционал по умолчанию уже из коробки.

Webpack работает на основание файла конфигурации, в отличие от gulp/grunt, где мы должны писать код для выполнения своих задач. В зависимости от конфигурации он может делать правильные предположения о том, что вам необходимо сделать; как работать с различными модулями JS, как компилировать код и как управлять активами и так далее. Так же есть функция горячей перезагрузки проекта live-reload. Возможность замены выходных имен файлов именами хеш-файлов которые позволяет браузерам легко обнаруживать измененные файлы путем включения в имя файла специфичного для сборки хэша. И это лишь некоторые основные моменты, которые делают webpack лучшим выбором.

Особенности webpack

Базовые функции, некоторые из которых мы обсудим далее:

  • Загрузчики (Loaders)
  • Плагины (Plugins)
  • Использование разных конфигураций для разных окружений
  • Отложенная загрузка модулей
  • Удаление с помощью tree shaking забытого кода
  • Горячая замена модуля, которая позволяет обновлять код во время выполнения без необходимости полного обновления
  • Кэширование путем подстановки имен файлов хэшами

Настройка проекта

Начальные условия

Для продолжения этого урока нам потребуется установленный Node.js, в котором так же должен быть установлен менеджер пакетов npm. Затем мы установим yarn, которая является альтернативой npm, что даст дополнительные функциональные возможности и улучшить скорость установки дополнительных пакетов.

Начальная структура каталогов

Мы начнем с создания структуры каталогов. Создайте папку для тестового проекта Webpack-Setup. Внутри нее инициализируйте проект с помощью команды yarn init, которая создаст для нас файл package.json.

Далее в ней создайте папку src. Затем зайдите в папку src и там создайте еще три папки: app, public, style.

  • src: тут будет размещается исходный код проекта.
  • src/app: здесь будут размещаться наши файлы JavaScript.
  • src/public: эта папка будет содержать ресурсы проекта и статические файлы.
  • src/style: в этой папке будут глобальные стили проекта.

Далее создадим файлы проекта.

Создайте пустой файл src/app/index.js этот файл будет главной точкой входа в наш проект.

Файл src/public/index.html основной шаблон проекта

Создайте пустой файл src/style/app.scss он нам пригодится позже.

Начальная конфигурация

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

HtmlWebpackPlugin упрощает создание файлов HTML и может автоматически вставлять модули JavaScript в наш основной шаблон HTML.

Первым делом установим основные модули: webpack и webpack-dev-server (облегченный веб сервер для разработки).

Так же нам будет нужен webpack-cli:

Теперь создадим файл конфигурации webpack. В корне проекта создайте файл webpack.config.js со следующим содержимым:

Начальная конфигурация представляет собой скелет нашего проекта со следующими частями.

  • entry – Указывает на точку входа в проект, и откуда нужно начать построение графа внутренних зависимостей проекта.
  • output – Указывает куда будут отправляться создаваемые файлы сборки и как называть эти файлы.
  • devServer – Набор параметров для использования webpack-dev-server.

Далее добавим команду start в файл package.json.

Затем мы можем запустить наше приложение с:

В консоле должно отобразиться что то типа такого:

Затем вы можете перейти по адресу http://localhost:7700/, чтобы увидеть наше приложение.

Загрузчики

Загрузчики (loaders) – это специальные модули, которые используются для «загрузки» других модулей (написанных на другом языке). Так же они позволяют предварительно обрабатывать файлы по мере их импорта или «загрузки».

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

Загрузчики могут преобразовывать файлы с одного языка на другой, например TypeScript в JavaScript или из sass в css. Они могут даже позволить нам делать такие вещи, как импорт файлов CSS и HTML непосредственно в наши модули JavaScript. Для их использование необходимо прописать нужные загрузчики в разделе module.rules файла конфигурации.

babel-loader

Этот загрузчик использует Babel для загрузки файлов ES2015. Мы установим babel-core, в который входит babel-loader. Также подключим модуль babel-preset-env, который компилирует ES2015+ в ES5 путем автоматического определения необходимых Babel плагинов и полифайлов. Для этого с начало установим их, командой:

Затем создаем файл .babelrc, в корне проекта, и в нем пропишем пресеты.

Теперь мы можем включить наш загрузчик в нашу конфигурацию для преобразования файлов Javascript. Это позволит нам использовать синтаксис ES2015 + в нашем коде (который будет автоматически конвертироваться в ES5 в окончательной сборки).

Тестирование результата

Внесите следующий код в файл src/app/index.js:

Приведенный выше фрагмент кода отобразит сообщение в консоли браузера: Using ES2015+ syntax. Далее мы продемонстрируем работу нескольких загрузчиков с популярными фреймворками, включая Angular (1.5+) и React.

raw-loader

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

Добавим в наш проект Angular и загрузчик raw-loader:

Добавьте следующий код в файл конфигурации webpack

В файл src/app/index.js внесите следующий код:

В файл src/public/index.html внесите следующий код:

А так же в каталоге src/app/ создайте новый файл index.tpl.html

Топ-пост этого месяца:  Мониторинг доступности сайта как включить и использовать нужные функции

sass-loader

Загрузчик sass-loader помогает нам использовать стиль scss в нашем приложении. Для этого требуется модуль node-sass, который позволяет нам скомпилировать файлы .scss в css . Рекомендуется использовать его вместе с css-loader, чтобы превратить его в модуль JS и загрузчик стилей, которые добавят CSS в DOM, внедряя тег style.

Начнем с установки модулей:

Внесите следующие изменения в файл настроек webpack

Далее внесите следующие изменения в src/style/app.scss:

Использование стилей

Для этого нам достаточно импортировать стили в шаблон, как показано ниже:

Плагины

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

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

Плагины работают на уровне пакета или блока и обычно запускаются в конце процесса генерации пакета.

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


Мы уже использовали html-webpack-plugin, теперь я покажу, как использовать некоторые распространенные плагины в нашем проекте.

DefinePlugin

DefinePlugin позволяет вам создавать глобальные константы, которые можно использовать во время компиляции. Это очень полезно для управления конфигурациями импорта, такими как ключи API и другими константами, которые можно легко менять под разные окружения. Лучший способ использовать этот плагин – создать файл .env с разными константами и получить к ним доступ в конфигурации с помощью пакета dotenv, после чего мы сможем напрямую ссылаться на эти константы в нашем коде.

Затем создайте файл в корне проекта .env со следующим содержимым.

Настройка файла конфигурации webpack:

Далее добавьте следующую строку в src/app/index.js:

Должно в итоге получится что то типа такого:

webpack-dashboard

Это редко используемая панель инструментов CLI для webpack-dev-server. Плагин добавляет «красоту и порядок» в среду разработки, и вместо обычных журналов консоли мы видим привлекательную, легко интерпретируемую панель инструментов.

Внесем изменения в файл конфигурации:

Затем мы отредактируем наш package.json, чтобы использовать плагин.

После запуска проекта командой yarn start мы должны увидеть что то типа такого:

Среды разработки

В этом последнем разделе мы сосредоточимся на том, как мы можем использовать webpack для управления различными конфигурациями среды окружения. Мы покажем как использовать плагины в зависимости от среды, которые предназначены либо для тестирования, или для разработки, или для продакшин в зависимости от предоставленных переменных. Мы будем полагаться на пакет dotenv. В зависимости от окружения у нас будут различаться использование таких инструментов как devtool и плагины: extract-text-webpack-plugin, UglifyJsPlugin и copy-webpack-plugin и другие.

  • devtool – Управляет генерацией source map.
  • copy-webpack-plugin – Копирует отдельные файлы или целые каталоги в каталог сборки. Этот плагин рекомендуется для использования в продакшин, чтобы копировать все активы в выходную папку.
  • uglifyjs-webpack-plugin – Используется для минимизации кода проекта. Рекомендуется использовать в продакшин, чтобы уменьшить размер окончательной сборки.

Настройка файла конфигурации

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

Теперь если добавьте в файл .env следующую переменную:

легко увидеть что разница между размерами пакетами сборки до и после минификации огромна.

Заключение

Webpack, безусловно, является мощным помощником для разработки, и его очень легко настраивать под любые задачи. Эта статья демонстрирует лишь некоторые базовые возможности из большого количества всех возможностей webpack. Не пожалейте времени на изучении всего на что способен этот очень полезного инструмент.

#2 — Установка Webpack, начало работы

Всем привет! Меня зовут Ковальчук Дмитрий. Вы смотрите Лофтскул. Мы продолжаем изучать Webpack и сейчас мы с вами вместе, шаг за шагом, создадим наше первое веб-приложение.

1. Подготовка проекта

Создадим новую директорию для нашего приложения.

При помощи пакетного менеджера Yarn создадим package.json файл для управления зависимостями проекта.

Инициализируем git-репозиторий и настроим файл .gitignore

В список исключений мы добавим две директории: папку с зависимостями проекта и скрытую папку с рабочими файлами phpstorm.

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

2. Установка Webpack

Согласно документации, Webpack не рекомендуется ставить глобально (чтобы избежать возможной несовместимости версий Webpack для разных приложений на вашем компьютере). Достаточно установить его локально.

Проверим, добавился ли вебпак в «devDependencies»

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

3. Запуск Webpack при помощи npm-скриптов

Запускать Webpack мы будем при помощи так называемых npm-скриптов — это стандартная рекомендованная практика. При чём в нашем случае мы вместо npm будет пользоваться Yarn. Надеюсь, вы уже освоили этот пакетный менеджер. Если нет — посмотрите соответствующее видео на лофтскул.

Npm-скрипты работают очень просто. В блоке scripts файла package.json мы пишем в формате «ключ» — «значение» слева — название скрипта (оно может быть любое, на наш вкус), а справа то, что должно быть запущено.

Для запуска скрипта используется команда «run»

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

4. Создание первых javascript-модулей

Создадим папку «source» и в ней 2 javascript-файла «index.js» и «menu.js».

В файл menu.js мы поместим функцию, которая будет создавать список пунктов меню. Эта функция принимает 2 параметра: первый — массив пунктов меню, второй — класс, который нужно присвоить тегу ˂ul˃. После вызова данная функция будет возвращать html-элемент, а именно ненумерованный список, правда, без ссылок. Вы можете усовершенствовать эту функцию самостоятельно, однако в наших целях простого списка будет вполне достаточно.

Кстати, перед нами самый настоящий ES6-модуль — изолированный и аккуратный код, который можно использовать из проекта в проект, если будет необходимо. Необходимо отметить, что поддержка ES6-модулей появилась в Webpack начиная со второй версии, т.е. нам нет необходимости подключать babel в данном случае. Всё и так будет работать.

Ключевое слово export, стоящее перед объявлением функции, экспортирует данную функцию в остальную часть приложения. Ключевое слово default говорит о том, что мы экспортируем только одно значение, по умолчанию.
Если это пока для вас сложно, не волнуйтесь. Вы достаточно быстро привыкнете.

Следующий модуль index.js. В него мы импортируем функцию переданную во вне по умолчанию из menu.js и сразу присваиваем ей имя “createMenu”. При этом мы можем не указывать “.js” — webpack и так поймёт, что мы имеем ввиду.

Давайте создадим меню, состоящее из 3х пунктов …. Для удобства стилизации присвоим меню класс «menu».

5. Создаём html-файлы при помощи html-webpack-plugin

Для создания html-файлов и работы с шаблонами мы будем использовать плагин html-webpack-plugin.
Установим плагин при помощи Yarn. Не забудем флаг -D, чтобы зависимость была сохранена в devDependencies файла-манифеста. Туда же, где сохранён вебпак.

В webpack.config.js мы поместим следующий код. Я сэкономлю ваше время, сейчас и далее я не буду тратить время на тайпинг. Вместо этого постараюсь объяснить уже набранный код.

Пояснения:

— “сonst” — это ES6-альтернатива для “var”, указывающая, что переменная не должна быть изменена. Node.js полностью поддерживает эту часть ES6, т.е. в данном случае я также могу обойтись без babel.

— “path” — это базовый модуль node.js, который поможет нашему приложению работать корректно (одинаково) на разных платформах (например, windows или linux), т.к. они по разному определяют пути к файлам.

— “PATH” — объект, в который мы поместили 2 свойства: “source” — исходники приложения и “build” — папка, в которую будут помещаться результаты работы Webpack.

— “module.exports” — экспорт модуля в node.js. Внутри него мы пишем такие настройки Webpack, как entry, output, plugins и пр.

— “entry” — точка входа нашего приложения. Для многостраничного сайта можно сделать отдельные точки входа для каждой страницы. Запомните, что точками входа могут являться только те модули, которые не используются другими модулями вашего приложения. Так, например, наш модуль index.js использует другой модуль — menu.js. Но сам index.js не используется больше никаким модулем.

— “output” — описывает имена файлов и директорию — результат работы Webpack.

— “[name]” — это плейсхолдер, в него автоматически будут подставляться имена точек входа “entry” нашего приложения. А у нас их будет несколько. Но об этом позже.

— “plugins” — в этом разделе перечисляются плагины, которые кастомизируют процесс сборки Webpack. В нашем случае, это всего один плагин, который создает HTML-файл с заданным тайтлом.

Автоматическая перезагрузка браузера при изменении index.html

Я использую webpack-dev-server в очень простой настройке. Я обнаружил, что даже если сервер автоматически запускает перезагрузку браузера при изменении файла index.js , он не вызывает перезагрузку при изменении index.html . Как я могу это достичь?

Здесь моя настройка:

package.json

webpack.config.js

Я запускаю webpack-dev-server с помощью: npm run start , и я указываю браузеру:

Каждое изменение, которое я сделал в src/index.js , автоматически обновляется в браузере, но не так с изменениями, которые я делаю в dist/index.html .

Я, наконец, наткнулся на html-webpack-plugin, как описано в этом руководстве.

Скринкаст по Webpack

Webpack — один из самых мощных и гибких инструментов для сборки frontend.

Вместе с тем, он достаточно сложен, а документация оставляет желать много лучшего.

Поэтому я записал этот скринкаст о том, как его использовать.

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

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

В первых частях скринкаста используется модуль babel-loader версии 5, который ставится через «npm i [email protected]» .

Текущая версия это Babel 7. Чтобы её использовать, поставьте несколько модулей:

Затем замените настройки babel-loader’а в конфиге на такие (для адаптации под браузеры с долей более 3%):

Добавить комментарий