{"id":426498,"date":"2024-07-17T15:00:41","date_gmt":"2024-07-17T15:00:41","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=426498"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=426498","title":{"rendered":"<span>\u0418\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u043e \u0441\u0435\u0442\u0430\u043f\u0430: \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0441\u0442\u0435\u043a\u0430 \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b<\/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\/w1560\/getpro\/habr\/upload_files\/35b\/617\/6a1\/35b6176a1de060064ee3e00738b7fbb8.png\" width=\"2438\" height=\"1369\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/35b\/617\/6a1\/35b6176a1de060064ee3e00738b7fbb8.png\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0413\u0440\u0430\u043d\u0442, \u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 <a href=\"https:\/\/kts.tech\/\">KTS<\/a>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0437\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043e\u0442 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<p>\u0412 \u043e\u0442\u0434\u0435\u043b\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u044b\u0445 \u0441\u043f\u0435\u0446\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0430\u043f\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u043b\u044f \u043d\u0430\u0441 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043c \u043f\u043e \u0442\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043c\u0435\u0441\u044f\u0446. \u0418\u0445 \u0444\u0440\u043e\u043d\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430<a href=\"https:\/\/react.dev\/\"> React<\/a>,<a href=\"https:\/\/styled-components.com\/\"> Styled Components<\/a> \u0438\u043b\u0438 \u0441\u0432\u044f\u0437\u043a\u0435<a href=\"https:\/\/github.com\/css-modules\/css-modules\"> CSS modules<\/a> \u0441<a href=\"https:\/\/sass-lang.com\/\"> SCSS<\/a>,<a href=\"https:\/\/mobx.js.org\/\"> MobX<\/a> \u0438<a href=\"https:\/\/axios-http.com\/\"> Axios<\/a>, \u0430 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0442\u043e \u043a \u0441\u043f\u0438\u0441\u043a\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0435\u0449\u0435<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> VKUI<\/a> \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<a href=\"https:\/\/dev.vk.com\/ru\/bridge\/getting-started\"> VK-Bridge<\/a> \u0434\u043b\u044f VK API.<\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u0441\u0431\u043e\u0440\u043a\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043d\u043e \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0432\u0430 \u0441\u0447\u0435\u0442\u0430. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0439\u0434\u0435\u0442 \u0440\u0435\u0447\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0421\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u043e\u043b\u043d\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u044d\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435: <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\">create-mediaproject-example<\/a>.<\/p>\n<p><strong>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"#1\">\u041a\u0430\u043a \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043d\u044c\u0448\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\">\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043a\u0430\u043b\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\">\u041a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\">\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0442\u0438\u043b\u0438\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\">\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\">\u0421 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\">\u0427\u0435\u0433\u043e \u043c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435<\/a><\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"#1\" id=\"#1\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043d\u044c\u0448\u0435  <\/h2>\n<p>\u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0442\u0430\u0439\u043d\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u043e\u0439 \u0441trl+c, ctrl+v\u00a0\u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0440\u0430\u043b\u0438 \u0441\u0430\u043c\u044b\u0439 \u0441\u0432\u0435\u0436\u0438\u0439 \u0438\u0437 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0435\u0433\u043e \u0432 \u043d\u043e\u0432\u044b\u0439. \u0414\u0430\u043b\u0435\u0435 \u043e\u0447\u0438\u0449\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442-\u0434\u043e\u043d\u043e\u0440 \u043e\u0442 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0433\u043e: \u043b\u0438\u0448\u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0443\u0442\u0438\u043b\u0438\u0442, \u0444\u0430\u0439\u043b\u043e\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 UI Kit \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u0438 \u0448\u0440\u0438\u0444\u0442\u044b, \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/26a\/b34\/dd2\/26ab34dd2bfeb6833b0a04af51ed7c94.png\" width=\"640\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/26a\/b34\/dd2\/26ab34dd2bfeb6833b0a04af51ed7c94.png\"\/><\/figure>\n<p>\u0421 \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u043c\u0438\u043a\u0441\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0435\u0439 \u0438\u043b\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445. \u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443 \u0431\u0435\u043a\u0435\u043d\u0434\u0435\u0440\u043e\u0432 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b, \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430-\u0434\u043e\u043d\u043e\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0434\u043b\u044f \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e CI.<\/p>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0438 \u0441\u0435\u0442\u0430\u043f\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u0437 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043d\u0430 \u0431\u0430\u0437\u0435 React Router. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u0436\u0435 \u0443\u0447\u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u043e\u0434<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> VKUI<\/a> \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 VK API, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043d\u0435\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u00ab\u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435\u00bb \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e \u0431\u044b\u043b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u043d\u043e\u0432\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c, \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430-\u0434\u043e\u043d\u043e\u0440\u0430 \u0438 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u0430 \u0447\u0442\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0441\u0435\u0442\u0430\u043f\u0430, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435.<\/p>\n<p><a class=\"anchor\" name=\"2\" id=\"2\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043a\u0430\u043b\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443  <\/h2>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u0435\u0442\u0430\u043f\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u0414\u043b\u044f \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439: \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430.<\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u043b\u0438 \u043c\u044b \u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<a href=\"https:\/\/create-react-app.dev\/\"> Create React App<\/a>, \u0438 \u043c\u0435\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u0440\u043e\u0434\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<a href=\"https:\/\/vitejs.dev\/guide\/\"> Create Vite<\/a>. \u041e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c.<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0440\u0430\u0437\u0443 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u044e \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430: \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439 \u0440\u043e\u0443\u0442\u0438\u043d\u0433, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432, \u043a\u043e\u043d\u0444\u0438\u0433\u0438 CI \u0438\u00a0\u0442.\u00a0\u0434.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/create-react-app.dev\/\">Create React App<\/a> \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043b\u0438\u0432\u044b\u043c \u0432 \u043f\u043b\u0430\u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430. \u0412 CRA \u043a\u043e\u043d\u0444\u0438\u0433 Webpack \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0441\u043a\u0440\u044b\u0442, \u0438 \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <strong>eject<\/strong>, \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0440\u043e\u0434\u0435<a href=\"https:\/\/github.com\/timarney\/react-app-rewired\"> <strong>react-app-rewired<\/strong><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u043d\u0430\u0448\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u0412\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,<a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/515008\/\"> \u044d\u0442\u0430<\/a>).<\/p>\n<p>\u0421\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 \u043f\u0430\u043f\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u0431\u044b\u043b \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442, \u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439.<\/p>\n<p><a class=\"anchor\" name=\"3\" id=\"3\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430  <\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/31a\/30c\/73d\/31a30c73db13cdc2b4aca1e0096b401f.png\" width=\"640\" height=\"843\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/31a\/30c\/73d\/31a30c73db13cdc2b4aca1e0096b401f.png\"\/><\/figure>\n<p>\u041e\u0431\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>create-mediaproject-example \u251c\u2500\u2500 src \u2502  \u251c\u2500\u2500 templates                         \u043f\u0430\u043f\u043a\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 \u2502  \u2502  \u251c\u2500\u2500 temp1                          \u043e\u0434\u0438\u043d \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u2502  \u2502  \u2502  \u251c\u2500\u2500 ...                          \u2502  \u2502  \u2502  \u251c\u2500\u2500 package.template.json \u2502  \u2502  \u2502  \u251c\u2500\u2500 README.template.md \u2502  \u2502  \u2502  \u2514\u2500\u2500 webpack.config.template.ts \u2502  \u2502  \u2514\u2500\u2500 ... \u2502  \u251c\u2500\u2500 ... \u2502  \u251c\u2500\u2500 createProject.ts                  \u0444\u0430\u0439\u043b\u044b \u0443\u0442\u0438\u043b\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f  \u2502  \u2514\u2500\u2500 index.ts                          \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u251c\u2500\u2500 ... \u251c\u2500\u2500 package.json                         \u043a\u043e\u043d\u0444\u0438\u0433 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u2514\u2500\u2500 README.md                            \u0441\u0435\u0442\u0430\u043f\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435. \u0415\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d (src\/templates\/vk-mini-app) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u044f\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<a href=\"https:\/\/react.dev\/\"> (React<\/a>);<\/p>\n<\/li>\n<li>\n<p>UI\u2011\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> (VKUI<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0VK API (<a href=\"https:\/\/dev.vk.com\/ru\/bridge\/getting-started\">VK\u2011Bridge<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430<a href=\"https:\/\/reactrouter.com\/\"> (React\u2011Router<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439<a href=\"https:\/\/mobx.js.org\/\"> (MobX<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u00a0\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (<a href=\"https:\/\/axios-http.com\/\">Axios<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0438\u043a\u0441\u0438\u043d\u043e\u0432 SCSS, \u0443\u0442\u0438\u043b\u0438\u0442 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0VK API, \u043d\u0430\u0431\u043e\u0440 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0441\u0442\u043e\u0440\u043e\u0432, \u0438\u00a0\u0442.\u00a0\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 dev\u2011\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u00a0\u2014 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (Webpack);<\/p>\n<\/li>\n<li>\n<p>\u043b\u0438\u043d\u0442\u0435\u0440\u044b (Eslint, Stylelint, Prettier);<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u043e\u0432 (Typescript, SCSS, Styled\u2011Components);<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0430\u0439\u043b\u044b \u0441\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0436\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 (src\/index.ts) \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0440\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<ol>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 \u0441\u00a0\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u0434\u043b\u044f\u00a0\u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u0412\u00a0\u043d\u0435\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430, \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0443\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0440\u044f\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043e\u043f\u0446\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u044e\u0449\u0430\u044f \u043f\u043e\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u0443 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u00a0\u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0431\u0435\u0437\u00a0\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u043e\u0441\u0442\u2011\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c git\u2011\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<p><a class=\"anchor\" name=\"4\" id=\"4\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0442\u0438\u043b\u0438\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430  <\/h2>\n<p>\u0421\u0442\u043e\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0442\u043e\u0447\u044c-\u0432-\u0442\u043e\u0447\u044c \u043f\u043e \u043d\u0430\u0448\u0438\u043c \u043b\u0435\u043a\u0430\u043b\u0430\u043c. \u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u043d\u0435 \u043d\u0430\u0434 \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0442\u0430\u043f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0449\u0435. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>\u0422\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0444\u0430\u0439\u043b <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/index.ts\">src\/index.ts<\/a>:<\/p>\n<details class=\"spoiler\">\n<summary>src\/index.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { parseOptions } from \".\/parseOptions\"; import { createProject } from \".\/createProject\"; import { postProcess } from \".\/postProcess\"; import { printError, printSuccess } from \".\/utils\/print\"; import { MESSAGES } from \".\/config\";  const main = async (): Promise&lt;void> => {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442 \u044e\u0437\u0435\u0440\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d   const options = await parseOptions();    try {     \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u0430\u043f\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430     createProject(options);     \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438     postProcess(options);      printSuccess(       MESSAGES.projectCreateSuccess(       options.templateName,        options.buildDir     )     );   } catch {     printError(MESSAGES.projectCreateError);   } };  main();<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d. \u0423\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/parseOptions.ts\">src\/parseOptions.ts<\/a> \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435. \u0417\u0434\u0435\u0441\u044c \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:\/\/github.com\/SBoudrias\/Inquirer.js\"> Inquirer.js<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>src\/parseOptions.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import * as fs from 'fs'; import * as path from 'path';  import { prompt } from 'inquirer';  const TEMPLATES_DIR_NAME = 'templates';  \/\/ \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f export type OptionsType = {   \/\/ \u0438\u043c\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430   templateName: string;   \/\/ \u043f\u0443\u0442\u044c \u043a \u0435\u0433\u043e \u043f\u0430\u043f\u043a\u0435   templatePath: string;   \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u0438 \u0435\u0433\u043e \u043f\u0430\u043f\u043a\u0438)   buildDir: string; };  \/\/ \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0432\u0432\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f export const parseOptions = async (): Promise&lt;OptionsType> => {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043f\u0430\u043f\u043a\u0435 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438   const templatesPath = path.join(__dirname, TEMPLATES_DIR_NAME);   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u043d \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438   const choices = fs.readdirSync(templatesPath);    \/\/ \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432   const questions = [     promptQuestions.templateName(choices),     promptQuestions.buildDir,   ];    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u044e\u0437\u0435\u0440\u0430   const { templateName, buildDir } = await prompt(questions);    \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u043c \u043e\u043f\u0446\u0438\u0439   return {     buildDir,     templateName,     templatePath: path.join(templatesPath, templateName),   }; };  \/\/ \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440 \u0438\u043c\u0435\u043d\u0438 \u043f\u0430\u043f\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 const validateDirectoryName = (dirName: string): true | string => {  return \/^([A-Za-z\\\\-_\\\\d])+$\/.test(dirName) || 'Incorrect directory name'; };  \/\/ \u043a\u043e\u043d\u0444\u0438\u0433 \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (\u0432 \u043f\u043e\u043b\u0435 message) \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043e\u043f\u0446\u0438\u0439 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 const promptQuestions = {   templateName: (choices: string[]) => ({     name: 'templateName',     type: 'list',     message: 'Select template',     choices,   }),   buildDir: {     name: 'buildDir',     type: 'input',     message: 'Project directory (also name)',     validate: validateDirectoryName, };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0434\u0435\u043b\u043e \u0432\u0441\u0442\u0443\u043f\u0438\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/createProject.ts\">src\/createProject.ts<\/a>. \u041e\u043d\u0430 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <a href=\"https:\/\/ejs.co\/\">EJS<\/a>):<\/p>\n<details class=\"spoiler\">\n<summary>src\/createProject.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import * as fs from \"fs\"; import * as path from \"path\";  import * as ejs from \"ejs\";  import { MESSAGES } from \".\/config\"; import { printError } from \".\/utils\/print\"; import { OptionsType } from \".\/parseOptions\";  \/\/ \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 export const SKIP_FILENAMES = [\".DS_Store\", \".git\", \"node_modules\"];  \/\/ \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c const TEMPLATE_REGEXP = \/\\\\.template\/; const isTemplate = (name: string) => Boolean(name.match(TEMPLATE_REGEXP));  \/\/ \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043f\u0446\u0438\u0438, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u044e\u0437\u0435\u0440\u043e\u043c, \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 export const createProject = (options: OptionsType): void => {   \/\/ \u0435\u0441\u043b\u0438 \u043f\u0430\u043f\u043a\u0430 \u0441 \u0442\u0435\u043c \u0436\u0435 \u0438\u043c\u0435\u043d\u0435\u043c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u044e\u0437\u0435\u0440\u0443 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435   if (fs.existsSync(options.buildDir)) {     printError(MESSAGES.buildDirExists);     throw new Error(MESSAGES.buildDirExists);   }    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430   fs.mkdirSync(options.buildDir);   \/\/ \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443   createDirectoryContents(options); };  \/\/ \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u044e\u0437\u0435\u0440\u043e\u043c \u043e\u043f\u0446\u0438\u0438 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0449\u0430\u044f \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 const createDirectoryContents = (   options: OptionsType,   relativePath = \"\" ): void => {   const buildRelativePath = (parentPath: string) =>     path.join(parentPath, relativePath);    \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u043d\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435   const fullProjectPath = buildRelativePath(options.buildDir);   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435   const fullTemplatePath = buildRelativePath(options.templatePath);   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u0430\u043f\u043a\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442   const entriesToCreate = fs.readdirSync(fullTemplatePath);    \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u0430\u043f\u043a\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430   entriesToCreate.forEach((entryName) => {     \/\/ \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b     if (SKIP_FILENAMES.includes(entryName)) {       return;     }      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435     const entryPath = path.join(fullTemplatePath, entryName);      \/\/ \u0435\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0441 \u044d\u0442\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c - \u044d\u0442\u043e \u043d\u0435 \u043f\u0430\u043f\u043a\u0430, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442     if (fs.statSync(entryPath).isFile()) {       return saveFile({         options,         entryPath,         entryName,         projectBuildPath: fullProjectPath,       });     }      \/\/ \u0438\u043d\u0430\u0447\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435     fs.mkdirSync(path.join(fullProjectPath, entryName));     \/\/ \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0435\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435     createDirectoryContents(options, path.join(relativePath, entryName));   }); };  type SaveFileProps = {   \/\/ \u043e\u043f\u0446\u0438\u0438, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u044e\u0437\u0435\u0440\u043e\u043c   options: OptionsType,   \/\/ \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043e \u0444\u0430\u0439\u043b\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430   entryPath: string,   \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430   entryName: string,   \/\/ \u043f\u0443\u0442\u044c, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0444\u0430\u0439\u043b \u043b\u0435\u0436\u0438\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c   projectBuildPath: string, };  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0433\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 const saveFile = ({   options,   entryName,   entryPath,   projectBuildPath, }: SaveFileProps) => {   \/\/ \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u0430   let dataToWrite = fs.readFileSync(entryPath, \"utf-8\");    \/\/ \u0435\u0441\u043b\u0438 \u0444\u0430\u0439\u043b\u0443 \u043d\u0443\u0436\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c, \u0442\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 EJS   if (isTemplate(entryName)) {     dataToWrite = ejs.render(dataToWrite, {       \/\/ \u0442\u0430\u043a EJS \u0437\u0430\u043c\u0435\u043d\u0438\u0442 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 dataToWrite       \/\/ \u0432\u0441\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f &lt;%= PROJECT_NAME %>       \/\/ \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043e\u043f\u0446\u0438\u0438 buildDir (\u0442.\u0435. \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u044e\u0437\u0435\u0440\u043e\u043c \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430)       PROJECT_NAME: options.buildDir,     });   }    \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u043e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438 .template \u0434\u043b\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0430   const writeFileName = entryName.replace(TEMPLATE_REGEXP, \"\");   \/\/ \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432 \u043d\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435   const fullFilePath = path.join(projectBuildPath, writeFileName);   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0444\u0430\u0439\u043b\u0430 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430   const { mode } = fs.statSync(entryPath);   \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0444\u0430\u0439\u043b \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u0442\u0435\u043c \u0436\u0435 mode,   \/\/ \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c\u0438   fs.writeFileSync(fullFilePath, dataToWrite, { mode }); };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/postProcess.ts\">src\/postProcess.ts<\/a>. \u041e\u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 git-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<a href=\"https:\/\/github.com\/shelljs\/shelljs\"> shelljs<\/a> \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0443\u0442\u0438\u043b\u0438\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>src\/postProcess.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import * as fs from \"fs\";  import { cd, exec, ShellString } from \"shelljs\";  import { MESSAGES } from \".\/config\"; import { OptionsType } from \".\/parseOptions\";  \/\/ \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043f\u0446\u0438\u0438, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u044e\u0437\u0435\u0440\u043e\u043c, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 export const postProcess = (options: OptionsType): void => {   \/\/ \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430   cd(options.buildDir);    \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438   initGit();   createGitIgnoreFile();   installDeps(); };  export const INITIAL_GIT_BRANCH = \"main\"; const FILES_GIT_SHOULD_IGNORE = [   \"*.log\",   \"node_modules\/\",   \"public\/\",   \"dist\/\",   \".idea\/\",   \".vscode\/\",   \".DS_Store\", ];  \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f const initGit = (branch = INITIAL_GIT_BRANCH): ShellString =>   exec(`git init --initial-branch ${branch}`);  \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 .gitignore const createGitIgnoreFile = (): void => {   \/\/ \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 echo   \/\/ \u0442\u0430\u043a\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u041e\u0421   const commands = FILES_GIT_SHOULD_IGNORE.map((name) => `echo ${name}`);    exec(`(${commands.join(\" &amp;&amp; \")}) > '.gitignore'`); };  \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u044b yarn export const installDeps = (): void => {   if (!fs.existsSync(\"package.json\")) {     return;   }    const result = exec(\"yarn install\");    if (result.code !== 0) {     throw new Error(MESSAGES.yarnInstallFail);   } };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"5\" id=\"5\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/h2>\n<p>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0430\u0448\u0435\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0443\u0442\u0438\u043b\u0438\u0442. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0438\u0447\u0438:<\/p>\n<ul>\n<li>\n<p>\u0432\u044b\u0431\u043e\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 \u043d\u0435\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439 (git);<\/p>\n<\/li>\n<li>\n<p>\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (yarn).<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0434\u043b\u044f \u043c\u0438\u043d\u0438-\u0430\u043f\u043f\u0430 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6697b6406748d7d46fd2c45b\" data-style=\"\" id=\"6697b6406748d7d46fd2c45b\" width=\"\"><\/div>\n<p><a class=\"anchor\" name=\"6\" id=\"6\"><\/a><\/p>\n<h2>\u0421 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c<\/h2>\n<p>\u041d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043d\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u0435\u043d, \u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0440\u043e\u0439 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u0438 \u0448\u0435\u0440\u043e\u0445\u043e\u0432\u0430\u0442\u043e\u0441\u0442\u0438. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0438 \u043e \u043d\u0438\u0445, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u043d\u0430\u0448\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0438\u0445 \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u00a0\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u00a0\u043d\u0435\u0433\u043e \u043d\u043e\u0432\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b. \u0412\u00a0\u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441\u0440\u0435\u0434\u0438 \u043d\u0438\u0445\u00a0\u0431\u044b\u043b \u0448\u0430\u0431\u043b\u043e\u043d SPA\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f\u00a0Web\u2011\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0412\u00a0\u043f\u0435\u0440\u0432\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u0434\u043b\u044f\u00a0\u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f<a href=\"https:\/\/webpack.js.org\/\"> Webpack<\/a>, \u043d\u043e\u00a0\u0447\u0442\u043e\u0431\u044b \u0438\u0434\u0442\u0438 \u0432\u00a0\u043d\u043e\u0433\u0443 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/vitejs.dev\/\">Vite<\/a>\u00a0\u2014 \u043e\u043d \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0449\u0435 \u0432\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435. \u0414\u0430, \u0435\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u00a0\u0445\u0432\u0430\u0442\u0430\u0442\u044c, \u043d\u043e\u00a0\u0441\u00a0\u043d\u0438\u043c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0441\u0442\u0430\u043b\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0441\u0442\u0430\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u043e\u0431\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043f\u043e\u0432\u0441\u044e\u0434\u0443 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u042d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0422\u0443\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438 \u0445\u0443\u043a\u0438, \u0441\u0442\u043e\u0440\u044b \u043d\u0430 \u0431\u0430\u0437\u0435 MobX \u0438 \u043c\u0438\u043a\u0441\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0435\u0439. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u0441\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f6f\/9dd\/c69\/f6f9ddc69e84672587ef50ccd9bcaf35.png\" width=\"640\" height=\"692\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f6f\/9dd\/c69\/f6f9ddc69e84672587ef50ccd9bcaf35.png\"\/><\/figure>\n<p>\u0415\u0449\u0435 \u043f\u0440\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0438\u043b\u0438\u00a0\u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0443\u00a0\u043d\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u0438 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0414\u0435\u043b\u043e \u0432\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043d\u0435\u00a0\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f\u00a0\u0441\u0432\u043e\u0438\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0415\u0441\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0432\u00a0IDE, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u00a0Typescript \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e: \u0442\u0438\u043f\u044b \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u044d\u0442\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043e\u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u0447\u0442\u043e\u00a0\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u043a\u0443\u0447\u0443 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0437\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0438 \u0443\u0436\u0435 \u0435\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u00a0IDE. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u00a0dev\u2011\u0440\u0435\u0436\u0438\u043c\u0435 \u0435\u0433\u043e \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0443\u0442 \u0432\u0438\u0434\u043d\u044b \u0432\u00a0\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u043d\u0443\u0436\u043d\u043e \u043d\u0435\u00a0\u0437\u0430\u0431\u044b\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432\u00a0\u0448\u0430\u0431\u043b\u043e\u043d, \u0447\u0442\u043e\u00a0\u0442\u043e\u0436\u0435 \u043e\u0442\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437.<\/p>\n<p>\u0414\u043b\u044f\u00a0\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441\u0432\u043e\u0439 \u00abdev\u2011\u0440\u0435\u0436\u0438\u043c\u00bb \u0434\u043b\u044f\u00a0\u0443\u0442\u0438\u043b\u0438\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u00a0\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430. \u041f\u0440\u0438\u00a0\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u00a0\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0442\u0435\u043c\u00a0\u0436\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u0447\u0442\u043e\u00a0\u0438 \u0432\u00a0\u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435: \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u044b, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f git \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0414\u0430\u043b\u0435\u0435 \u043f\u0430\u043f\u043a\u0430 \u0441\u00a0\u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438\u0437\u00a0\u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (node_modules)\u00a0\u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f \u0432\u00a0\u043f\u0430\u043f\u043a\u0443 \u044d\u0442\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 IDE \u0432\u00a0\u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0438\u043f\u044b \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043d\u0430\u00a0\u0431\u0430\u0437\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<a href=\"https:\/\/www.npmjs.com\/package\/chokidar\"> chokidar<\/a>. \u041e\u043d\u0430 \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430\u00a0\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u0432\u00a0\u0444\u0430\u0439\u043b\u0430\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u0432\u00a0\u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u0438\u043b\u0438\u00a0\u0443\u0434\u0430\u043b\u044f\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043f\u0430\u043f\u043a\u0438. \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0442\u0430\u043a\u0436\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432\u00a0dev\u2011\u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u0447\u0442\u043e\u00a0\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0435\u0433\u043e \u0432\u00a0\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0440\u0430\u0432\u043a\u0438 \u0432\u00a0\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u044f\u043c\u043e \u0432\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u0435, \u0438 IDE \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0432\u00a0\u0440\u0430\u0431\u043e\u0442\u0435, \u0430\u00a0\u0432\u00a0\u043a\u043e\u043d\u0446\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p><a class=\"anchor\" name=\"7\" id=\"7\"><\/a><\/p>\n<h2>\u0427\u0435\u0433\u043e \u043c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435<\/h2>\n<p>\u0421\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043c\u044b \u0437\u0430\u043a\u0440\u044b\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u00a0\u0441\u0435\u0442\u0430\u043f\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0434\u043b\u044f 70% \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043e\u0442\u0434\u0435\u043b\u0430. \u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u0435\u0442\u0430\u043f\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u043e\u0441\u044c \u0432 4\u00a0\u0440\u0430\u0437\u0430\u00a0\u2014 \u0434\u043e 30\u00a0\u043c\u0438\u043d\u0443\u0442. \u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u00a0\u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0438 \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u00a0\u0441\u0442\u0430\u0440\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0438 \u00ab\u0441\u0435\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443\u00bb \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0VKUI.<\/p>\n<p>\u0412\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043d\u0430\u0448\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u0442\u0438\u0432\u0430 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044b, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u00a0\u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u043e\u043d\u043e\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441\u00a0\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438 \u043e\u0431\u0449\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043d\u0430\u0448 \u043e\u043f\u044b\u0442 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u0442 \u0438 \u0432\u0430\u0441, \u0430\u00a0\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u00a0\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u0432\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438. \u041f\u0440\u043e\u0431\u0443\u0439\u0442\u0435, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u0438 \u0443\u0441\u043a\u043e\u0440\u044f\u0439\u0442\u0435, \u0430\u00a0\u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c, \u0447\u0435\u043c \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f\u00a0\u2014 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u00a0\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438.<\/p>\n<p>\u0410\u00a0\u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a\u00a0\u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u00a0\u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c, \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0448\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430\u00a0\u044d\u0442\u0443 \u0442\u0435\u043c\u0443:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/kts\/articles\/821111\/\">\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e npm\/yarn link<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/kts\/articles\/779670\/\">\u041a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c VS Code \u0434\u043b\u044f \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/kts\/articles\/735104\/\">\u041a\u0430\u043a yarn v3 \u0438 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f Zero Installs \u043f\u043e\u043c\u043e\u0433\u043b\u0438 \u043d\u0430\u043c \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c ci\/cd \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430 \u0432 3 \u0440\u0430\u0437\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/kts\/articles\/566176\/\">\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0432\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f SSR \u043d\u0430 React<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/kts\/articles\/744976\/\">\u0427\u0435\u043a-\u043b\u0438\u0441\u0442 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435\u0440\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u043e\u0433\u043e \u0441\u043f\u0435\u0446\u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a><\/p>\n<\/li>\n<\/ul>\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\/829460\/\"> https:\/\/habr.com\/ru\/articles\/829460\/<\/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\"><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0413\u0440\u0430\u043d\u0442, \u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 <a href=\"https:\/\/kts.tech\/\">KTS<\/a>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0437\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043e\u0442 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<p>\u0412 \u043e\u0442\u0434\u0435\u043b\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u044b\u0445 \u0441\u043f\u0435\u0446\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0430\u043f\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u043b\u044f \u043d\u0430\u0441 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043c \u043f\u043e \u0442\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043c\u0435\u0441\u044f\u0446. \u0418\u0445 \u0444\u0440\u043e\u043d\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043a \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430<a href=\"https:\/\/react.dev\/\"> React<\/a>,<a href=\"https:\/\/styled-components.com\/\"> Styled Components<\/a> \u0438\u043b\u0438 \u0441\u0432\u044f\u0437\u043a\u0435<a href=\"https:\/\/github.com\/css-modules\/css-modules\"> CSS modules<\/a> \u0441<a href=\"https:\/\/sass-lang.com\/\"> SCSS<\/a>,<a href=\"https:\/\/mobx.js.org\/\"> MobX<\/a> \u0438<a href=\"https:\/\/axios-http.com\/\"> Axios<\/a>, \u0430 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0442\u043e \u043a \u0441\u043f\u0438\u0441\u043a\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0435\u0449\u0435<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> VKUI<\/a> \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<a href=\"https:\/\/dev.vk.com\/ru\/bridge\/getting-started\"> VK-Bridge<\/a> \u0434\u043b\u044f VK API.<\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u0441\u0431\u043e\u0440\u043a\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043d\u043e \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0432\u0430 \u0441\u0447\u0435\u0442\u0430. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0439\u0434\u0435\u0442 \u0440\u0435\u0447\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0421\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u043e\u043b\u043d\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u044d\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435: <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\">create-mediaproject-example<\/a>.<\/p>\n<p><strong>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"#1\">\u041a\u0430\u043a \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043d\u044c\u0448\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\">\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043a\u0430\u043b\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\">\u041a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\">\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0442\u0438\u043b\u0438\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\">\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\">\u0421 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\">\u0427\u0435\u0433\u043e \u043c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435<\/a><\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"#1\" id=\"#1\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0441\u0435\u0442\u0430\u043f\u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043d\u044c\u0448\u0435  <\/h2>\n<p>\u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0442\u0430\u0439\u043d\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u043e\u0439 \u0441trl+c, ctrl+v\u00a0\u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0440\u0430\u043b\u0438 \u0441\u0430\u043c\u044b\u0439 \u0441\u0432\u0435\u0436\u0438\u0439 \u0438\u0437 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0435\u0433\u043e \u0432 \u043d\u043e\u0432\u044b\u0439. \u0414\u0430\u043b\u0435\u0435 \u043e\u0447\u0438\u0449\u0430\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442-\u0434\u043e\u043d\u043e\u0440 \u043e\u0442 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0433\u043e: \u043b\u0438\u0448\u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0443\u0442\u0438\u043b\u0438\u0442, \u0444\u0430\u0439\u043b\u043e\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438 UI Kit \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u0438 \u0448\u0440\u0438\u0444\u0442\u044b, \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421 \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u043c\u0438\u043a\u0441\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u0442\u0438\u043b\u0435\u0439 \u0438\u043b\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445. \u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443 \u0431\u0435\u043a\u0435\u043d\u0434\u0435\u0440\u043e\u0432 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b, \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430-\u0434\u043e\u043d\u043e\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0434\u043b\u044f \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e CI.<\/p>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0438 \u0441\u0435\u0442\u0430\u043f\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u0437 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043d\u0430 \u0431\u0430\u0437\u0435 React Router. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u0436\u0435 \u0443\u0447\u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u043e\u0434<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> VKUI<\/a> \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 VK API, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043d\u0435\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u00ab\u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435\u00bb \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b.<\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e \u0431\u044b\u043b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u043d\u043e\u0432\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c, \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430-\u0434\u043e\u043d\u043e\u0440\u0430 \u0438 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u0430 \u0447\u0442\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0441\u0435\u0442\u0430\u043f\u0430, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435.<\/p>\n<p><a class=\"anchor\" name=\"2\" id=\"2\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0438\u0441\u043a\u0430\u043b\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443  <\/h2>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u0435\u0442\u0430\u043f\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u0414\u043b\u044f \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439: \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430.<\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u043b\u0438 \u043c\u044b \u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<a href=\"https:\/\/create-react-app.dev\/\"> Create React App<\/a>, \u0438 \u043c\u0435\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u0440\u043e\u0434\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<a href=\"https:\/\/vitejs.dev\/guide\/\"> Create Vite<\/a>. \u041e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c.<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0440\u0430\u0437\u0443 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u044e \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430: \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439 \u0440\u043e\u0443\u0442\u0438\u043d\u0433, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u0438\u043d\u0442\u0435\u0440\u043e\u0432, \u043a\u043e\u043d\u0444\u0438\u0433\u0438 CI \u0438\u00a0\u0442.\u00a0\u0434.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/create-react-app.dev\/\">Create React App<\/a> \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043b\u0438\u0432\u044b\u043c \u0432 \u043f\u043b\u0430\u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u043c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430. \u0412 CRA \u043a\u043e\u043d\u0444\u0438\u0433 Webpack \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0441\u043a\u0440\u044b\u0442, \u0438 \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043b\u0438\u0431\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <strong>eject<\/strong>, \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0440\u043e\u0434\u0435<a href=\"https:\/\/github.com\/timarney\/react-app-rewired\"> <strong>react-app-rewired<\/strong><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u043d\u0430\u0448\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u0412\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,<a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/515008\/\"> \u044d\u0442\u0430<\/a>).<\/p>\n<p>\u0421\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 \u043f\u0430\u043f\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u0431\u044b\u043b \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442, \u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439.<\/p>\n<p><a class=\"anchor\" name=\"3\" id=\"3\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430  <\/h2>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0431\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>create-mediaproject-example \u251c\u2500\u2500 src \u2502  \u251c\u2500\u2500 templates                         \u043f\u0430\u043f\u043a\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 \u2502  \u2502  \u251c\u2500\u2500 temp1                          \u043e\u0434\u0438\u043d \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u2502  \u2502  \u2502  \u251c\u2500\u2500 ...                          \u2502  \u2502  \u2502  \u251c\u2500\u2500 package.template.json \u2502  \u2502  \u2502  \u251c\u2500\u2500 README.template.md \u2502  \u2502  \u2502  \u2514\u2500\u2500 webpack.config.template.ts \u2502  \u2502  \u2514\u2500\u2500 ... \u2502  \u251c\u2500\u2500 ... \u2502  \u251c\u2500\u2500 createProject.ts                  \u0444\u0430\u0439\u043b\u044b \u0443\u0442\u0438\u043b\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f  \u2502  \u2514\u2500\u2500 index.ts                          \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u251c\u2500\u2500 ... \u251c\u2500\u2500 package.json                         \u043a\u043e\u043d\u0444\u0438\u0433 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u2514\u2500\u2500 README.md                            \u0441\u0435\u0442\u0430\u043f\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435. \u0415\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d (src\/templates\/vk-mini-app) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u044f\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438<a href=\"https:\/\/react.dev\/\"> (React<\/a>);<\/p>\n<\/li>\n<li>\n<p>UI\u2011\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<a href=\"https:\/\/vkcom.github.io\/VKUI\/\"> (VKUI<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0VK API (<a href=\"https:\/\/dev.vk.com\/ru\/bridge\/getting-started\">VK\u2011Bridge<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f\u00a0\u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430<a href=\"https:\/\/reactrouter.com\/\"> (React\u2011Router<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439<a href=\"https:\/\/mobx.js.org\/\"> (MobX<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u00a0\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (<a href=\"https:\/\/axios-http.com\/\">Axios<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0438\u043a\u0441\u0438\u043d\u043e\u0432 SCSS, \u0443\u0442\u0438\u043b\u0438\u0442 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0VK API, \u043d\u0430\u0431\u043e\u0440 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0441\u0442\u043e\u0440\u043e\u0432, \u0438\u00a0\u0442.\u00a0\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 dev\u2011\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u00a0\u2014 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (Webpack);<\/p>\n<\/li>\n<li>\n<p>\u043b\u0438\u043d\u0442\u0435\u0440\u044b (Eslint, Stylelint, Prettier);<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u043e\u0432 (Typescript, SCSS, Styled\u2011Components);<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0434\u043b\u044f\u00a0\u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0430\u0439\u043b\u044b \u0441\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0436\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430 (src\/index.ts) \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0440\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<ol>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 \u0441\u00a0\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u0434\u043b\u044f\u00a0\u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u0412\u00a0\u043d\u0435\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430, \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0443\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0440\u044f\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043e\u043f\u0446\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u044e\u0449\u0430\u044f \u043f\u043e\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u0443 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u00a0\u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0431\u0435\u0437\u00a0\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 \u043f\u043e\u0441\u0442\u2011\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c git\u2011\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<p><a class=\"anchor\" name=\"4\" id=\"4\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0442\u0438\u043b\u0438\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0442\u0430\u043f\u0430  <\/h2>\n<p>\u0421\u0442\u043e\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0442\u043e\u0447\u044c-\u0432-\u0442\u043e\u0447\u044c \u043f\u043e \u043d\u0430\u0448\u0438\u043c \u043b\u0435\u043a\u0430\u043b\u0430\u043c. \u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u043d\u0435 \u043d\u0430\u0434 \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0442\u0430\u043f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0449\u0435. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>\u0422\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0435\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0444\u0430\u0439\u043b <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/index.ts\">src\/index.ts<\/a>:<\/p>\n<details class=\"spoiler\">\n<summary>src\/index.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { parseOptions } from \".\/parseOptions\"; import { createProject } from \".\/createProject\"; import { postProcess } from \".\/postProcess\"; import { printError, printSuccess } from \".\/utils\/print\"; import { MESSAGES } from \".\/config\";  const main = async (): Promise&lt;void> => {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442 \u044e\u0437\u0435\u0440\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d   const options = await parseOptions();    try {     \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u0430\u043f\u043a\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430     createProject(options);     \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438     postProcess(options);      printSuccess(       MESSAGES.projectCreateSuccess(       options.templateName,        options.buildDir     )     );   } catch {     printError(MESSAGES.projectCreateError);   } };  main();<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d. \u0423\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/parseOptions.ts\">src\/parseOptions.ts<\/a> \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435. \u0417\u0434\u0435\u0441\u044c \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:\/\/github.com\/SBoudrias\/Inquirer.js\"> Inquirer.js<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>src\/parseOptions.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import * as fs from 'fs'; import * as path from 'path';  import { prompt } from 'inquirer';  const TEMPLATES_DIR_NAME = 'templates';  \/\/ \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f export type OptionsType = {   \/\/ \u0438\u043c\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430   templateName: string;   \/\/ \u043f\u0443\u0442\u044c \u043a \u0435\u0433\u043e \u043f\u0430\u043f\u043a\u0435   templatePath: string;   \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u0438 \u0435\u0433\u043e \u043f\u0430\u043f\u043a\u0438)   buildDir: string; };  \/\/ \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0432\u0432\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f export const parseOptions = async (): Promise&lt;OptionsType> => {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043f\u0430\u043f\u043a\u0435 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438   const templatesPath = path.join(__dirname, TEMPLATES_DIR_NAME);   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u043d \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438   const choices = fs.readdirSync(templatesPath);    \/\/ \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432   const questions = [     promptQuestions.templateName(choices),     promptQuestions.buildDir,   ];    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u044e\u0437\u0435\u0440\u0430   const { templateName, buildDir } = await prompt(questions);    \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u043c \u043e\u043f\u0446\u0438\u0439   return {     buildDir,     templateName,     templatePath: path.join(templatesPath, templateName),   }; };  \/\/ \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440 \u0438\u043c\u0435\u043d\u0438 \u043f\u0430\u043f\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 const validateDirectoryName = (dirName: string): true | string => {  return \/^([A-Za-z\\\\-_\\\\d])+$\/.test(dirName) || 'Incorrect directory name'; };  \/\/ \u043a\u043e\u043d\u0444\u0438\u0433 \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438 (\u0432 \u043f\u043e\u043b\u0435 message) \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043e\u043f\u0446\u0438\u0439 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 const promptQuestions = {   templateName: (choices: string[]) => ({     name: 'templateName',     type: 'list',     message: 'Select template',     choices,   }),   buildDir: {     name: 'buildDir',     type: 'input',     message: 'Project directory (also name)',     validate: validateDirectoryName, };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0434\u0435\u043b\u043e \u0432\u0441\u0442\u0443\u043f\u0438\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 <a href=\"https:\/\/github.com\/ktsstudio\/create-mediaproject-example\/blob\/main\/src\/createProject.ts\">src\/createProject.ts<\/a>. \u041e\u043d\u0430 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <a href=\"https:\/\/ejs.co\/\">EJS<\/a>):<\/p>\n<details class=\"spoiler\">\n<summary>src\/createProject.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import * as fs from \"fs\"; import * as path from \"path\";  import * as ejs from \"ejs\";  import { MESSAGES } from \".\/config\"; import { printError } from \".\/utils\/print\"; import { OptionsType } from \".\/parseOptions\";  \/\/ \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 export const SKIP_FILENAMES = [\".DS_Store\", \".git\", \"node_modules\"];  \/\/ \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0435\u0433\u043e<\/code><\/pre>\n<\/div>\n<\/details>\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-426498","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/426498","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=426498"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/426498\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=426498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=426498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=426498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}