Что такое 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 проанализирует файлы и объединит их в один выходной JavaScript-файл, содержащий все необходимое для запуска приложения.
Установка Webpack
Webpack может быть установлен глобально или локально для каждого проекта.
Глобальная установка
Глобальная установка с помощью Yarn:
yarn global add webpack webpack-cli
npm i -g webpack webpack-cli
Теперь мы можем запустить webpack:
webpack-cli
Локальная установка
Это рекомендуемый способ установки, поскольку Webpack может обновляться каждый проект и у вас возникнет меньше проблем при использовании последних функций для одного небольшого проекта, нежели постоянное обновление всех проектов, в которых используется Webpack.
Установка с помощью Yarn:
yarn add webpack webpack-cli -D
npm i webpack webpack-cli --save-dev
После этого добавьте эти строчки в свой package.json файл:
<
//.
"scripts": <
"build": "webpack"
>
>
Как только все будет сделано, вы можете запустить Webpack, набрав:
yarn build
в корневом каталоге проекта.
Настройка Webpack
По умолчанию, Webpack (начиная с 4-й версии) не требует никакой настройки, если вы соблюдаете эти правила:
- точкой входа вашего приложения является ./src/index.js
- вывод (output) размещается в ./dist/main.js
- Webpack работает в production mode (режим производства)
Конечно, если понадобится, вы сможете настроить каждую мельчайшую деталь в Webpack. Конфигурационный файл Webpack — webpack.config.js хранится в корневой директории проекта.
Точка входа
По умолчанию, точкой входа является ./src/index.js . Нижеприведенный пример использует файл ./index.js в качестве входной точки.
module.exports = /*. */
entry: './index.js'
/*. */
>
Вывод (output)
По умолчанию, вывод размещается в ./dist/main.js . В нижеприведенном примере, результат работы в Webpack генерируется в файле app.js :
module.exports = /*. */
output: path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
>
/*. */
>
С помощью Webpack можно использовать оператор import или require в своем JavaScript коде для того, чтобы подключать файлы любого типа (например, CSS).
В Webpack загрузчики являются аналогами задач (tasks) в Grunt и Gulp. Они принимают содержимое файлов, а затем преобразуют его необходимым образом и включают результат преобразования в общую сборку. Например, они могут компилировать TypeScript, загружать компоненты Vue.js и многое другое.
Например, в своем коде вы можете использовать:
import 'style.css'
указав конфигурацию данного загрузчика в файле webpack.config.js :
module.exports = /*. */
module: rules: [
< test: /\.css$/, use: 'css-loader' >,
>]
>
/*. */
>
Регулярное выражение применяет данный загрузчик только к CSS файлам.
У загрузчика есть параметры:
module.exports = /*. */
module: rules: [
test: /\.css$/,
use: [
loader: 'css-loader',
options: modules: true
>
>
]
>
]
>
/*. */
>
Для одной и той же задачи может потребоваться несколько загрузчиков:
module.exports = /*. */
module: rules: [
test: /\.css$/,
use:
[
'style-loader',
'css-loader',
]
>
]
>
/*. */
>
В этом примере css-loader интерпретирует директиву import ‘style.css’ в CSS. Затем style-loader внедряет этот CSS в DOM, используя тег .
Порядок выполнения перевернут (последнее выполняется первым).
Так сколько всего существует загрузчиков? Очень много! Здесь вы сможете найти полный список.
Самым часто используемым загрузчиком является Babel — он используется для транспиляции современного JavaScript в ES5:
module.exports = /*. */
module: rules: [
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: loader: 'babel-loader',
options: presets: ['@babel/preset-env']
>
>
>
]
>
/*. */
>
Данный пример заставляет Babel предварительно обрабатывать все наши React/JSX файлы:
module.exports = /*. */
module: rules: [
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
>
]
>,
resolve: extensions: [
'.js',
'.jsx'
]
>
/*. */
>
Здесь вы можете увидеть параметры babel-loader .
Плагины
Плагины — это почти то же самое, что и загрузчики, но под стероидами. Они могут сделать то, что не могут загрузчики. Ко всему прочему, Webpack построен на системе плагинов, которые вы используете в своем файле конфигурации.
Рассмотрим следующий пример:
module.exports = /*. */
plugins: [
new HTMLWebpackPlugin()
]
/*. */
>
Плагин HTMLWebpackPlugin автоматически создает HTML-файл с уже подключенным скриптом.
Здесь доступно множество плагинов.
Еще один полезный плагин, CleanWebpackPlugin , мы можем использовать перед перегенерацией файлов, чтобы очистить нашу папку dist/ и получить аккуратный файл с конфигурацией.
module.exports = /*. */
plugins: [
new CleanWebpackPlugin(['dist']),
]
/*. */
>
Режимы Webpack
Данные режимы (появившиеся в 4-й версии Webpack) настраивают среду, в которой будет работать Webpack. Режим может быть настроен на development или production (по умолчанию стоит production ).
module.exports = entry: './index.js',
mode: 'development',
output: path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
>
>
- менее оптимизирован, чем production
- работает быстрее
- не удаляет комментарии
- предоставляет более подробные сообщения об ошибках и способы их решения
- сильно облегчает отладку
Режим production работает медленнее, чем development , так как ему нужно создать более оптимизированный бандл. Полученный JavaScript файл меньше по размеру, поскольку многое из режима development в нем отсутствует.
Я написал небольшое приложение, которое выводит содержимое console.log .
Вот бандл production :
Вот бандл development :
Запуск Webpack
Если Webpack установлен глобально, его можно вручную запустить из командной строки. Но, обычно, вы прописываете скрипт внутри файла package.json , который затем запускаете через npm или yarn .
Например, эти package.json скрипты, которые мы использовали ранее:
"scripts": "build": "webpack"
>
позволяют запускать webpack , набрав:
npm run build
yarn run build
yarn build
Просмотр изменений
Webpack может автоматически перестраивать бандл, когда в вашем приложении происходят изменения. Для этого добавьте данный скрипт:
"scripts": "watch": "webpack --watch"
>
и запустите данную функцию:
npm run watch
yarn run watch
yarn watch
Одной из приятных особенностей watch mode (режима просмотра) является то, что бандл изменяется только в том случае, если в сборке нет ошибок. Если ошибки присутствуют, watch продолжит следить за изменениями и будет пытаться перестраивать бандл, но текущий, рабочий бандл не зависит от проблемных бандлов.
Обработка изображений
С помощью Webpack можно очень удобно работать с изображениями, используя загрузчик file-loader .
Эта простая конфигурация:
module.exports = /*. */
module: rules: [
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
>
]
>
/*. */
>
Позволяет импортировать изображения в ваш JavaScript:
import Icon from './icon.png'const img = new Image()
img.src = Icon
element.appendChild(img)
Где img — это HTMLImageElement. Ознакомьтесь с документацией по Image().
file-loader может обрабатывать и другие типы ассетов, например, шрифты, CSV-файлы, XML и т.д.
Еще одним приятным инструментом для работы с изображениями является url-loader загрузчик.
В этом примере загружается любой PNG-файл размером менее 8 КБ в качестве data:URL.
module.exports = /*. */
module: rules: [
test: /\.png$/,
use: [
loader: 'url-loader',
options: limit: 8192
>
>
]
>
]
>
/*. */
>
Обработайте SASS код и преобразуйте его в CSS
Используйте sass-loader , css-loader и style-loader :
module.exports = /*. */
module: rules: [
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
>
]
>
/*. */
>
Генерация Source Maps
С транспилированным кодом, зачастую, возникают проблемы при отладке кода в браузере или анализе ошибок. Так как транспилированный и трудночитаемый JavaScript, а не оригинальный код, затрудняет поиск и исправление ошибок. Source Map — это JSON-файл, который содержит информацию о том, как транспилировать код обратно в исходный код.
Source Maps можно сгенерировать, используя свойство конфигурации devtool :
module.exports = /*. */
devtool: 'inline-source-map',
/*. */
>
devtool имеет множество возможных значений, из которых наиболее часто используемые:
- none : не добавляет Source Maps
- source-map : идеально подходит для режима production , предоставляет отдельную Source Map, которую можно свернуть и добавляет ссылку в бандл, чтобы инструменты разработки знали о том, что Source Map доступна
- inline-source-map : идеально подходит для режима development , встраивает Source Maps в качестве data:URL
Конфигурирование Babel
Babel автоматически конфигурируется для всех файлов .js и .jsx через babel-loader с благоразумными значениями по умолчанию (например, с @babel/preset-env и @babel/preset-react , по запросу).
Вам нужно ещё больше расширить конфигурацию Babel? Самый лёгкий способ сделать это — через configureBabel() :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// webpack.config.js // . Encore // . .configureBabel(function(babelConfig) < // добавить дополнительные пресеты babelConfig.presets.push('@babel/preset-flow'); // по умолчанию плагины не добавляются, но вы можете их добавить babelConfig.plugins.push('styled-jsx/babel'); >, < // node_modules не обрабатывается через Babel по умолчанию, // но вы можете позволить обработку каких-то конкретных модулей includeNodeModules: ['foundation-sites'], // или полностью контролировать правило исключения (заметьте, что вы не // можете использовать "includeNodeModules" и "exclude" одновременно) exclude: /bower_components/ >) ;
Конфигурация целей браузера
Пресет @babel/preset-env переписывает ваш JavaScript, чтобы финальный синтаксис работал в любом браузере, который вы захотите. Чтобы сконфигурировать браузеры, которые вам нужно поддерживать, см. PostCSS и автоматическое добавление префиксов (postcss-loader).
После изменения вашей конфигурации «browserslist», вам понадобится вручную удалить каталог кеша babel:
# В Unix запустите эту команду. В Windows, очистите этот каталог вручную $ rm -rf node_modules/.cache/babel-loader/
Создание файла .babelrc
Вместо того, чтобы вызывать configureBabel() , вы можете создать файл .babelrc в корне вашего проекта. Это более «стандартный» способ конфигурации Babel, но у него есть недостатки: как только появляется файл .babelrc , Encore больше не может добавлять никакую конфигурацию Babel для вас. Например, если вы вызовете Encore.enableReactPreset() , предустановка react не будет автоматически добавлена в Babel: вы должны будете добавить её сами в .babelrc .
Как только файл .babelrc будет существовать, он будет главенствовать над конфигурацией Babel, добавленной Encore.
Symfony is a trademark of Symfony SAS. Переклад — Playtini. UA RU RU EN
Config Files
Babel has two parallel config file formats, which can be used together, or independently.
| Version | Changes |
|---|---|
| v7.21.0 | Support .babelrc.cts and babel.config.cts (Experimental) |
| v7.8.0 | Support .babelrc.mjs and babel.config.mjs |
| v7.7.0 | Support .babelrc.json , .babelrc.cjs , babel.config.json , babel.config.cjs |
- Project-wide configuration
- babel.config.* files, with the following extensions: .json , .js , .cjs , .mjs , .cts .
- .babelrc.* files, with the following extensions: .json , .js , .cjs , .mjs , .cts .
- .babelrc file, with no extension.
- package.json files, with a «babel» key.
Project-wide configuration
New in Babel 7.x, Babel has a concept of a «root» directory, which defaults to the current working directory. For project-wide configuration, Babel will automatically search for a babel.config.json file, or an equivalent one using the supported extensions, in this root directory. Alternatively, users can use an explicit «configFile» value to override the default config file search behavior.
Because project-wide config files are separated from the physical location of the config file, they can be ideal for configuration that must apply broadly, even allowing plugins and presets to easily apply to files in node_modules or in symlinked packages, which were traditionally quite painful to configure in Babel 6.x.
The primary downside of this project-wide config is that, because it relies on the working directory, it can be more painful to use in monorepos if the working directory is not the monorepo root. See the monorepo documentation for examples of how to use config files in that context.
Project-wide configs can also be disabled by setting «configFile» to false .
File-relative configuration
Babel loads .babelrc.json files, or an equivalent one using the supported extensions, by searching up the directory structure starting from the «filename» being compiled (limited by the caveats below). This can be powerful because it allows you to create independent configurations for subsections of a package. File-relative configurations are also merged over top of project-wide config values, making them potentially useful for specific overrides, though that can also be accomplished through «overrides».
There are a few edge cases to consider when using a file-relative config:
- Searching will stop once a directory containing a package.json is found, so a relative config only applies within a single package.
- The «filename» being compiled must be inside of «babelrcRoots» packages, or else searching will be skipped entirely.
These caveats mean that:
- .babelrc.json files only apply to files within their own package
- .babelrc.json files in packages that aren’t Babel’s ‘root’ are ignored unless you opt in with «babelrcRoots».
See the monorepo documentation for more discussion on how to configure monorepos that have many packages. File-relative configs can also be disabled by setting «babelrc» to false .
6.x vs 7.x .babelrc loading
Users coming from Babel 6.x will likely trip up on these two edge cases, which are new in Babel 7.x. These two restrictions were added to address common footguns in Babel 6.x:
- .babelrc files applied to node_modules dependencies, often unexpectedly.
- .babelrc files failed to apply to symlinked node_modules when people expected them to behave like normal dependencies.
- .babelrc files in node_modules dependencies would be detected, even though the plugins and presets inside they were generally not installed, and may not even be valid in the version of Babel compiling the file.
These cases will primarily cause issues for users with a monorepo structure, because if you have
.babelrc packages/ mod1/ package.json src/index.js mod2/ package.json src/index.jsthe config will now be entirely ignored, because it is across a package boundary.
One alternative would be to create a .babelrc in each sub-package that uses «extends» as
.babelrc.json
Unfortunately, this approach can be a bit repetitive, and depending on how Babel is being used, could require setting «babelrcRoots».
Given that, it may be more desirable to rename the .babelrc to be a project-wide «babel.config.json». As mentioned in the project-wide section above, this may then require explicitly setting «configFile» since Babel will not find the config file if the working directory isn’t correct.
Supported file extensions
Babel can be configured using any file extension natively supported by Node.js, as mentioned in Configuration File Types section:
- babel.config.json and .babelrc.json are parsed as JSON5 and should contain an object matching the options format that Babel accepts. They have been supported since v7.7.0 . We recommend using this file type wherever possible: JS config files are handy if you have complex configuration that is conditional or otherwise computed at build time. However, the downside is that JS configs are less statically analyzable, and therefore have negative effects on cacheability, linting, IDE autocomplete, etc. Since babel.config.json and .babelrc.json are static JSON files, it allows other tools that use Babel such as bundlers to cache the results of Babel safely, which can be a huge build performance win.
- babel.config.cjs and .babelrc.cjs allow you to define your configuration as CommonJS, using module.exports . They have been supported since v7.7.0 .
- babel.config.mjs and .babelrc.mjs use native ECMAScript modules. They are supported by Node.js 13.2+ (or older versions via the —experimental-modules flag). Please remember that native ECMAScript modules are asynchronous (that’s why import() always returns a promise!): for this reason, .mjs config files will throw when calling Babel synchronously. They have been supported since v7.8.0 .
- babel.config.js and .babelrc.js behave like the .mjs equivalents when your package.json file contains the «type»: «module» option, otherwise they are exactly the same as the .cjs files.
- babel.config.cts and .babelrc.cts allow you to define your configuration as Typescript + CommonJS. You must either install @babel/preset-typescript , or run Babel using ts-node .
This functionality is experimental. It’s not possible yet to use babel.config.ts and babel.config.mts files, pending stabilization of the Node.js ESM loader API.
JavaScript configuration files can either export an object, or a function that when called will return the generated configuration. Function-returning configs are given a few special powers because they can access an API exposed by Babel itself. See Config Function API for more information.
For compatibility reasons, .babelrc is an alias for .babelrc.json .
Monorepos
Monorepo-structured repositories usually contain many packages, which means that they frequently run into the caveats mentioned in file-relative configuration and config file loading in general. This section is aimed at helping users understand how to approach monorepo configuration.
With monorepo setups, the core thing to understand is that Babel treats your working directory as its logical «root», which causes problems if you want to run Babel tools within a specific sub-package without having Babel apply to the repo as a whole.
Separately, it is also important to decide if you want to use .babelrc.json files or just a central babel.config.json . .babelrc.json files are not required for subfolder-specific configuration like they were in Babel 6, so often they are not needed in Babel 7, in favor of babel.config.json .
Root babel.config.json file
The first step in any monorepo structure should be to create a babel.config.json file in repository root. This establishes Babel’s core concept of the base directory of your repository. Even if you want to use .babelrc.json files to configure each separate package, it is important to have as a place for repo-level options.
You can often place all of your repo configuration in the root babel.config.json . With «overrides», you can easily specify configuration that only applies to certain subfolders of your repository, which can often be easier to follow than creating many .babelrc.json files across the repo.
The first issue you’ll likely run into is that by default, Babel expects to load babel.config.json files from the directory set as its «root», which means that if you create a babel.config.json , but run Babel inside an individual package, e.g.
cd packages/some-package; babel src -d distthe «root» Babel is using in that context is not your monorepo root, and it won’t be able to find the babel.config.json file.
If all of your build scripts run relative to your repository root, things should already work, but if you are running your Babel compilation process from within a subpackage, you need to tell Babel where to look for the config. There are a few ways to do that, but the recommended way is the «rootMode» option with «upward» , which will make Babel search from the working directory upward looking for your babel.config.json file, and will use its location as the «root» value.
One helpful way to test if your config is being detected is to place a console.log() call inside of it if it is a babel.config.json JavaScript file: the log will execute the first time Babel loads it.
How you set this value varies by project, but here are a few examples:
CLI
babel --root-mode upward src -d libИспользование Babel и Webpack для настройки React-проекта с нуля
Существует немало инструментов, позволяющих подготовить среду для React-разработки. Например, в наших материалах учебного курса по React используется средство create-react-app, позволяющее создать шаблонный проект, содержащий всё необходимое для разработки React-приложений. Автор статьи, перевод которой мы публикуем сегодня, хочет рассказать о том, как самостоятельно настроить окружение для разработки React-проектов с использованием Babel и Webpack. Эти инструменты используются и в проектах, создаваемых средствами create-react-app, и мы полагаем, что всем, кто изучает React-разработку, интересно будет познакомиться с ними и с методикой создания React-проектов на более глубоком уровне. А именно, речь пойдёт о том, как сконфигурировать Webpack таким образом, чтобы это средство использовало бы Babel для компиляции JSX-кода в JavaScript-код, и как настроить сервер, используемый при разработке React-проектов.
Webpack
Webpack используется для компиляции JavaScript-модулей. Этот инструмент часто называют «бандлером» (от bundler) или «сборщиком модулей». После его установки работать с ним можно, используя интерфейс командной строки или его API. Если вы не знакомы с Webpack — рекомендуется почитать об основных принципах его работы и посмотреть его сравнение с другими сборщиками модулей. Вот как, на высоком уровне, выглядит то, что делает Webpack.

