{"id":352149,"date":"2024-05-20T22:03:02","date_gmt":"2024-05-20T22:03:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=352149"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=352149","title":{"rendered":"<span>React starter (Webpack + Typescript + Css modules + Jest)<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/12f\/5e2\/d56\/12f5e2d568dad7b0c8e56d537e7167c0.jpg\" alt=\"Webpack 5\" title=\"Webpack 5\" width=\"960\" height=\"589\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/12f\/5e2\/d56\/12f5e2d568dad7b0c8e56d537e7167c0.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>Webpack<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u0432\u0438\u0434\u0435\u043d\u0438\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 React.<\/p>\n<p>\u041f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e &#171;\u043d\u0430 \u0441\u043a\u043e\u0440\u0443\u044e&#187; \u0432\u043e\u0439\u0442\u0438 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<p>\u0427\u0442\u043e-\u0442\u043e \u044f \u043f\u043e\u0434\u0433\u043b\u044f\u0434\u0435\u043b \u0437\u0434\u0435\u0441\u044c \u0436\u0435, \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u043f\u0440\u0438\u0448\u0451\u043b \u0441\u0430\u043c, \u043d\u0443 \u0438 &#171;\u0430\u043d\u0433\u0430\u0436\u0438\u0440\u043e\u0432\u0430\u043b&#187; \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 &#171;\u043d\u0435\u043e\u0431\u044a\u044f\u0442\u043d\u043e\u0433\u043e&#187;.<\/p>\n<p>\u0426\u0435\u043b\u044c \u043f\u043e\u0441\u0442\u0430 &#8212; \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u043c\u043d\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0437\u043d\u0430\u0442\u044c \u043f\u0440\u043e \u0431\u0440\u0435\u0448\u044c.<\/p>\n<p>\u041f\u043e\u0435\u0445\u0430\u043b\u0438.<\/p>\n<h2>\u0427\u0442\u043e &#171;\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c&#187;<\/h2>\n<ol>\n<li>\n<p>Webpack 5<\/p>\n<\/li>\n<li>\n<p>React v.18<\/p>\n<\/li>\n<li>\n<p>Redux (Redux Toolkit)<\/p>\n<\/li>\n<li>\n<p>Typescript<\/p>\n<\/li>\n<li>\n<p>Css modules<\/p>\n<\/li>\n<li>\n<p>Jest<\/p>\n<\/li>\n<li>\n<p>VS Code<\/p>\n<\/li>\n<\/ol>\n<h2>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 <\/h2>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0448\u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cf0\/994\/4de\/cf09944def1e4b749fd1484fd46e8261.png\" width=\"359\" height=\"704\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cf0\/994\/4de\/cf09944def1e4b749fd1484fd46e8261.png\"\/><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">__jest__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 Jest<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">__tests__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043f\u043a\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043b\u0435\u0436\u0430\u0442 \u0442\u0435\u0441\u0442\u044b. \u0414\u0430, \u044f \u0437\u043d\u0430\u044e \u0447\u0442\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f (\u0443\u0434\u043e\u0431\u043d\u043e) \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c. \u041a\u043e\u043d\u0444\u0438\u0433 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u043e\u0434\u0445\u043e\u0434 \u0441 \u0432\u044b\u043d\u043e\u0441\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0442\u043e\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0435 \u0448\u0430\u043d\u0441\u044b \u0431\u044b\u0442\u044c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">__webpack__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 Webpack<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">build<\/p>\n<\/td>\n<td>\n<p align=\"left\">Output \u043f\u0430\u043f\u043a\u0430 c \u0431\u0430\u043d\u0434\u043b\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">.vscode<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043f\u043a\u0430, \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 VS Code. \u0412\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0432 \u043d\u0438\u0445 \u043f\u043e\u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/36f\/eef\/e65\/36feefe65c1e3f6848665de8b1627405.png\" width=\"357\" height=\"685\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/36f\/eef\/e65\/36feefe65c1e3f6848665de8b1627405.png\"\/><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">public<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0430\u0442 \u0444\u0430\u0439\u043b\u044b, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">static<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0430\u0442 \u0444\u0430\u0439\u043b\u044b, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0441 \u043a\u043e\u0434\u043e\u043c. \u0417\u0434\u0435\u0441\u044c \u0442\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0432\u043e\u043b\u0448\u0435\u0431\u0441\u0442\u0432\u043e.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/core<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0443\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, state-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440. <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/pages<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/routes<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u0440\u043e\u0443\u0442\u043e\u0432 (\u0435\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c Webpack<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 dev \u0438 prod \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f (\u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c) \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0440\u0435\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (dev, \u043b\u0438\u0431\u043e prod).<\/p>\n<p><a href=\"https:\/\/webpack.js.org\/guides\/production\/\" rel=\"noopener noreferrer nofollow\"><u>\u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435<\/u><\/a><\/p>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 __webpack__ \u0431\u044b\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b 3 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>common.config.js<\/p>\n<\/li>\n<li>\n<p>dev.config.js<\/p>\n<\/li>\n<li>\n<p>prod.config.js<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0432\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u043f\u0435\u0440\u0432\u044b\u0439.<\/p>\n<p><strong>common.config.js<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c webpack<\/summary>\n<div class=\"spoiler__content\">\n<blockquote>\n<p>npm i &#8212;save -D webpack webpack-cli webpack-dev-server<\/p>\n<\/blockquote>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u043d\u043e\u0441\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">const webpack = require(\"webpack\"); const path = require(\"path\");  const BUILD_DIR = path.resolve(__dirname, \"..\", \"build\"); const PUBLIC_DIR = path.resolve(__dirname, \"..\", \"public\"); const STATIC_DIR = path.resolve(__dirname, \"..\", \"static\");<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 Dev-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D mini-css-extract-plugin html-webpack-plugin favicons-webpack-plugin @pmmmwh\/react-refresh-webpack-plugin filemanager-webpack-plugin<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">mini-css-extract-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0444\u0430\u0439\u043b CSS \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 JS, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e CSS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/mini-css-extract-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/mini-css-extract-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">html-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c \u0444\u0430\u0439\u043b\u044b \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 index.html  <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/\" rel=\"noopener noreferrer nofollow\">https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">favicons-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0430\u0432\u0438\u043a\u043e\u043d\u043e\u043a.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/favicons-webpack-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/favicons-webpack-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">favicons<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f favicons-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/favicons\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/favicons<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">@pmmmwh\/react-refresh-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 React \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u0434\u0430. Hot Reload. <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package<\/a><a class=\"mention\" href=\"\/users\/pmmmwh\">@pmmmwh<\/a>h\/react-refresh-webpack-plugin<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">react-refresh<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c Webpack \u0434\u043b\u044f &#171;\u0413\u043e\u0440\u044f\u0447\u0435\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438&#187;<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/react-refresh\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/react-refresh<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">filemanager-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c, \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 \u0434\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/filemanager-webpack-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/filemanager-webpack-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<details class=\"spoiler\">\n<summary>\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const MiniCssExtractPlugin = require(\"mini-css-extract-plugin\"); const HtmlWebpackPlugin = require(\"html-webpack-plugin\"); const FaviconsWebpackPlugin = require(\"favicons-webpack-plugin\"); const ReactRefreshWebpackPlugin = require(\"@pmmmwh\/react-refresh-webpack-plugin\"); const FileManagerPlugin = require(\"filemanager-webpack-plugin\");  const plugins = [   new FileManagerPlugin({     events: {       \/\/ Remove build dir       onStart: {         delete: [BUILD_DIR],       },       onEnd: {         \/\/ Copy static files         copy: [           {             source: STATIC_DIR,             destination: BUILD_DIR,           },         ],       },     },   }),   new HtmlWebpackPlugin({     template: path.join(PUBLIC_DIR, \"index.html\"),     filename: \"index.html\",   }),   \/\/   new FaviconsWebpackPlugin({     logo: path.resolve(PUBLIC_DIR, \"favicon.svg\"),     prefix: \"\/favicons\/\",     outputPath: path.resolve(BUILD_DIR, \"favicons\"),     mode: \"webapp\",     \/\/ Injecting into all HTML Files or separately (for an every instance of HtmlWebpackPlugin)     \/\/ inject: true,     inject: (htmlPlugin) =>       path.basename(htmlPlugin.options.filename) === \"index.html\",     favicons: {       icons: {         appleIcon: false, \/\/ Apple touch icons.         appleStartup: false, \/\/ Apple startup images.         android: false, \/\/ Android homescreen icon.         favicons: true, \/\/ Regular favicons.         coast: false, \/\/ Opera Coast icon.         firefox: false, \/\/ Firefox OS icons.         windows: false, \/\/ Windows 8 tile icons.         yandex: false, \/\/ Yandex browser icon.       },     },     cache: false, \/\/ Disallow caching the assets across webpack builds.   }),   new webpack.HotModuleReplacementPlugin(), \/\/ For page reloading ];  if (process.env.SERVE) {   plugins.push(new ReactRefreshWebpackPlugin()); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<hr\/>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Dev Server<\/p>\n<pre><code class=\"javascript\">const devServer = {   historyApiFallback: true, \/\/ Apply HTML5 History API if routes are used   open: true,   compress: true,   allowedHosts: \"all\",   hot: true, \/\/ Reload the page after changes saved (HotModuleReplacementPlugin)   client: {     \/\/ Shows a full-screen overlay in the browser when there are compiler errors or warnings     overlay: {       errors: true,       warnings: true,     },     progress: true, \/\/ Prints compilation progress in percentage in the browser.   },    port: 3000,   \/**    * Writes files to output path (default: false)    * Build dir is not cleared using &lt;output: {clean:true}>    * To resolve should use FileManager    *\/   devMiddleware: {     writeToDisk: true,   },   static: [     \/\/ Required to use favicons located in a separate directory as assets     \/\/ Should use with historyApiFallback, to avoid of 404 for routes     {       directory: path.join(BUILD_DIR, \"favicons\"),     },   ], };<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 devMiddleware. \u0410 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"javascript\">writeToDisk: true<\/code><\/pre>\n<p>\u041e\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <strong>dev server<\/strong> \u043d\u0430 \u0434\u0438\u0441\u043a. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u043e\u0435.<\/p>\n<p>\u041d\u043e \u0442\u0443\u0442 \u0436\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u0411\u0438\u043b\u0434 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f File Manager \u043f\u043b\u0430\u0433\u0438\u043d, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u0435, \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"javascript\">events: {       \/\/ Remove build dir       onStart: {         delete: [BUILD_DIR],       }, }<\/code><\/pre>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0445\u043e\u0447\u0443 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">static: [     {       directory: path.join(BUILD_DIR, \"favicons\"),     }, ],<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u0444\u0430\u0432\u0438\u043a\u043e\u043d\u043a\u0438.<\/p>\n<hr\/>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 Dev-\u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0443\u043b\u0437\u044b \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">module.exports = {   devServer,   plugins,   entry: path.join(__dirname, \"..\", \"src\", \"index.tsx\"),   output: {     path: BUILD_DIR,     \/**      * Helps to avoid of MIME type ('text\/html') is not a supported stylesheet      * And sets address in html imports      *\/     publicPath: \"\/\",   },   \/\/ Checking the maximum weight of the bundle is disabled   performance: {     hints: false,   },   \/\/ Modules resolved   resolve: {     extensions: [\".tsx\", \".ts\", \".js\"],   },   module: {     strictExportPresence: true, \/\/ Strict mod to avoid of importing non-existent objects     rules: [       \/\/ --- JS | TS USING BABEL       {         test: \/\\.[jt]sx?$\/,         exclude: \/node_modules\/,         use: {           loader: \"babel-loader\",           options: {             cacheDirectory: true, \/\/ Using a cache to avoid of recompilation           },         },       },       \/\/ --- HTML       { test: \/\\.(html)$\/, use: [\"html-loader\"] },       \/\/ --- S\/A\/C\/SS       {         test: \/\\.(s[ac]|c)ss$\/i,         use: [           MiniCssExtractPlugin.loader,           {             loader: \"css-loader\", \/\/ translates css into CommonJS             options: {               esModule: true,               \/\/ css modules               modules: {                 localIdentName: \"[name]__[local]__[hash:base64:5]\", \/\/ format of output                 namedExport: true, \/\/ named exports instead of default               },             },           },           {             \/\/ autoprefixer             loader: \"postcss-loader\",             options: {               postcssOptions: {                 plugins: [                   [                     \"postcss-preset-env\",                     {                       \/\/ Options                     },                   ],                 ],               },             },           },         ],       },       \/\/ --- S\/A\/SS       {         test: \/\\.(s[ac])ss$\/i,         use: [\"sass-loader\"],       },       \/\/ --- IMG       {         test: \/\\.(png|jpe?g|gif|svg|webp|ico)$\/i,         type: \"asset\/resource\",         generator: {           filename: \"assets\/img\/[hash][ext]\",         },       },       \/\/ --- FONTS       {         test: \/\\.(woff2?|eot|ttf|otf)$\/i,         exclude: \/node_modules\/,         type: \"asset\/resource\",         generator: {           filename: \"assets\/fonts\/[hash][ext]\",         },       },     ],   }, };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u043e \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445:<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432 Dev <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D babel-loader html-loader css-loader postcss-loader postcss-preset-env sass-loader<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">babel-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0440\u0430\u043d\u0441\u043f\u0430\u0439\u043b\u0435\u0440 \u0434\u043b\u044f js\/ts<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/babel-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/babel-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">html-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 html \u0444\u0430\u0439\u043b\u043e\u0432. \u041f\u043b\u0430\u0433\u0438\u043d \u043d\u0435 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439, \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/html-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/html-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">css-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c @import\u00a0\u0438\u00a0url()\u00a0\u043a\u0430\u043a\u00a0import\/require()\u00a0\u0432 JS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/css-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/css-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">postcss-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 css<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/postcss-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/postcss-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">postcss-preset-env<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d (\u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430) \u0434\u043b\u044f postcss. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 CSS \u0432\u043e \u0447\u0442\u043e-\u0442\u043e, \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0444\u0438\u043b\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0446\u0435\u043b\u0435\u0432\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0438\u043b\u0438 \u0441\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.  <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/postcss-preset-env\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/postcss-preset-env<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">sass-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 CSS-\u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u044b \u0432 CSS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/sass-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/sass-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>dev.config.js<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>dev.config.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const { merge } = require(\"webpack-merge\"); const common = require(\".\/common.config.js\"); const MiniCssExtractPlugin = require(\"mini-css-extract-plugin\");  const plugins = [   new MiniCssExtractPlugin({     filename: \"[name].[contenthash].css\",   }), ];  module.exports = merge(common, {   mode: \"development\",   target: \"web\",   plugins,   devtool: \"inline-source-map\",   output: {     filename: \"[name].[contenthash].js\",   }, });<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>prod.config.js<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>prod.config.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const { merge } = require(\"webpack-merge\"); const common = require(\".\/common.config.js\"); const MiniCssExtractPlugin = require(\"mini-css-extract-plugin\"); const ImageMinimizerPlugin = require(\"image-minimizer-webpack-plugin\"); const TerserPlugin = require(\"terser-webpack-plugin\");  const plugins = [   new MiniCssExtractPlugin({     filename: \"[contenthash].css\",   }),   \/\/ Compress images   new ImageMinimizerPlugin({     minimizer: {       implementation: ImageMinimizerPlugin.imageminMinify,       options: {         plugins: [           [\"gifsicle\", { interlaced: true }],           [\"jpegtran\", { progressive: true }],           [\"optipng\", { optimizationLevel: 8 }],           [             \"svgo\",             {               plugins: [                 {                   name: \"preset-default\",                   params: {                     overrides: {                       removeViewBox: false,                       addAttributesToSVGElement: {                         params: {                           attributes: [{ xmlns: \"http:\/\/www.w3.org\/2000\/svg\" }],                         },                       },                     },                   },                 },               ],             },           ],         ],       },     },   }), ];  module.exports = merge(common, {   mode: \"production\",   target: \"browserslist\",   plugins,   devtool: false,   output: {     filename: \"[fullhash].js\",   },   optimization: {     usedExports: false,     minimize: true, \/\/ Affects Terser Plugin     minimizer: [       new TerserPlugin({         terserOptions: {           mangle: false,           compress: true,           output: {             beautify: true,             comments: false,           },         },         extractComments: false,       }),     ],   }, }); <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0420\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u043c\u0435\u0436\u0434\u0443 dev \u0438 prod \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u043d\u043e\u043c \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0438 output-\u0444\u0430\u0439\u043b\u043e\u0432. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u044b.<\/p>\n<p>\u041f\u043b\u044e\u0441 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0441\u0436\u0430\u0442\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043c\u0438\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0432 bundle.js.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0447\u0443\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u0443\u0441\u044c.<\/p>\n<p>\u0417\u0430 \u0441\u0436\u0430\u0442\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <strong>image-minimizer-webpack-plugin, <\/strong>\u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b (\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0438\u0445 &#8212; \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0447\u0430\u0441\u0442\u043d\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f :D), \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u043d \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u0445<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D image-minimizer-webpack-plugin imagemin imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430 &#171;\u0441\u0436\u0430\u0442\u0438\u0435&#187; js \u0431\u0430\u043d\u0434\u043b\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <strong>terser-webpack-plugin.<\/strong><\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u0442.\u043a. \u0438\u0434\u0451\u0442 \u0441 webpack 5 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438.<\/p>\n<p><a href=\"https:\/\/webpack.js.org\/plugins\/terser-webpack-plugin\/\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0443\u0442<\/u><\/a><\/p>\n<p>\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c webpack &#8212; \u0432\u0441\u0451.<\/p>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0432 package.json<\/h2>\n<details class=\"spoiler\">\n<summary>package.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">\"config\": {     \"dev\": \"--config __webpack__\/dev.config.js\",     \"prod\": \"--config __webpack__\/prod.config.js\"   }, \"scripts\": {     \"webpack-config-dev\": \"nodemon --watch \\\".\/__webpack__\/*\\\" --exec npm run start-dev\",     \"webpack-config-prod\": \"nodemon --watch \\\".\/__webpack__\/*\\\" --exec npm run start-prod\",     \"start-dev\": \"cross-env-shell webpack serve ${npm_package_config_dev}\",     \"start-prod\": \"cross-env-shell webpack serve ${npm_package_config_prod}\",     \"build-dev\": \"cross-env-shell webpack ${npm_package_config_dev}\",     \"build-prod\": \"cross-env-shell webpack ${npm_package_config_prod} --stats-children\",     \"clean\": \"rd \/s \/q build\",     \"lint\": \"eslint src --ext .js --ext .ts\",     \"lint-fix\": \"eslint src --ext .js --ext .ts --fix\",     \"test\": \"cross-env jest --config __jest__\/jest.config.js\",     \"test-watch\": \"jest --watch --config __jest__\/jest.config.js\",     \"test-coverage\": \"jest --coverage --config __jest__\/jest.config.js\"   },<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>webpack-config- [<\/strong>dev|prod<strong>]<\/strong><\/p>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0438 \u0437\u0430\u0442\u0435\u043c \u0437\u0430\u043d\u043e\u0432\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e. \u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0434\u043e\u0435\u0434\u0430\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 <strong>nodemon <\/strong>\u0441 \u0444\u043b\u0430\u0433\u043e\u043c <strong>&#8212;watch.<\/strong><\/p>\n<p><strong>start-[<\/strong>dev|prod<strong>]<\/strong><\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0431\u043e\u0440\u043a\u0438 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445. \u0421 \u0440\u0435\u0431\u0438\u043b\u0434\u0438\u043d\u0433\u043e\u043c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445 \u0432 \u043a\u043e\u0434\u0435.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b (\u0430\u0434\u0440\u0435\u0441 \u0444\u0430\u0439\u043b\u043e\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 webpack), \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u043d\u044b\u0435 \u0432 config, \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.<\/p>\n<p><a href=\"https:\/\/docs.npmjs.com\/cli\/v6\/using-npm\/config\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0443\u0442<\/u><\/a><\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d cross-env-shell \u0434\u043b\u044f \u0443\u0445\u043e\u0434\u0430 \u043e\u0442 \u043e\u0448\u0438\u0431\u043e\u043a, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u043e\u0439 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435.<\/p>\n<p><a href=\"https:\/\/www.npmjs.com\/package\/cross-env\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u0443\u0442<\/u><\/a><\/p>\n<p><strong>build-[<\/strong>dev|prod<strong>]<\/strong><\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0431\u043e\u0440\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c. \u0421\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0431\u0440\u0430\u043b \u0431\u0430\u043d\u0434\u043b \u0438 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u043b \u0441\u0432\u043e\u044e \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c &#8212; \u044d\u0442\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0444\u043b\u0430\u0433\u0430 <strong>serve.<\/strong><\/p>\n<p><strong>clean<\/strong><\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0441\u043e \u0441\u0431\u043e\u0440\u043a\u043e\u0439.<\/p>\n<p><strong>lint<\/strong> \u0438 <strong>lint-fix<\/strong><\/p>\n<p>\u041d\u0430\u0439\u0442\u0438, \u043b\u0438\u0431\u043e \u043d\u0430\u0439\u0442\u0438 \u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438, \u0432\u044b\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u043c.<\/p>\n<p>&#8230;<\/p>\n<p>\u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f 3 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0432\u0438\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D nodemon cross-env eslint jest<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">nodemon<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/nodemon\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/nodemon<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">cross-env<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f CLI \u043a\u043e\u043c\u0430\u043d\u0434<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/cross-env\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/cross-env<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">eslint<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/eslint\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/eslint<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">jest<\/p>\n<\/td>\n<td>\n<p align=\"left\">JS \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/jestjs.io\/\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/jestjs.io\/<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 React \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0444\u0440\u043e\u043d\u0442\u043e\u0432\u044b\u0445 \u0448\u0442\u0443\u043a<\/h2>\n<p>\u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f (\u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f): <\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">react<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/react.dev\/\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/react.dev\/<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">react-dom<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 DOM<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/react-dom\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/react-dom<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">react-redux<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c React \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Redux  <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/react-redux.js.org\/introduction\/getting-started\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/react-redux.js.org\/introduction\/getting-started<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">react-router-dom<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 React Router<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/react-router-dom\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/react-router-dom<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">@reduxjs\/toolkit<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0442\u0435\u0439\u0442-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c Redux<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/redux-toolkit.js.org\/\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/redux-toolkit.js.org\/<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">@emotion<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f CSS \u0441\u0442\u0438\u043b\u0435\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Javascript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/emotion.sh\/docs\/introduction\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/emotion.sh\/docs\/introduction<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">@mui<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/mui.com\/\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/mui.com\/<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">redux-logger<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, &#8212; \u044d\u0442\u043e \u043b\u043e\u0433\u0433\u0435\u0440 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0434\u043b\u044f Redux<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/redux-logger\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/redux-logger<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\">@types\/redux-logger<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0441 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f redux-logger<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/@types\/redux-logger\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/@types\/redux-logger<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u0430\u043a Prod \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i react react-dom react-redux react-router-dom @reduxjs\/toolkit @emotion\/react @emotion\/styled @mui\/icons-material @mui\/material<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>redux-logger \u0438 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044e \u043a \u043d\u0435\u043c\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 Dev<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D redux-logger @types\/redux-logger<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c ESLint<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0444\u0430\u0439\u043b \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Typescript:<\/p>\n<details class=\"spoiler\">\n<summary>.eslintrc<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{     \"root\": true,     \"extends\": [         \"plugin:react\/recommended\",         \"plugin:@typescript-eslint\/recommended\"     ],     \"parser\": \"@typescript-eslint\/parser\",     \"parserOptions\": {         \"sourceType\": \"module\",         \"ecmaVersion\": 2015,         \"ecmaFeatures\": {             \"jsx\": true \/\/ JSX-compatible         }     },     \"env\": {         \"es6\": true,         \"browser\": true,         \"node\": true     },     \"plugins\": [         \"@typescript-eslint\",         \"react\"     ],     \"rules\": {         \"@typescript-eslint\/no-var-requires\": \"off\", \/\/ To avoid of error: \"Require statement not part of import statement\", if ES modules are used          \"semi\": [             \"error\",             \"always\"         ],         \"quotes\": [             \"error\",             \"double\"         ],         \"indent\": \"off\",         \"no-fallthrough\": \"off\", \/\/ disallow fallthrough of case statements         \"no-multiple-empty-lines\": [             1,             {                 \"max\": 2             }         ], \/\/ disallow multiple empty lines (off by default)         \"no-nested-ternary\": 1, \/\/ disallow nested ternary expressions (off by default)         \"eqeqeq\": 2, \/\/ require the use of === and !==         \"react\/prop-types\": \"off\" \/\/ Prevent missing props validation in a React component definition     },     \"settings\": {         \"react\": {             \"version\": \"detect\" \/\/ Tell eslint-plugin-react to automatically detect the latest version of react.         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u0430\u0432\u0438\u043c, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043b\u0438\u043d\u0442\u0435\u0440\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 React \u0438 Typescript:<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 Dev-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>npm i --save -D eslint-plugin-react @typescript-eslint\/eslint-plugin @typescript-eslint\/parser<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">eslint-plugin-react<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u044b\u0445 \u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c React<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/eslint-plugin-react\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/eslint-plugin-react<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@typescript-eslint\/eslint-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b \u043f\u043e\u0434 Typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package%20@typescript-eslint%20t\/eslint-plugin\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/eslint-plugin<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@typescript-eslint\/parser<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 Typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package@typescript-eslint\/parser\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package@typescript-eslint\/parser<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e Babel<\/h2>\n<p>\u0412 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Babel:<\/p>\n<details class=\"spoiler\">\n<summary>babel.config.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">const plugins = [];  module.exports = {   presets: [     \"@babel\/preset-env\",     \"@babel\/preset-react\",     \"@babel\/preset-typescript\",   ],   plugins, };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u0430\u0432\u0438\u043c, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432 Dev<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D @babel\/preset-env @babel\/preset-react @babel\/preset-typescript<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">@babel\/preset-env<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u0441\u0435\u0442, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e JavaScript \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430    <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/babeljs.io\/docs\/babel-preset-env\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/babeljs.io\/docs\/babel-preset-env<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">@babel\/preset-react<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u0441\u0435\u0442 \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 React<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/babeljs.io\/docs\/babel-preset-react\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/babeljs.io\/docs\/babel-preset-react<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">@babel\/preset-typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u0441\u0435\u0442 \u0434\u043b\u044f Typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/babeljs.io\/docs\/babel-preset-typescript\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/babeljs.io\/docs\/babel-preset-typescript<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>&#171;\u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u043c&#187; Typescript<\/h2>\n<p>\u0412 \u043a\u043e\u0440\u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>tsconfig.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{     \"compilerOptions\": {         \"rootDirs\": [             \"src\",             \"__jest__\"         ],         \"outDir\": \"build\",         \"lib\": [             \"dom\",             \"esnext\"         ],         \/\/ This will include all packages from array only         \/\/ node_modules\/@types - is default path. Required, otherwise it will be ignored.         \"typeRoots\": [             \"node_modules\/@types\",             \"src\/types\"         ],         \"target\": \"es5\",         \"skipLibCheck\": true, \/\/ Skip type checking of declaration files (.d.ts)         \"esModuleInterop\": true, \/\/ Creates __importStar and __importDefault helpers for compatibility with the Babel         \"allowSyntheticDefaultImports\": true, \/\/ allows import w\/o default prop         \"strict\": true, \/\/ \u0415nabling all of the strict mode family options         \"forceConsistentCasingInFileNames\": true, \/\/ Force consistent casing in file names         \"noFallthroughCasesInSwitch\": true, \/\/ Report errors for fallthrough cases in switch statements         \"module\": \"esnext\", \/\/ Sets the module system for the program. Also it's required when use outFile option.          \"moduleResolution\": \"node\", \/\/ Specify the module resolution strategy         \"resolveJsonModule\": true, \/\/ Allows importing modules with a \u2018.json\u2019 extension, which is a common practice in node projects         \"isolatedModules\": true, \/\/ all implementation files must be modules (which means it has some form of import\/export)         \"noImplicitAny\": true, \/\/ Raise error if the type \"any\" is specified somewhere         \"noImplicitThis\": true, \/\/ Raise error on \"this\" expressions with an implied \"any\" type         \"noUnusedLocals\": true, \/\/ Raise errors on unused local variables         \"noEmit\": true, \/\/ Do not emit compiler output files like JavaScript source code, source-maps or declarations         \"jsx\": \"react\",         \"plugins\": [             {                 \"name\": \"typescript-plugin-css-modules\", \/\/ auto-genertes virtual .d.ts for an every css file                 \"options\": {                     \"customTemplate\": \".\/customTemplate.js\"                 }             }         ]     },     \"exclude\": [         \"node_modules\",         \"build\",         \"coverage\",         \"webpack.*.js\",         \"*.config.js\",         \"**\/*.test.ts*\"     ] }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u0430\u0432\u0438\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>\u0415\u0441\u0442\u0435\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 devDependencies<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D typescript typescript-plugin-css-modules<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"231\" width=\"231\">\n<p align=\"left\">typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\">Typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/typescript\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/typescript<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"231\" width=\"231\">\n<p align=\"left\">typescript-plugin-css-modules<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 CSS-\u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 \u0432 TS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/typescript-plugin-css-modules\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/typescript-plugin-css-modules<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u0438\u043a <strong>customTemplate.js<\/strong>, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>customTemplate.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">module.exports = (dts, { classes }) => {   return Object.keys(classes)     .map((key) => `export const ${key}: string`)     .join(\"\\n\"); };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/688844\/\" rel=\"noopener noreferrer nofollow\"><u>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0440\u0435\u0446\u0435\u043f\u0442<\/u><\/a><\/p>\n<h2>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0448\u0442\u0440\u0438\u0445\u0438 &#8212; Jest<\/h2>\n<p>\u0412 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u043d\u0435\u0435, \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043f\u0430\u043f\u043a\u0435 __jest__, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>jest.config.js<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">module.exports = {   roots: [\"..\/__tests__\", \"..\/src\"],   setupFilesAfterEnv: [\"&lt;rootDir>\/jest.setup.ts\"], \/\/ Modules are meant for code which is repeating in each test file   moduleFileExtensions: [\"js\", \"jsx\", \"ts\", \"tsx\"],   moduleNameMapper: {     \"\\\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$\":       \"&lt;rootDir>\/filesMock.js\",   },   transform: {     \"^.+\\\\.jsx?$\": \"babel-jest\",     \"^.+\\\\.tsx?$\": \"ts-jest\",     \".+\\\\.(css|styl|less|sass|scss)$\": \"jest-css-modules-transform\",   },   testMatch: [\"**\/?(*.)(spec|test).[jt]s?(x)\"], \/\/ Finds test files named like abc.test|spec.ts?tsx|js|jsx in roots:[] prop.   testEnvironment: \"jsdom\", \/\/ To avoid of js DOM errors };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>\u041a\u0440\u0430\u0442\u043a\u043e \u043f\u0440\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/strong><\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0440\u043d\u0435\u0432\u044b\u0435 \u043f\u0443\u0442\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432, \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0438 \u0438\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>transform<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#171;\u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0433\u043e&#187; \u0434\u043b\u044f Nodejs \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0432 Javascript. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b React.<\/p>\n<p><a href=\"https:\/\/jestjs.io\/docs\/code-transformation\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442<\/u><\/a><\/p>\n<p>\u0427\u0443\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 <strong>setupFilesAfterEnv.<\/strong><\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430. <\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0442\u0435\u0441\u0442\u0435.<\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/testing-library.com\/\" rel=\"noopener noreferrer nofollow\"><u>Testing Library<\/u><\/a>.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0431\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <strong>setupFilesAfterEnv<\/strong>, \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"bash\"> FAIL  __tests__\/components\/homePage.test.tsx   \u00d7 Home page shows the text (57 ms)    \u25cf Home page shows the text      TypeError: expect(...).toBeInTheDocument is not a function        11 | it(\"Home page shows the text\", () => {       12 |   renderWithProviders(&lt;Home \/>);     > 13 |   expect(screen.getByText&lt;HTMLHeadingElement>(\"Home page\")).toBeInTheDocument();          |                                                             ^       14 | });       15 |<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434 <code>toBeInTheDocument()<\/code> \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e\/\u043c\u0435\u0442\u043e\u0434\u043e\u043c React Testing Library. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 <code>@testing-library\/jest-dom<\/code> , \u0438 \u0437\u0430\u0442\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b \u0441 \u0442\u0435\u0441\u0442\u043e\u043c.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0438\u043c\u043f\u043e\u0440\u0442 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0442\u0435\u0441\u0442.<\/p>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0444\u0430\u0439\u043b\u0438\u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442.<\/p>\n<details class=\"spoiler\">\n<summary>jest.setup.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import \"@testing-library\/jest-dom\";<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0432\u0441\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0451\u043c, \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0435\u0441\u0442\u043e\u043c.<\/p>\n<p><a href=\"https:\/\/jestjs.io\/ru\/docs\/configuration#setupfilesafterenv-array\" rel=\"noopener noreferrer nofollow\"><u>\u0423\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0434\u0435\u0441\u044c<\/u><\/a><\/p>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>utils<\/strong> \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d (\u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u043c \u0434\u0435\u043b\u0430\u0442\u044c <a href=\"https:\/\/redux.js.org\/usage\/writing-tests\" rel=\"noopener noreferrer nofollow\"><u>\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/u><\/a><u>)<\/u> \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<details class=\"spoiler\">\n<summary>utils\/testUtils.tsx<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import React, { PropsWithChildren } from \"react\"; import { render } from \"@testing-library\/react\"; import type { RenderOptions } from \"@testing-library\/react\"; import { configureStore } from \"@reduxjs\/toolkit\"; import type { PreloadedState } from \"@reduxjs\/toolkit\"; import { Provider } from \"react-redux\";  import type { store, RootState } from \"..\/..\/src\/core\/redux\/store\"; \/\/ As a basic setup, import your same slice reducers import { postSlice } from \"..\/..\/src\/core\/redux\/slices\/postSlice\"; import { thunkSlice } from \"..\/..\/src\/core\/redux\/slices\/thunkSlice\";  \/\/ This type interface extends the default options for render from RTL, as well \/\/ as allows the user to specify other things such as initialState, store. interface ExtendedRenderOptions extends Omit&lt;RenderOptions, \"queries\"> {   preloadedState?: PreloadedState&lt;RootState>;   \/\/ store?: AppStore;   store?: typeof store; }  export function renderWithProviders(   ui: React.ReactElement,   {     preloadedState = {},     \/\/ Automatically create a store instance if no store was passed in     store = configureStore({       reducer: {         postReducer: postSlice.reducer,         thunkReducer: thunkSlice.reducer,       },       preloadedState,     }),     ...renderOptions   }: ExtendedRenderOptions = {} ) {   function Wrapper({ children }: PropsWithChildren&lt;object>): JSX.Element {     return &lt;Provider store={store}>{children}&lt;\/Provider>;   }    \/\/ Return an object with the store and all of RTL's query functions   return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) }; } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e:<\/p>\n<blockquote>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Redux \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u0430 \u043d\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u00a0.\u00a0\u042d\u0442\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0439 \u0443\u0442\u0435\u0447\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u0441\u0442\u0430\u043c\u0438. <\/p>\n<\/blockquote>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432 Dev<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D ts-jest jest-environment-jsdom jest-css-modules-transform babel-jest @types\/jest @testing-library\/react @testing-library\/jest-dom<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">ts-jest<\/p>\n<\/td>\n<td>\n<p align=\"left\">Jest \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 Typescript<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/ts-jest\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/ts-jest<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">jest-environment-jsdom<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 JSDOM<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/jestjs.io\/docs\/next\/tutorial-jquery\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/jestjs.io\/docs\/next\/tutorial-jquery<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">jest-css-modules-transform<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 CSS \u0444\u0430\u0439\u043b\u044b \u0432 JS \u043c\u043e\u0434\u0443\u043b\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/jest-css-modules-transform\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/jest-css-modules-transform<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">babel-jest<\/p>\n<\/td>\n<td>\n<p align=\"left\">Jest \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/babel-jest\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/babel-jest<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@types\/jest<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f Jest<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/@types\/jest\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/@types\/jest<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@testing\u2011library\/react<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 React Testing Library<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/@testing-library\/react\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/@testing-library\/react<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@testing-library\/jest-dom<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0449\u0438\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Jest<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/@testing-library\/jest-dom\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/www.npmjs.com\/package\/@testing-library\/jest-dom<\/u><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 VS Code<\/h2>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0444\u0430\u0439\u043b <strong>.vscode\/settings.json <\/strong>\u0438 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u043a \u0432\u0438\u0434\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>settings.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{     \"editor.formatOnSave\": true,     \"[typescriptreact]\": {         \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"     },     \"[json]\": {         \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"     },     \"typescript.updateImportsOnFileMove.enabled\": \"always\",     \"[javascript]\": {         \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"     },     \"editor.codeActionsOnSave\": {         \"source.fixAll.eslint\": true     },     \"eslint.validate\": [         \"javascript\",         \"typescript\"     ],     \"typescript.tsdk\": \"node_modules\\\\typescript\\\\lib\", \/\/ Use Workspace Version for using plugins from tsconfig     \"typescript.enablePromptUseWorkspaceTsdk\": true }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0438\u0435 \u043a\u0430\u043a, \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440\u0430, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u0430, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438, \u0438.\u0442.\u043f.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c, \u0432\u0441\u0451.<\/p>\n<h2>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u041a\u043e\u043d\u043a\u043b\u044e\u0436\u043d\u0430<\/h2>\n<p>\u0412\u044b\u0448\u043b\u043e \u0441\u0443\u043c\u0431\u0443\u0440\u043d\u043e. \u041f\u043e\u043d\u0438\u043c\u0430\u044e. \u0421\u0442\u0430\u0440\u0430\u043b\u0441\u044f &#171;\u043b\u0438\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u043e\u0434\u044b&#187;. \u041c\u0435\u0441\u0442\u0430\u043c\u0438, \u0433\u0434\u0435 \u043f\u0440\u044f\u043c \u043d\u0443 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u0441\u0443\u0445\u0430, \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435.<\/p>\n<p>\u041e \u043c\u043d\u043e\u0433\u043e\u043c \u043d\u0435 \u0441\u043a\u0430\u0437\u0430\u043b, \u043d\u043e \u0433\u043e\u0442\u043e\u0432 \u043e\u0431\u0441\u0443\u0434\u0438\u0442\u044c.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u043a\u0442\u043e-\u0442\u043e \u043d\u0430\u0439\u0434\u0451\u0442 \u0437\u0434\u0435\u0441\u044c \u0447\u0442\u043e-\u043b\u0438\u0431\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435.<\/p>\n<p><a href=\"https:\/\/github.com\/Cere8ellum\/react-starter-split-webpack-5-ts\" rel=\"noopener noreferrer nofollow\"><u>\u041a\u043e\u0434 \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0437\u0434\u0435\u0441\u044c<\/u><\/a><\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0443\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044e \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/754560\/\"> https:\/\/habr.com\/ru\/articles\/754560\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\">\n<div><figcaption>Webpack<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0425\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c \u0432\u0438\u0434\u0435\u043d\u0438\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 React.<\/p>\n<p>\u041f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e &#171;\u043d\u0430 \u0441\u043a\u043e\u0440\u0443\u044e&#187; \u0432\u043e\u0439\u0442\u0438 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<p>\u0427\u0442\u043e-\u0442\u043e \u044f \u043f\u043e\u0434\u0433\u043b\u044f\u0434\u0435\u043b \u0437\u0434\u0435\u0441\u044c \u0436\u0435, \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u043f\u0440\u0438\u0448\u0451\u043b \u0441\u0430\u043c, \u043d\u0443 \u0438 &#171;\u0430\u043d\u0433\u0430\u0436\u0438\u0440\u043e\u0432\u0430\u043b&#187; \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 &#171;\u043d\u0435\u043e\u0431\u044a\u044f\u0442\u043d\u043e\u0433\u043e&#187;.<\/p>\n<p>\u0426\u0435\u043b\u044c \u043f\u043e\u0441\u0442\u0430 &#8212; \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u043c\u043d\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0437\u043d\u0430\u0442\u044c \u043f\u0440\u043e \u0431\u0440\u0435\u0448\u044c.<\/p>\n<p>\u041f\u043e\u0435\u0445\u0430\u043b\u0438.<\/p>\n<h2>\u0427\u0442\u043e &#171;\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c&#187;<\/h2>\n<ol>\n<li>\n<p>Webpack 5<\/p>\n<\/li>\n<li>\n<p>React v.18<\/p>\n<\/li>\n<li>\n<p>Redux (Redux Toolkit)<\/p>\n<\/li>\n<li>\n<p>Typescript<\/p>\n<\/li>\n<li>\n<p>Css modules<\/p>\n<\/li>\n<li>\n<p>Jest<\/p>\n<\/li>\n<li>\n<p>VS Code<\/p>\n<\/li>\n<\/ol>\n<h2>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 <\/h2>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0448\u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445:<\/p>\n<figure class=\"\"><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">__jest__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 Jest<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">__tests__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043f\u043a\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043b\u0435\u0436\u0430\u0442 \u0442\u0435\u0441\u0442\u044b. \u0414\u0430, \u044f \u0437\u043d\u0430\u044e \u0447\u0442\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f (\u0443\u0434\u043e\u0431\u043d\u043e) \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c. \u041a\u043e\u043d\u0444\u0438\u0433 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u043e\u0434\u0445\u043e\u0434 \u0441 \u0432\u044b\u043d\u043e\u0441\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0442\u043e\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0435 \u0448\u0430\u043d\u0441\u044b \u0431\u044b\u0442\u044c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">__webpack__<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 Webpack<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">build<\/p>\n<\/td>\n<td>\n<p align=\"left\">Output \u043f\u0430\u043f\u043a\u0430 c \u0431\u0430\u043d\u0434\u043b\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">.vscode<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043f\u043a\u0430, \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 VS Code. \u0412\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0432 \u043d\u0438\u0445 \u043f\u043e\u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<figure class=\"\"><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">public<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0430\u0442 \u0444\u0430\u0439\u043b\u044b, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">static<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0442\u0430\u043b\u043e\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0430\u0442 \u0444\u0430\u0439\u043b\u044b, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0441 \u043a\u043e\u0434\u043e\u043c. \u0417\u0434\u0435\u0441\u044c \u0442\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0432\u043e\u043b\u0448\u0435\u0431\u0441\u0442\u0432\u043e.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/core<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0443\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, state-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440. <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/pages<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"351\" width=\"351\">\n<p align=\"left\">src\/routes<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b \u0440\u043e\u0443\u0442\u043e\u0432 (\u0435\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c Webpack<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 dev \u0438 prod \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f (\u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c) \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0440\u0435\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (dev, \u043b\u0438\u0431\u043e prod).<\/p>\n<p><a href=\"https:\/\/webpack.js.org\/guides\/production\/\" rel=\"noopener noreferrer nofollow\"><u>\u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435<\/u><\/a><\/p>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 __webpack__ \u0431\u044b\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b 3 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>common.config.js<\/p>\n<\/li>\n<li>\n<p>dev.config.js<\/p>\n<\/li>\n<li>\n<p>prod.config.js<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0432\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u043f\u0435\u0440\u0432\u044b\u0439.<\/p>\n<p><strong>common.config.js<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c webpack<\/summary>\n<div class=\"spoiler__content\">\n<blockquote>\n<p>npm i &#8212;save -D webpack webpack-cli webpack-dev-server<\/p>\n<\/blockquote>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u043d\u043e\u0441\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">const webpack = require(\"webpack\"); const path = require(\"path\");  const BUILD_DIR = path.resolve(__dirname, \"..\", \"build\"); const PUBLIC_DIR = path.resolve(__dirname, \"..\", \"public\"); const STATIC_DIR = path.resolve(__dirname, \"..\", \"static\");<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 Dev-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D mini-css-extract-plugin html-webpack-plugin favicons-webpack-plugin @pmmmwh\/react-refresh-webpack-plugin filemanager-webpack-plugin<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">mini-css-extract-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0444\u0430\u0439\u043b CSS \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 JS, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e CSS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/mini-css-extract-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/mini-css-extract-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">html-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u043c \u0444\u0430\u0439\u043b\u044b \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 index.html  <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/\" rel=\"noopener noreferrer nofollow\">https:\/\/webpack.js.org\/plugins\/html-webpack-plugin\/<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">favicons-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0430\u0432\u0438\u043a\u043e\u043d\u043e\u043a.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/favicons-webpack-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/favicons-webpack-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">favicons<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f favicons-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/favicons\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/favicons<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">@pmmmwh\/react-refresh-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 React \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u0434\u0430. Hot Reload. <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package<\/a><a class=\"mention\" href=\"\/users\/pmmmwh\">@pmmmwh<\/a>h\/react-refresh-webpack-plugin<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">react-refresh<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u043a\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c Webpack \u0434\u043b\u044f &#171;\u0413\u043e\u0440\u044f\u0447\u0435\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438&#187;<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/react-refresh\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/react-refresh<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"203\" width=\"203\">\n<p align=\"left\">filemanager-webpack-plugin<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c, \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 \u0434\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/filemanager-webpack-plugin\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/filemanager-webpack-plugin<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<details class=\"spoiler\">\n<summary>\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const MiniCssExtractPlugin = require(\"mini-css-extract-plugin\"); const HtmlWebpackPlugin = require(\"html-webpack-plugin\"); const FaviconsWebpackPlugin = require(\"favicons-webpack-plugin\"); const ReactRefreshWebpackPlugin = require(\"@pmmmwh\/react-refresh-webpack-plugin\"); const FileManagerPlugin = require(\"filemanager-webpack-plugin\");  const plugins = [   new FileManagerPlugin({     events: {       \/\/ Remove build dir       onStart: {         delete: [BUILD_DIR],       },       onEnd: {         \/\/ Copy static files         copy: [           {             source: STATIC_DIR,             destination: BUILD_DIR,           },         ],       },     },   }),   new HtmlWebpackPlugin({     template: path.join(PUBLIC_DIR, \"index.html\"),     filename: \"index.html\",   }),   \/\/   new FaviconsWebpackPlugin({     logo: path.resolve(PUBLIC_DIR, \"favicon.svg\"),     prefix: \"\/favicons\/\",     outputPath: path.resolve(BUILD_DIR, \"favicons\"),     mode: \"webapp\",     \/\/ Injecting into all HTML Files or separately (for an every instance of HtmlWebpackPlugin)     \/\/ inject: true,     inject: (htmlPlugin) =>       path.basename(htmlPlugin.options.filename) === \"index.html\",     favicons: {       icons: {         appleIcon: false, \/\/ Apple touch icons.         appleStartup: false, \/\/ Apple startup images.         android: false, \/\/ Android homescreen icon.         favicons: true, \/\/ Regular favicons.         coast: false, \/\/ Opera Coast icon.         firefox: false, \/\/ Firefox OS icons.         windows: false, \/\/ Windows 8 tile icons.         yandex: false, \/\/ Yandex browser icon.       },     },     cache: false, \/\/ Disallow caching the assets across webpack builds.   }),   new webpack.HotModuleReplacementPlugin(), \/\/ For page reloading ];  if (process.env.SERVE) {   plugins.push(new ReactRefreshWebpackPlugin()); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<hr\/>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Dev Server<\/p>\n<pre><code class=\"javascript\">const devServer = {   historyApiFallback: true, \/\/ Apply HTML5 History API if routes are used   open: true,   compress: true,   allowedHosts: \"all\",   hot: true, \/\/ Reload the page after changes saved (HotModuleReplacementPlugin)   client: {     \/\/ Shows a full-screen overlay in the browser when there are compiler errors or warnings     overlay: {       errors: true,       warnings: true,     },     progress: true, \/\/ Prints compilation progress in percentage in the browser.   },    port: 3000,   \/**    * Writes files to output path (default: false)    * Build dir is not cleared using &lt;output: {clean:true}>    * To resolve should use FileManager    *\/   devMiddleware: {     writeToDisk: true,   },   static: [     \/\/ Required to use favicons located in a separate directory as assets     \/\/ Should use with historyApiFallback, to avoid of 404 for routes     {       directory: path.join(BUILD_DIR, \"favicons\"),     },   ], };<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 devMiddleware. \u0410 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"javascript\">writeToDisk: true<\/code><\/pre>\n<p>\u041e\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <strong>dev server<\/strong> \u043d\u0430 \u0434\u0438\u0441\u043a. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u043e\u0435.<\/p>\n<p>\u041d\u043e \u0442\u0443\u0442 \u0436\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u0411\u0438\u043b\u0434 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f File Manager \u043f\u043b\u0430\u0433\u0438\u043d, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u0435, \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"javascript\">events: {       \/\/ Remove build dir       onStart: {         delete: [BUILD_DIR],       }, }<\/code><\/pre>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0445\u043e\u0447\u0443 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c:<\/p>\n<pre><code class=\"javascript\">static: [     {       directory: path.join(BUILD_DIR, \"favicons\"),     }, ],<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u0444\u0430\u0432\u0438\u043a\u043e\u043d\u043a\u0438.<\/p>\n<hr\/>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 Dev-\u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0443\u043b\u0437\u044b \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">module.exports = {   devServer,   plugins,   entry: path.join(__dirname, \"..\", \"src\", \"index.tsx\"),   output: {     path: BUILD_DIR,     \/**      * Helps to avoid of MIME type ('text\/html') is not a supported stylesheet      * And sets address in html imports      *\/     publicPath: \"\/\",   },   \/\/ Checking the maximum weight of the bundle is disabled   performance: {     hints: false,   },   \/\/ Modules resolved   resolve: {     extensions: [\".tsx\", \".ts\", \".js\"],   },   module: {     strictExportPresence: true, \/\/ Strict mod to avoid of importing non-existent objects     rules: [       \/\/ --- JS | TS USING BABEL       {         test: \/\\.[jt]sx?$\/,         exclude: \/node_modules\/,         use: {           loader: \"babel-loader\",           options: {             cacheDirectory: true, \/\/ Using a cache to avoid of recompilation           },         },       },       \/\/ --- HTML       { test: \/\\.(html)$\/, use: [\"html-loader\"] },       \/\/ --- S\/A\/C\/SS       {         test: \/\\.(s[ac]|c)ss$\/i,         use: [           MiniCssExtractPlugin.loader,           {             loader: \"css-loader\", \/\/ translates css into CommonJS             options: {               esModule: true,               \/\/ css modules               modules: {                 localIdentName: \"[name]__[local]__[hash:base64:5]\", \/\/ format of output                 namedExport: true, \/\/ named exports instead of default               },             },           },           {             \/\/ autoprefixer             loader: \"postcss-loader\",             options: {               postcssOptions: {                 plugins: [                   [                     \"postcss-preset-env\",                     {                       \/\/ Options                     },                   ],                 ],               },             },           },         ],       },       \/\/ --- S\/A\/SS       {         test: \/\\.(s[ac])ss$\/i,         use: [\"sass-loader\"],       },       \/\/ --- IMG       {         test: \/\\.(png|jpe?g|gif|svg|webp|ico)$\/i,         type: \"asset\/resource\",         generator: {           filename: \"assets\/img\/[hash][ext]\",         },       },       \/\/ --- FONTS       {         test: \/\\.(woff2?|eot|ttf|otf)$\/i,         exclude: \/node_modules\/,         type: \"asset\/resource\",         generator: {           filename: \"assets\/fonts\/[hash][ext]\",         },       },     ],   }, };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u043e \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445:<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432 Dev <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">npm i --save -D babel-loader html-loader css-loader postcss-loader postcss-preset-env sass-loader<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">babel-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0440\u0430\u043d\u0441\u043f\u0430\u0439\u043b\u0435\u0440 \u0434\u043b\u044f js\/ts<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/babel-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/babel-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">html-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 html \u0444\u0430\u0439\u043b\u043e\u0432. \u041f\u043b\u0430\u0433\u0438\u043d \u043d\u0435 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439, \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c.<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/html-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/html-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">css-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c @import\u00a0\u0438\u00a0url()\u00a0\u043a\u0430\u043a\u00a0import\/require()\u00a0\u0432 JS<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/css-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/css-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">postcss-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 css<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/postcss-loader\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/postcss-loader<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">postcss-preset-env<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0433\u0438\u043d (\u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430) \u0434\u043b\u044f postcss. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 CSS \u0432\u043e \u0447\u0442\u043e-\u0442\u043e, \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0443 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0444\u0438\u043b\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0446\u0435\u043b\u0435\u0432\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0438\u043b\u0438 \u0441\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.  <\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/postcss-preset-env\" rel=\"noopener noreferrer nofollow\">https:\/\/www.npmjs.com\/package\/postcss-preset-env<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"234\" width=\"234\">\n<p align=\"left\">sass-loader<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u043e\u0431\u0440\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-352149","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/352149","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=352149"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/352149\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=352149"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=352149"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=352149"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}