Работа Webpack
Webpack берёт всё, от чего зависит проект, и преобразует это в статические ресурсы, которые могут быть переданы клиенту. Упаковка приложений — это очень важно, так как большинство браузеров ограничивает возможности по одновременной загрузке ресурсов. Кроме того, это позволяет экономить трафик, отправляя клиенту лишь то, что ему нужно. В частности, Webpack использует внутренний кэш, благодаря чему модули загружаются на клиент лишь один раз, что, в итоге, приводит к ускорению загрузки сайтов.
Babel
Babel — это транспилятор, который, в основном, используется для преобразования конструкций, принятых в свежих версиях стандарта ECMAScript, в вид, понятный как современным, так и не самым новым браузерам и другим средам, в которых может выполняться JavaScript. Babel, кроме того, умеет преобразовывать в JavaScript и JSX-код, используя @babel/preset-react.

Именно благодаря Babel мы, при разработке React-приложений, можем пользоваться JSX. Например, вот код, в котором используется JSX:
import React from "react"; function App() < return(Hello world!) > export default App;Выглядит такой код аккуратно, он понятен, его легко читать и редактировать. Глядя на него, сразу можно понять, что он описывает компонент, возвращающий элемент , в котором содержится текст Hello world! , выделенный жирным шрифтом. А вот пример кода, делающего то же самое, в котором JSX не используется:
"use strict"; Object.defineProperty(exports, "__esModule", < value: true >); var _react = require("react"); var _react2 = _interopRequireDefault(_react); function _interopRequireDefault(obj) < return obj && obj.__esModule ? obj : < default: obj >; > function App(props) < return _react2.default.createElement( "div", null, _react2.default.createElement( "b", null, "Hello world!" ) ); >exports.default = App;Преимущества первого примера перед вторым очевидны.
Предварительные требования
Для того чтобы настроить проект React-приложения, нам понадобятся следующие npm-модули.
- react — библиотека React.
- react-dom — библиотека, которая поможет нам использовать возможности React в браузере.
- babel/core — транспиляция JSX в JS.
- babel/preset-env — создание кода, подходящего для старых браузеров.
- babel/preset-react — настройка транспилятора для работы с React-кодом.
- babel-loader — настройка Webpack для работы с Babel.
- css-loader — настройка Webpack для работы с CSS.
- webpack — сборка модулей.
- webpack-cli — работа с Webpack из командной строки.
- style-loader — загрузка всего используемого CSS-кода в заголовке HTML-файла.
- webpack-dev-server — настройка сервера разработки.
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader webpack webpack-cli style-loader webpack-dev-serverТочкой входа в программу будет файл index.js , который содержится в папке src , находящейся в корневой директории проекта. Ниже показана структура этого проекта. Некоторые файлы и папки создаются автоматически, некоторые вам нужно будет создать самостоятельно.

Структура проекта
Готовый проект, которым мы будем здесь заниматься, можно найти в этом репозитории.
Папка component будет содержать компоненты проекта (в нашем случае тут присутствует лишь один компонент). В папке dist , в файле main.js , будет находиться скомпилированный код, а index.html — это, как уже было сказано, главный HTML-файл нашего приложения.
Настройка Webpack
Webpack можно настраивать разными способами. В частности, настройки этого инструмента могут принимать вид аргументов командной строки или присутствовать в проекте в виде конфигурационного файла с именем webpack.config.js . В нём нужно описать и экспортировать объект, содержащий настройки. Мы начнём настройку этого файла с описания объекта, выглядящего так (мы будем рассматривать его по частям, а ниже приведём его полный код):
Свойство entry задаёт главный файл с исходным кодом проекта. Значение свойства mode указывает на тип окружения для компиляции (в нашем случае это окружение разработки — development ) и на то, куда нужно поместить скомпилированный файл.
Работа над проектом
Поместим в файл index.html нашего проекта, расположенный в папке dist , следующий код:
React From Scratch Обратите внимание на тег script , присутствующий в этом файле. Он указывает на файл main.js , который будет получен в ходе компиляции проекта. Элемент с идентификатором root мы будем использовать для вывода React-приложения.
Теперь установим пакеты react и react-dom:
npm install react react-domВнесём в index.js следующий код:
import React, < Component >from "react"; import ReactDOM from "react-dom"; import App from "./component/app.component"; ReactDOM.render(, document.querySelector("#root"));Это — стандартный код для подобных файлов React-приложений. Тут мы подключаем библиотеки, подключаем файл компонента и выводим приложение в тег с идентификатором root .
Вот код файла app.component.js :
import React, < Component >from "react"; import s from "./app.component.css"; class MyComponent extends Component < render() < return>Hello World; > > export default MyComponent;Вот код файла app.component.css :
.intro
Настройка Babel
Babel — это транспилятор, обладающий огромными возможностями. В частности, он умеет преобразовывать LESS в CSS, JSX в JS, TypeScript в JS. Мы будем использовать с ним лишь две конфигурации — react и env (их ещё называют «пресетами»). Babel можно настраивать по-разному, в частности, речь идёт о средствах командной строки, о специальном файле с настройками, о стандартном файле package.json . Нас устроит последний вариант. Добавим в package.json следующий раздел:
"babel": < "presets": [ "@babel/env", "@babel/react" ] >Благодаря этим настройкам Babel будет знать о том, какие пресеты ему нужно использовать. Теперь настроим Webpack на использование Babel.
Настройка Webpack на работу с Babel
Тут мы воспользуемся библиотекой babel-loader, которая позволит использовать Babel с Webpack. Фактически, речь идёт о том, что Babel сможет перехватывать и обрабатывать файлы до их обработки Webpack.
▍JS-файлы
Вот правила, касающиеся работы с JS-файлами (этот код пойдёт в файл webpack.config.js ), они представляют собой одно из свойств объекта с настройками, экспортируемого этим файлом:
module: < rules: [ < test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: < loader: "babel-loader" >>, ] >В свойстве rules представленного здесь объекта хранится массив правил, в соответствии с которыми должен быть обработан файл, заданный регулярным выражением, описанным в свойстве test . В данном случае правило будет применяться ко всем файлам с расширениями .m и .js , при этом файлы из папок node_modules и bower_components мы транспилировать не хотим. Далее, тут мы указываем, что мы хотим пользоваться babel-loader. После этого наши JS-файлы будут сначала обрабатываться средствами Babel, а потом упаковываться с помощью Webpack.
▍CSS-файлы
Добавим в массив rules объекта module настройки для обработки CSS-файлов:
module: < rules: [ < test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: < loader: "babel-loader" >>, < test: /\.css$/, use: [ "style-loader", < loader: "css-loader", options: < modules: true >> ] >, ] >Задачу обработки CSS-файлов мы будем решать средствами style-loader и css-loader. Свойство use может принимать массив объектов или строк. Загрузчики вызываются, начиная с последнего, поэтому наши файлы сначала будут обработаны с помощью css-loader. Мы настроили это средство, записав в свойство modules объекта options значение true . Благодаря этому CSS-стили будут применяться лишь к тем компонентам, в которые они импортированы. Css-loader разрешит команды импорта в CSS-файлах, после чего style-loader добавит то, что получится, в форме тега style , в разделе страницы:
▍Статические ресурсы
Продолжим работу над объектом настроек module , описав в нём правила обработки статических ресурсов:
module: < rules: [ < test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: < loader: "babel-loader" >>, < test: /\.css$/, use: [ "style-loader", < loader: "css-loader", options: < modules: true >> ] >, < test: /\.(png|svg|jpg|gif)$/, use: ["file-loader"] >] >Если система встретит файл с расширением PNG, SVG, JPG или GIF, то для обработки такого файла будет использован file-loader. Обработка таких файлов важна для правильной подготовки и оптимизации проекта.
Настройка сервера разработки
Теперь, в файле webpack.config.js , настроим сервер разработки:
devServer: < contentBase: path.join(__dirname, "dist"), compress: true, port: 9000, watchContentBase: true, progress: true >,Свойство contentBase объекта с настройками devServer указывает на папку, в которой расположены наши ресурсы и файл index.html . Свойство port позволяет задать порт, который будет прослушивать сервер. Свойство watchContentBase позволяет реализовать наблюдение за изменениями файлов в папке, задаваемой свойством contentBase .
Вот полный код файла webpack.config.js :
const path = require("path"); module.exports = < entry: "./src/index.js", mode: "development", output: < filename: "./main.js" >, devServer: < contentBase: path.join(__dirname, "dist"), compress: true, port: 9000, watchContentBase: true, progress: true >, module: < rules: [ < test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: < loader: "babel-loader" >>, < test: /\.css$/, use: [ "style-loader", < loader: "css-loader", options: < modules: true >> ] >, < test: /\.(png|svg|jpg|gif)$/, use: ["file-loader"] >] > >;Теперь внесём в package.json , в раздел scripts , команду для запуска сервера разработки и команду для запуска сборки проекта:
"scripts": < "dev": "webpack-dev-server", "start": "webpack" >,Сейчас всё готово к тому, чтобы запустить сервер разработки следующей командой:
npm run devЕсли теперь перейти по адресу http://localhost:9000, можно будет увидеть страницу нашего проекта.

Страница проекта в браузере
Для того чтобы собрать проект воспользуйтесь следующей командой:
npm run startПосле этого можно будет открыть файл index.html в браузере и увидеть то же самое, что можно было видеть, запустив сервер разработки и перейдя по адресу http://localhost:9000.
Итоги
В этом материале приведён обзор настройки Webpack и Babel для их использования в React-проектах. На самом деле, на той базе, которую мы сегодня разобрали, можно создавать гораздо более сложные конфигурации. Например, вместо CSS можно воспользоваться LESS, вместо обычного JS писать на TypeScript. При необходимости можно, например, настроить минификацию файлов и многое другое. Конечно, если сегодня состоялось ваше первое знакомство с процессом самостоятельной настройки React-проектов, вам может показаться, что всё это очень сложно и куда легче воспользоваться готовым шаблоном. Однако после того, как вы немного в этом разберётесь, вы поймёте, что некоторое увеличение сложности настроек даёт вам большую свободу, позволяя настраивать свои проекты именно так, как вам это нужно, не полагаясь полностью на некие «стандартные» решения и снизив свою зависимость от них.
Уважаемые читатели! Какой подход вы чаще всего используете при подготовке рабочей среды для React-проектов?