Transcript for:
Основные концепции и возможности Webpack

Приветствую вас друзья в очередном фундаментальном курсе на канале от А до Я в котором мы разберём все основные концепции и возможности вебпак и также рассмотрим Как создать свой манорен Нда на основе Federation module ролик будет очень полезным как следует из названия фундаментальным и я всем Настоятельно рекомендую его даже если ском вы не работаете для тех кто не в курсе на канале есть прям отдельный плейлист с фундаментальными большими курсами по разным темам и вот после ве пака планирую добраться до ангуляр я его когда-то записывал больше чем на 3 часа был ролик но так и не озвучил и не домон его в итоге он устарел я его уже выкладывать не стал Итак переходим к теме ве пака сразу предвижу комментарий по поводу того Зачем изучать вебпак уже есть Вид уже есть другие сборщики устарел здесь сразу хочется показать вот эту вот статистику 26 млн скачиваний за неделю webpack - это мощнейший продакшн инструмент который умрёт нескоро Да какие-то новые небольшие проекты летят на новых сборщика но энтерпрайз по-прежнему живёт на впаке и какое-то время он ещё на нём будет жить обязательно V пак - это легендарный инструмент сборщик который в своё время вообще перевернул многое и разобравшись с ним разобравшись с его концепциями А вот кстати по-прежнему работает нормально только в нём Ну и что я хотел сказать если вы разобрались с ним разобраться с каким-нибудь вид это будет для вас как ДЖД ну и плюс рано или поздно с вебком Я думаю столкнётся каждый поэтому понимать как он работает тоже важно Ну и не буду сильно сведением затягивать Давайте посмотрим на план этого ролика и приступим к обучению я план сокращался огромным и поэтому большое количество деталей в него не попало поэтому максимально по верхам быстренько пробега и приступаем к обучению Итак рассмотрим максимально базовую конфигурацию обозначим для чего вообще нужен vack будет немного теории научимся принимать опции конфигурации работать с переменными окружения с Production и Def сборкой настроим HTML подключим к ним скрипты научимся работать с плагинами поймём концепцию лоде настроим typescript поработаем с регулярными выражениями webpack config также переведём на typescript обязательно настроим Def Север Watch режим поговорим про Source Map карты исходного кода настроим react jsx чтобы всё это у нас из коробки работало без каких-либо проблем также обязательно настроим стили CSS научимся работать с пре процессорами в частности на примере scss Когда наш webpack config начнёт разрастаться мы его декомпозировать в наших и БМ реализуем роутинг в нашем приложении поговорим про линий вые чанки размер бандла и код Сплин настроим А и resolving модулей опять же если слова пока что для вас непонятны в ходе курса со всем этим разберёмся научимся работать с а сетами картинками шрифтами иконками и так далее поработаем с глобальными переменными сборками и рассмотрим концепцию 3 shaking на примере ускорим сборку за счёт того что вынесем проверку типа в тайп скрипто в отдельный процесс поговорим про концепцию Hot Mod replacement и настроим её настроим фави конку и поговорим про то как копировать файлы в итоговую сборку также настроим B и для того чтобы он не был чёрным ящиком мы создадим свой плагин и посмотрим на то как он работает про Source Map я уже говорил но в данном пункте мы рассмотрим прямо детально на то как это всё работает и для чего карты исходного кода нужны далее большая часть курса - это настройка морето фронтов здесь будет конфигурация проекта и настройка воркспейс далее настроим сами микросервисы с помощью webpack module Federation и также за счёт нашего монорельсе сборка вебпак Ту что мы делали в первой части ролике как расширять тест конфиги Как использовать какие-то утилитарные функции общие компоненты и так далее В общем этот план я ужа Как только можно было очень много деталей упущено в каждом из этих пунктов будет очень-очень много пунктов деталей моментов нюансов разобрано и ролик должен получиться очень и очень полезным Ну и на этом друзья с вводной частью мы заканчиваем и приступаем непосредственно к практике не забываем друзья ставить лайки писать комментарии это правда всё очень помогает всем спасибо и приступаем Итак друзья создаём чистый проект я буду использовать для разработки Вы можете использовать vs код или любую другую среду разработки Понятное дело что у вас должен быть установлен node.js и npm в первую очередь проинициализировался код нашего приложения и внутри создаём Index JS Файлик для начала Давайте напишем здесь какой-нибудь код чтобы вообще убедиться что у нас всё будет работать Ну давайте сделаем по классике Hello world Ну понятное дело что если с помощью node.js мы этот файл запустим то в логе у нас всё выведется но также Давайте создадим рядом другой Файлик и экспортируем отсюда какую-нибудь функцию экспортируем через mpt модули эта функция будет просто складывать А и про функция возвращаемся в Index JS Файлик теперь Давайте попробуем здесь вывести в логе результат выполнения этой функции используем классические импорты очевидно что они по дефолту работать не будут причём работать из коробки это не будет как в браузере так и в Note JS для этого придётся проделать определённые махинации либо же воспользоваться бандлер который все эти модули будет объединять в один бандл очевидно что мы будем использовать webpack и Давайте сразу же начнём по ходу курса мы будем активно пользоваться документацией чтобы вы знали что где искать что За что отвечает и как вообще этим пользоваться потому что у начинающих часто с этим есть проблемы в первую очередь Как де зависимости Нам необходимо установить webpack И webpack cli по ходу курса я буду делать Вот такие вот вставки с версиями конкретными которые использовались в данном ролике Настоятельно рекомендую использовать именно те версии которые использовал я потому что что-то чуть-чуть могло поменяться на процесс обучения это не повлияет А у Вас могут возникнуть трудности отлично с этим разобрались устанавливаем webpack и webpack C как D в зависимости потому что webpack используется только на этапе разработки то есть после того как код мы скомпилировать webpack для того чтобы собрать бандл сделать сборку нашего проекта и Давайте сразу же попробуем пишем npm Run build видим что у нас сборка прошла в целом без ошибок есть один ворнинг по умолчанию без конфига есть какие-то предна сройс функции Сам он объединил Ну то есть заранее предпослан Log то что получается в результате сборки и называется бандл Давайте двигаться дальше теперь мы будем с нуля впа конфигурировать и адаптировать под наши условия если двигаться дальше по документации то нам рекомендует создать файл webpack config.js Давайте его создадим создаём прямо в корне нашего проекта webpack config JS здесь будут абсолютно все настройки также в документации нам сразу предлагают самый-самый базовый вариант настройки запускать сборку мы будем в среде Note JS поэтому используем здесь по умолчанию обычный новский мол эпо Command JS Но чуть позже Мы настроим Здесь также привычные экспорты и импорты и первая опция в нашей конфигурации - это entry это путь к точке входа в наше приложение как правило это какой-то Index JS файл и как сказано в документации необходимо путь до этого файла указать лучше сразу использовать стандартный модуль Pass из node.js для того чтобы более корректно обрабатывать все эти пути на разных операционных системах в вебшторме единственно включу поддержку nodejs синтаксиса склеиваем участки пути через Па resolve указываем dirname - это текущая папка src и Index JS это путь как раз до файлика entry файла точка входа в наше приложение теперь запустим npm Run Build ещё раз опять же видим что сборка прошла Ну видим в принципе тот же йн Файлик ничего не изменилось также точек входа в приложение в принципе может быть несколько несколько каких-то исходных файлов которые вы по-разному как-то хотите за один проход сборки собрать и их можно указывать вот в таком вот формате ключ значения где это как раз название риита делаем сборку видим что у нас теперь появился Файлик Hello world он получился точно такой же потому что это тот же файл но у него другое название если мы сейчас сделаем какой-нибудь другой Икс 2 JS файл и здесь выведем Hello 2 здесь вот эту строчку продублируйте появилось два файлика и как можете заметить они уже разные но подавляющем большинстве приложений у вас будет один entry Point поэтому лишнее здесь можно убрать и оставить только путь до нашего идекс JS файла отлично с этим разобрались двигаемся дальше давайте пока папку дис со сборкой удалим чтобы она нам не мешалась и рассмотрим второе по важности свойство - Это output здесь указывается конфигурация того куда и Как Сборка у вас будет происходить опять же Сыла документации здесь в примере простейшем показано Куда В какую директорию и с каким названием файл у вас будет сохраняться файне Давайте поменяем оставим просто Bundle JS и папку в которую будет происходить сборка назовём Неди а Build Как видите здесь используется также па resolve запускаем сборку npm Run Build видим что она прошла и Обратите внимание что папка называется и Bus вем фигу Но на самом деле у статичного файне есть проблемы браузер будет эти файлы кэшировать и даже когда вы какие-то изменения в эти файлы будете вносить он будет доставать их из кэша чуть позже мы решим эту проблему а пока Давайте посмотрим если у нас в папке Build образуется много разных файлах нам каждый раз их придётся руками удалять ну вернее не придётся если мы укажем опцию Clean True и Как видите при каждой сборке перед тем как положить новые файлы в эту папку он будет их очищать теперь Давайте разберёмся с названием нашего бандла чтобы каждый раз название не было статичным и было каким-то динамичным чтобы браузер файлы кэширование У пользователя всегда была максимально свежая версия нашего приложения на каждый релиз Давайте откроем настройки конфигурации и вот здесь вот для свойства файне Как видите можно указать вот такие вот шаблоны всякий там в общем в зависимости от того какой шаблон вы укажете название будет на выходе всегда разным ну давайте с этим немного поиграем укажем вот такой вот шаблон так запустим сборку npm Run Build Ну видим что Файлик у нас назван mains от названия Рита ent по умолчанию как раз называется если мы добавим здесь Е в квадратных скобочках какой-нибудь хэш то он будет брать хэш от содержимого файла и будет добавлять этот хэш в название опять же я это не придумал Вот это всё взято из документации запускаем сборку ещё раз и видим что у нас появился Файлик Вот с таким названием При этом если мы запустим сборку ещё раз название файла не поменяется потому что содержимое файлов изменено не было но если мы поправим содержимое файла и запустим сборку ещё раз чуть-чуть подождём видим что название файла у нас поменялось то есть оно берётся на основании содержимого Таким образом мы достигаем того что всяких коллизий У нас не будет если содержимое файлов одинаковое то файл у нас будет называться одинаково Если оно разное то файлы будут называться по-разному это вот самая минимальная конфигурация которую можно сделать впаке здесь в принципе всё просто и надеюсь с этим понятно двигаемся дальше видим что у нас в консоли есть waring ругается на отсутствие опции и мод определяет то в каком формате у нас происходит сборка в режиме разработки или уже в продакшн билде догадаться думаю не сложно отличается эти два режима скоростью сборки какими-то оптимизация и моментами которые критичны для продакшена и некритично для сборки если мы запустим в деф режиме мы увидим вот такой вот Файлик здесь добавлен всякий вспомогательный код он не минимизированы он в общем к проду не подготовлен он нужен исключительно на этапе Работки но если мы мод передадим значение Production мы увидим вот такой вот сжатый лаконичный оптимизированный код здесь удалены все комментарии лишние пробелы переносы строк и так далее двигаемся дальше вообще захард кодить значение мода вот так вот прямо в конфиге это конечно хорошо но хотелось бы иметь возможность передавать это значение откуда-то Извне например в виде переменных окружения Ну и конечно wep такую возможность поддерживает можно использовать любой формат переменных окружения передать их просто при запуске в консоли создать DN File или же задать их прямо на уровне операционной системы Ну давайте пойдём самым простым путём передадим их просто при запуске скрипта делается это вот таким вот образом передаём мо и указываем здесь development То есть у нас будет два скрипта в package Son один для де сборки другой для продакшн сборки соответственно в зависимости от того какой скрипт Мы запускаем у нас передаётся разный мод Ну таким вот образом это всё выглядит Теперь давайте этот мод динамически передадим Ну и для этого посмотрим в документации как это вообще делается Обратите внимание что здесь экспортируется не напрямую config а экспортируется функция которая принимает аргументом как раз вот эти N в переменные и уже из этой функции возвращается config вот таким вот образом N в переменные чуть позже мы их ещё тизим с помощью тайп скрипта Ну пока оставляем Так ну и соответственно здесь передаём N В точка мо и на случай если эта переменно окружения не задана можем указать в качестве дефолта например development делаем сборку npm Run Build Def Обратите внимание видим что у нас код не минимизированы делаем npm Run Build prod видим что код минимизированы то есть вот так с помощью переменных окружения можно передавать какую-то конфигурацию Извне чуть позже мы будем так передавать порт ещё какие-то опции В общем так можно передавать любые данные Извне которые нужны для конфигурации и на этом этапе в принципе у нас всё хорошо JS файлы мы обрабатывать научились но пока что это всё не имеет особого смысла без HTML файла который есть в любом фнн приложении поскольку мы потом будем разрабатывать react приложение сразу создадим div с ашнико Root чтобы туда потом вмонтировать реакторс приложение и теперь на Наша задача сделать так чтобы в эту HTML автоматически подставляли скрипты ссылкой как раз на те JS файлы которые у нас компилируется в результате сборки то есть должен вот так вот здесь указываться путь под который подгружает JS файл для того чтобы Ну соответственно HTML понимал какой JS должен выполняться и вот Наша задача сейчас это сделать Давайте Кстати запустим этот Файлик убедимся в том что у нас всё работает кстати конечно эту ссылку можно вот так вот руками указывать как мы это сделали но наша задача - это автоматизация сборки и плюс у нас каждый раз динамические названия бандл и чанков и поэтому мы хотим чтобы не приходилось каждый раз вот так вот руками ходить в HTML файл менять ссылку на этот файл Ну понятно что так никто не делает Это скорее для начинающих объясняю Вот и Наша задача сделать так чтобы вот этот вот путь подставлял до бандла и чанков автоматически и впаке существует механизм плагинов которые добавляют какой-то дополнительный функционал этих готовых плагинов огромное количество и при этом Вы можете также за счёт AP которая есть у V пака писать свои плагины которые будут реализовывать тот функционал который Вам нужен в ходе курса мы будем использовать только готовые плагины свои писать мы не будем Однако использовать мы будем все самые основные часто используемые плагины в первую очередь Давайте воспользуемся HTML VP плагином это плагин который будет выполнять именно тот функционал который Нам нужен Ну и в первую очередь устанавливаем его Как де зависимость устанавливаем указанную на слайде версию видим что у нас появилась новая строчка в package Son в качестве де зависимости Ну и теперь давайте посмотрим как этим плагином пользоваться копируем прямо вот эту строчку в конфиге под плагины есть отдельное свойство это массив плагинов и Обратите внимание что мы создаём объект из класса HTML Пак плагин то есть здесь вот есть определённый набор входных опций которые мы можем передать и основная опция - это template Это ссылка до нашего HTML файла который будет использоваться в качестве шаблона именно туда вот этот плагин будет подставлять путь до нашего бандла до наших JS файлов указываем опять же через па resolve dirname папка Public Икс HTML это как раз путь до нашего HTML файла документации кстати есть Прямо отдельный такой раздел про плагины здесь представлено большое количество плагинов официальных которые в паком как бы признаются но также есть ещё большое количество плагинов которые писали разработчики Ну грубо говоря Open Source Ну если мы в поиски сейчас прямо в браузер нам напишем HTML webpack плагин то мы здесь прямо найдём отдельную страничку по этому плагину в том числе здесь будет ссылка прямо на github этого плагина с подробной документацией с опиш кой Как видите Здесь много звёзд опять же все эти уточнения делаются для начинающих потому что многие пользоваться документацией не умеют и при этом vack - это достаточно сложно для начинающих инструмент поэтому я стараюсь Как можно подробнее всё показывать и рассказывать так с этим понятно двигаемся дальше предлагаю сейчас вот эти опции из HTML vack плагина убрать и попробовать сделать сборку посмотреть что у нас будет Как видите в папке Build У нас появился HTML Файлик здесь же можно увидеть что у нас подставился скрипт всё хорошо но мы в Боде не видим того самого Diva с дишни ком Root который мы добавляли То есть если мы не указываем телей этот плагин автоматически создаёт дефолтный HTML файл но Давайте Теперь попробуем сделать боркум template И вот здесь мы уже видим divs ID Root видим что скрипт подставился то есть теперь наш вот этот вот HTML Файлик используется как шаблон Сюда можно добавлять любые Мета теги ссылки на какие-нибудь CSS файлы какие-то свои кастомные скрипты И если мы сейчас сделаем сборку мы увидим что вот всё что мы сейчас дописали оно сохраняется то есть вот этот файл он используется как основа и в эту основу HTML webpack plugin уже добавляет скрипты Ну давайте пока что мы говорим про плагины попробуем добавить ещё какой-нибудь планчик это дефолтный ве павский плагин который идёт по умолчанию Называется он прогрес плагин импортируем в первую очередь webpack и уже внутри самого веб пака мы к этому Прогресс плагину можем обратиться вот таким вот образом не забываем добавить New потому что мы должны передать объект увеличим немного размер терминала чтобы видеть как проходит сборка Ну и на долю секунду на самом деле если замедлить можно увидеть как там появляются проценты сборки на самом деле она сейчас проходит очень быстро и это незаметно Ну и собственно говоря всё что делает этот плагин он показывает процент того насколько прошла сборка кстати в продакшене его особо не рекомендуют использовать потому что он может сильно замедлять сборку так отлично с этим разобрались к плагинам Мы ещё обязательно вернёмся их будет минимум пять-шесть а то и семь штук входе этого курса А теперь предлагаю научиться обрабатывать typescript файлы и познакомиться с концепцией лоде впаке во-первых меняем расширение у наших файлов с JS на ТС Ну и во-вторых Давайте напишем какой-нибудь tpt код минимальный просто укажем тип аргументов который мы ожидаем на входе ну Давайте проверим что у нас на это tyt реагирует видим да что он у нас ругается если мы пытаемся передать в строку вместо числа и в entry меняем путь с ИК JS на инк TS Ну и пробуем сделать сборку Как видите сборка падает с ошибкой И мы видим что вот этот вот ТС файл обработать webpack не может То есть он не понимает вообще что это за файл и не может его зарез Вить и это Неудивительно потому что wep по умолчанию работает с JS файлами про какие-нибудь SG png там про какие-нибудь шрифты по умолчанию не знает Нам необходимо указать ему как такие файлы с таким расширением обрабатывать И для этого в впаке есть концепция лоудейли с тем или иным расширением по тому расширению которое мы указываем в этом лоде обработчик понимает какие файлы ему необходимо обработать и на выходе он их компилирует тест например в JavaScript какие-нибудь svg файлы мы можем конвертировать сразу в react компоненты scss или less файлы мы можем конвертировать в CSS Ну думаю основная идея ясна Но что самое важное на что хотелось бы обратить внимание что порядок лоде очень важен потому что на выходе из каждого лоде мы получаем обработанный уже код причём вот воспринимать это нужно от обратного грубо говоря с конца массива мы идём Давайте вот посмотрим на примере Представьте что это у нас массив в котором Ука по порядку первым элементом Style Loader вторым элементом CSS Loader и третьим элементом scss Loader то есть Наша задача обработать scss Мы указываем в качестве регулярного выражения для scss лоурайдере на выходе мы получаем скомпилированный CSS этот скомпилированный CSS попадает уже в CSS Loader где происходит компиляция CSS Command JS и попадая в Style Loader то что мы получили из CSS Лора превращается уже в JS строки в CSS JS строки которые попадают в финальный бандл при этом Style Loader мы можем подменить на какой-нибудь другой и сделать так чтобы у нас получались не JS строки А например создавались отдельные CSS файлы то есть здесь основная мысль которую я хочу донести - это именно вот этот порядок обработки кода это очень важный момент потому что дважды обработав typescript например каким-нибудь typescript лором и B лором мы можем получить что-то странная в зависимости от того какие действия мы захотим выполнить так с этим думаю разобрались Давайте двигаться дальше попробуем настроить обработку тайп скрипта в нашем VP конфиге Ну опять же пользуемся документацией и в первую очередь что нам говорят нам говорят установить сам тайпскрипт и TS Loader давайте это сделаем устанавливаем нужные версии заглянем в package Son видим что у нас появился здесь Test Loader и typescript опять же напоминаю что устанавливаем конкретные версии двигаемся дальше Ну теперь понятное дело чтобы typescript у нас начал работать Нам необходимо создать T config с настройками для непосредственно самого тайп скрипта его бы вам создавать пришлось в любом случае неважно используете Вы vpd или любой другой сборщик TS config Придётся делать всегда когда вы используете typescript двигаемся по документации дальше И теперь мы видим что от нас требуется добавить вот такой вот массив как раз Слоу здесь Можете заметить TS Loader и вот такой вот резольвер в котором мы указываем расширения которые необходимо будет резолвится сейчас добавим всё это в config и поподробнее разберём но сначала предлагаю запустить сборку чтобы убедиться что typescript у нас действительно компилируется npm Run Build Pro L npm Run Build Def видим что сборка прошла И при этом видим тот же самый код но уже написанный на тайп скрипте с использованием типизации теперь поговорим о конфиге в массиве Rules указываются как раз те самые лоде в том порядке О котором я говорил в политест указывается регулярка название тех файлов которые мы хотим обрабатывать обычно здесь указывается расширение в данном случае регулярка нам говорит о том что мы обрабатываем TS и tsx файлы Давайте даже убедимся в этом откроем regex 101 ставим сюда свою регуляр и попробуем написать какие-нибудь названия файлов main.js Как видите его не обрабатывает регулярка Main TS обрабатывает и Main tsx тоже обрабатывает то есть эта регулярка направлена именно на TS и tsx файлы все остальные она будет пропускать мимо себя и соответственно эти файлы в Loader не попадут ну и соответственно views указывается название Loader А exclude - это то что мы не обрабатываем в данном случае мы не обрабатываем папку node modules в resolve extensions мы указываем расширения которые необходимо обработать как правило Вот именно здесь указываются расширение файлов с исходным кодом то есть мы не пишем вот так test. TS мы оставляем просто тест и он автоматически понимает что это файлы с исходным кодом то есть обычно мы вот импорты делаем Вот так мы не указываем что мы импортируем компоненты из файла с расширением tsx мы просто указываем компонент и вот благодаря вот этой вот настройке как раз ревин вот этих вот расширений и происходит он понимает что это файлы с исходным кодом Причём здесь порядок в массиве тоже важен он будет их Именно по порядку пытаться разрезов Вить Примерно вот так вот ло работают мы к этому ещё обязательно вернёмся мы будем обрабатывать все возможные варианты файлов Ну давайте откроем нашу HTML посмотрим что у нас всё работает открываем открываем терминал Ну и видим что Hello world и значение суммы которые мы посчитали выводится в логи Отлично На этом этапе У нас всё хорошо двигаемся дальше Теперь мы можем писать код на тайп скрипте это конечно замечательно но хотелось бы сам вебпак плагин также написать на тайп скрипте зати Зро например N в переменные типизировать какие-нибудь опции входные В общем хотелось бы его также писать на тайп скрипте но если мы просто поменяем расширение файла и запустим сборку то мы увидим что всё у нас свалится с ошибкой Ну и опять же ничего нового Мы не придумаем идём в документацию пишем config typescript И первую же ссылочку открываем здесь будет инструкция по тому как настроить config на тайп скрипте Ну и в первую очередь опять же устанавливаем зависимости де зависимости обращаем на это внимание тайпскрипт сам у нас уже установлен второй раз его устанавливать не нужно устанавливаем типы для ноды потому что впа работает в среде Note JS типы для ве пака и непосредственно сам TS noe и также нам ещё понадобится установить webpack Dev сервер в будущем и поскольку мы всё равно будем его устанавливать Давайте сразу ити установим после установки заглянем в Pack видим что новые строчки появились Ну давайте двигаться дальше во-первых видим что импорты через require мы можем заменить сразу на обычные импорты давайте скопи И вот так вот заменим вот этот вот пас удаляем единственно нам понадобится ещё HTML plin здесь импортировать Давайте средствами среды разработки воспользуемся Alt Enter и шрм автоматически нам подставляет единственно вот здесь нужно будет добавить вот такую вот конструкцию грубо говоря мы сообщаем что мы импортируем всё как webpack как HTML webpack plin попробуем сделать сборку сейчас чуть позже расскажу для чего это нужно Ну и видим уже что сразу у нас упала сборка из-за того что enf у нас указан неявно как any пока что явно это укажем чтобы сборка прошла но видим что теперь всплывает другая ошибка теперь он ругается как раз на вот эти вот импорт на самом деле мы просто до конца по документации не прошли Ну и для начала Давайте зати зру сам конфиг для того чтобы пользоваться всеми прелестями автокомп создаём отдельный объект с конфигом и вот это вот всё что мы уже написали переносим в него и возвращаем его из этой функции от модуля exps можно избавиться и воспользоваться обычным э default которым мы пользуемся в привычной нам разработке Ну и Давайте двигаться по документации дальше нам рекомендуют добавить две вот этих строчки в TS config Они как раз нужны чтобы правильно обрабатывать импорты пока что давайте слепо добавим и чуть позже мы прямо на них остановимся Я прямо распишу для чего они нужны добавляем благодаря тому что эти две строчки мы добавили Вот от этого можно избавиться импортируем привычным нам образом пробуем сделать сборку сейчас она скорее всего тоже свалится с ошибкой Да но и возвращаемся к документации мы на самом деле ещё не всё доделали читаем что здесь написано Обратите внимание что вам также необходимо проверить тест config если модуль проставлен у вас Command JS то всё будет хорошо иначе нужно будет сделать ещё дополнительные действия Давайте проверим что у нас в тест конфиге мол у нас стоит ecmascript 6 это нужно чтобы как раз использовать импорты и экспорты полноценно но если мы пойдём дальше по документации мы увидим что у нас есть три пути решения изменить TS config изменить TS config и добавить settings для TS Note или установить TS config Pass Давайте пойдём по второму пути он самый простой добавляем здесь вот такую вот опцию для TS Note мы переопределять грубо говоря comper options и указываем module Command JS А здесь нам рекомендуют установить module SN Ну и Давайте попробуем сделать сборку теперь немного ждём и видим что сборка прошла то есть ничего мы не придумали прошлись по шагам прямо в документации сфгу Нам необходимо config и вс у нас заработало Теперь давайте воспользуемся сразу преимуществами крипта и зати зру переменные окружения пока что на вход мы ожидаем одну переменную это мод которая может принимать два значения либо прок либо development указываем их в виде вот такого Union типа тием ну и теперь обращая мы ВИМ есть переменная мод которая принимает одно из этих значений чуть позже у нас количество этих переменных будет расти и мы всегда будем знать что у нас на входе ожидается также я обещал пояснить за те флажки которые мы добавили в Test config давайте к ним вернёмся чтобы было более понятно и каких-то пробелов не оставалось сейчас Я прямо примеры с комментариями вставлю первый флажок позволяет работать с пакетами которые используют Command JS то есть импорт происходит там вот через require вот таким вот образом на примере момен использует Command JS если мы тием его через вот такой вот импорт мы получим undefined с этим флажком мы получим объект если что Ставьте на паузу и более вдумчиво считыватели отеки также могут не иметь дефолтном порта то есть вот так вот когда мы импортируем прямо вот сразу какой-то объект указываем какое-то название это называется дефолтный импорт соответственно также мы снизу вот по дефолту экспортируем и чтобы не указывать Вот эту вот звёздочку S там какой-то объект мы можем добавить вот этот флажок и по умолчанию вместо вот такого вот импорта мы можем писать Вот такой вот как снизу опять же если не очень понятно объяснил Ставьте на паузу и учитывайте в комментарии это больше про ТС поэтому прям подробно на этом не останавливаюсь мы всё-таки здесь рассматриваем webpack Итак чуть раньше я упоминал некий де сервер и давайте сейчас поговорим о нём Это очень важный функционал о котором стоит сказать пораньше если мы сейчас внесём какие-то прав откроем нашу htm естественно здесь ничего не обновится потому что какого-то ре билда у нас не происходило то есть нам надо явно запустить сборку явно открыть новый HTML Файлик и только тогда мы увидим что вот тут вот значение у нас поменялось и вот Def сервер позволяет Как раз на какие-то изменения в коде автоматически запускать ребилд чтобы все изменения сразу у нас отображались и нам было комфортно разрабатывать тут у нас есть ссылочка на develop Guide Давайте откроем её Ну во-первых нам говорят мод проставить про Source Map мы чуть позже поговорим Здесь нам предлагают три варианта работы грубо говоря в режиме Def сервера первые - это простой вепа ковский Watch Mode Это самый такой банальный стандартный простой способ vack Def Server - это что-то среднее конфигурируется и wep Def middleware - это грубо говоря уже такой продвинутый способ настройки Def сервера Когда вы прямо в Note JS поднимаете сервер подключаете middleware можно использовать там какой-нибудь Express например Watch Mode использует слишком тривиально V Pack de middleware для нас избыточно Но пойдём по пути золотой середины будем использовать vack Def Server листаем чуть ниже и посмотрим как его использовать вот здесь прямо отдельный раздел про VP Dev Server Ну и в первую очередь как обычно необходимо установить де зависимость устанавливаем убеждаемся что в package Son добавилась новая строчка Вот она Ну и также Напоминаю что чуть ранее мы устанавливали ещё типы для де сервера это тоже важно поскольку конфиг мы пишем на тайп скрипте двигаемся дальше надо добавить вот такую вот опцию Def сервер Чуть позже это сделаем и запускать сам Def сервер будем с помощью вот такой команды webpack Surf Давайте её скопирую и сразу же добавим Def Север но при этом Обратите внимание что тайпскрипт у нас ругается по умолчанию Такое поле в типе Вебка отсутствует ну давайте откроем документацию де сервера и вообще посмотрим что тут про это нам пишут здесь есть про это прям целый раздел и здесь Обратите внимание что нам необходимо импортировать тип из de Север для того чтобы ty скрипт начал его подхватывания ста вынести чуть позже мы так и сделаем пока Давайте прямо здесь укажем все настройки потому что мы потом будем декомпозировать конфиг здесь можно указать порт здесь можно указать флажок Open ну и соответственно запускаем с помощью команды webpack Surf Давайте в скрипты только это добавим единственно команду Surf заменим на болею привычную из Create react App Start и на этом в принципе всё уже должно работать здесь необходимые опции мы задали нува Давайте попробуем запустить npm Run немного ждём пока у нас де сервер запустится Ну и в консоли видим наш Hello world и результат подсчёта суммы Давайте попробуем прямо в realtime поменять какие-нибудь значения Ну видим да что они автоматически в режиме Live скажем так меняются Также хотелось бы иметь возможность запускать на любом указанном порту и мы уже знаем как передавать Какие опции в нашем случае это опция пор принимать мы её будем из переменных окружения Ну и Например если эту переменную не указали будем запускать на тысячном порту Давайте попробуем запустить без переменное окружение видим что запустился на тысячном порту де сервер этот порт можно прокинуть через SCP P можно прокинуть прямо через строку ввода передам вот таким вот образом единственно видно почему-то вебшторм затемняет название флажков так единственно Ага да когда запускаете вот здесь вот нужно такой разделитель поставить два минуса и потом уже указывать какие-то флажки вот даже под свечу чтобы получше видно было Вот Да теперь видим что переменная передалась правильно и видим что у нас сервер запустился на тысячном порту то есть вот таким вот образом можно передавать ещё прямо в строке какие-то перемен окружение и запускать на любом порту на котором нам это понадобится можно запустить даже два приложения одновременно на разных портах Ну если зачем-то это нужно с де сервером мы почти закончили единственное когда мы смотрели документацию там было упоминание неких sce Map давайте к ним вернёмся и посмотрим для чего это нужно открываем документацию так где-то здесь это было вот этот раздел Ну и на самом деле как не трудно догадаться Когда у нас на выходе из огромного количества наших gss файлов получается один финальный бандл не очень понятно как потом отслеживать ошибки Как понять где они произошли Как правильно отслеживать к Trace смотреть в каком порядке были вызваны функции где именно произошла ошибка и вот Source Map - это как не трудно догадаться из перевода карты исходного кода которые как раз помогают нам понять В каком исходном виде был написан код если мы сделаем сборку мы увидим снизу вот такую вот строчку sce mapping URL Ну и СРС мапы в принципе уже будут работать и если вдруг в коде мы где-то не обработали какую-то ошибку если где-то у нас какой-то баг если ошибка где-то стрельнет мы сможем понять где именно она стрельнула сейчас пока что я в таком ознакомительной примере разберём чтобы понятнее было а то сейчас у нас всего два файла и я думаю на двух файлах такое объяснять не очень понятно будет Вот двигаемся дальше уже Сейчас может быть понятно что у нас два режима сборки это прок и development и очевидно что какие-то плагины какие-то лоде какие-то настройки по типу деф сервера Мы хотим в одном режиме как бы запускать использовать а в другом режиме для скорости сборки для всяких оптимизаций Мы хотим их исключить соответственно мы можем смотреть перее и в зависимости от этого какие-то настройки либо использовать либо исключать делается Это примерно таким образом то есть используем бун флажок смотрим если он True то передаём какие-то опции если он ЛС то передаём или undef или false или какое-то другое значение в зависимости от того что мы настраиваем то есть если мо будет передан как Production Вот и Tool у на будут со значением инно у на проставляется и в случае если мы запускаем в режиме де сервера у нас соответственно этот флажок будет True и де сервер будет работать ну можно ещё для подстраховки вот здесь вот ф передать значение development чтобы точно быть уверенным что у нас нужное значение там передаётся так Ну и на этом этапе мы проделали уже достаточно большую работу Я предлагаю подвести итоги во-первых мы сделали config в котором указали мод это либо Production либо develop также мы указали entry Point это путь до входного файла до точки входа в наше приложение Настройки output задают то куда происходит у нас сборка также для файне можно использовать шаблоны Чтобы избежать проблем с каширования в браузере далее мы использовали плагины самый важный - это HTML webpack плагин который подставляет скрипты в нашу HTML скрипты которые получаются в результате сборки ссылку на сам bandle также использовали прогрес плагин который показывает в процентах Нако сколько прошла сборка кстати вот я уже упоминал что на больших проектах он может очень сильно замедлять сборку и поэтому можно или его оставить только для прода или только для Дева в зависимости от того как вы вообще его используете или вообще подумать над тем нужен он вам или не нужен То есть можно исключать вот таким вот образом плагины тоже из массива здесь вот кстати можно тоже так сделать Для более короткой записи единственный момент что если мы сейчас попробуем сделать сборку то скорее всего она отвалится Давайте даже попробуем запустить кстати нет сборка прошла успешно но это из-за того что мы в деф режиме запустили Давайте в прот попробуем запустить чтобы у нас это условие в массиве не сработало Ну и Да он говорит что у нас некорректное что-то попадает в массив плагинов Здесь нам просто по Булин флешку необходимо отфильтровать То есть все Фолс значения всякие афд налы Мы просто из этого массива убираем так и сейчас он ругается ещё на Def сервер Да здесь видимо fse нельзя передавать здесь скорее всего надо передать undef всё-таки Давайте вот здесь сделаем вот так как было изначально Вот и теперь оно должно запуститься Да сейчас сборка прошла успешно Так мы остановились на плагинах разобрали их Давайте дальше подводить итоги также мы поговорили про концепцию лоров которые как-то обрабатывают файлы с разными расширениями указали лнг расширений как раз файлов с исходным кодом настроили Def Tool карты с исходным кодом и настроили де сервер который можно открыть по заданному порту запустить вернее не открыть уже достаточно много мы сделали всего но пока что это всё равно так абстрактно предлагаю переходить уже к конкретным примерам к конкретным реализация и установим react Обратите внимание что react и react dom мы устанавливаем уже как Production зависимости а типы к ним устанавливаем как Def зависимости после установки Заходим в package Son видим что у нас появилось две прокш зависимости и две де зависимости дополнительные вот здесь сразу хочется сделать такое замечание что если бы мы не использовали typescript который умеет работать с jsx то нам понадобилось бы настроить bable Loader то есть Test Loader он из коробки по умолчанию jsx который мы пишем в реакте умеет обрабатывать Если б мы использовали обычный JS то нам бы пришлось подключать bable и настраивать его для того чтобы обрабатывать jsx но мы это в дальнейшем потом всё равно сделаем для примера мы с Лора переедем на B Loader опять же для расширения кругозора Итак поскольку мы будем jsx меняем расширение ИК TS файла На ИК tsx и также не забываем поменять его в entry поинте также сразу Давайте создадим по классике папочку с компонентами и внутри корневой компонент apt SX с помощью спета развернут единственно экспорт сделаю именованы они дефолтные Ну и Давайте здесь напишем классический Hello world На этом этапе видео Я немного ускорю здесь будет в принципе стандартный код любого к приложения отлично корневой компонент мы отрендерить приложение запустим пишем Script npm RST идёт сборка и сборка падает с ошибкой Как видите он требует импорта КТА Давайте в ик tsx файл импорт реакта добавим и убедимся в том что сборка пройдёт успешно запускаем Да видим что сборка прошла успешно в браузере если откроем по тысячном порту приложения Ну видим наш Hello world Давайте чтобы убедиться что у нас прям полноценно всё работает быстренько какой-нибудь счётчик напишем чтобы какого-нибудь интерактива добавить опять же коро счётчик я не буду Просто на этом этапе видео ускорю счётчик готов нажимаем Ctrl S или Command S видим что Def сервер приложение обновил кнопка отлично работает в логах ничего лишнего нет но есть один момент начиная с семнадцатой версии импорт реакта указывать не требуется Однако если мы его удаляем по какой-то причине сборка у нас начинает падать с ошибкой при том что react у нас установлен в восемнадцатой версии Вот 18.2 давайте Вот это сообщение с ошибкой скопирую прямо в таком виде как есть в саве мы посмотрим какое решение нам предлагает интернет и на Stack Overflow нам предлагают в TS конфиги добавить вот такое вот поле jsx со значением react jsx у нас оно уже есть но с не с тем значением Давайте заменим и попробуем перезапустить сборку npm Run Start и сейчас проект собрался успешно без явного импорта реакта Теперь его вообще в компонентах импортировать нет необходимости отлично с этим разобрались теперь переходим к стилизации наших компонентов создаём первый CSS Файлик Давайте просто для примера покрасим например кнопку в какой-нибудь красный просто чтобы изменения сразу были заметны Ну и попробуем Файлик со о силами сюда импортировать App CSS Ну и как видите сразу же сборка отваливается и сообщает нам о том что не хватает лоудейли из неё scss Ну и как обычно открываем браузер пишем wep CSS открываем первую же ссылку и смотрим Что он нам здесь рекомендует Ну в первую очередь соответственно необходимо установить сам scss Loader как дев зависимость Ну и дальше уже по известной нам схеме необходимо добавить лодер который будет CSS файлы обрабатывать Как видите здесь сначала идёт Style Loader Затем идёт CSS Loader Давайте скопирую откроем наш webpack config находим массив с правилами и вставляем сюда лодер Обратите внимание что в можно передать как Одиночный лодер так и массив этих лоде при этом как я говорил порядок важен То есть если мы добавим ещё какой-то лодер который будет обрабатывать файлы опять же это может быть B Loader svc Load или любой другой лодер то порядок будет иметь значение потому что на выходе мы получаем уже обработанные файлы это всегда надо иметь в виду так с этим мы разобрались двигаемся дальше scss loer мы установили Но в этой документации конкретно нам не предложили установить Style Loader давайте тоже посмотрим что он из себя представляет откроем Style Loader да В первую очередь Нам его также установить и после установки Давайте попробуем запустить сборку на этот раз сборка прошла успешно если мы откроем браузер то Увидим что стили у нас успешно применили кнопка стала красной чисто ради интереса Давайте ещё какое-нибудь свойство добавим например Дин сдела 20 пикселей Да как видите кнопка тоже изменила в обновляется Watch режим работает отлично с обычным CSS вопрос порешали как видите ничего сложного Давайте теперь научимся обрабатывать scss файлы Это для любителей при процессоров опять же видим что за resol Вить файл такой он не может потому что мы добавляли регуляр только на CSS файлы на scss файлы у нас ничего нет ну и опять же открываем документацию опять же уверен найдутся люди которые скажут что я документацию пересказывают работают начинающие для тех кого это тёмный лес Те кто не понимают вообще что такое V пак для чего он нужен для них хотя бы будет понятно Где искать откуда я эту информацию у беру и так далее уже по известной схеме в режиме Def устанавливаем SAS и сам SAS Loader который мы будем к паку уже подключать и пока установка зависимости у нас идёт Давайте заглянем в документацию и Как видите здесь по сути ничего не меняется меняется только регулярное выражение и добавляется ещё один лодер в этот массив Как видите Здесь даже комментариями подписано то что было на вот этом Вот слайде то есть каждый лодер последовательно отвечает за определённый этап преобразований за определённый этап компиляции Давайте Вот это прям целиком всё скопирую откроем config и Весь вот этот вот лодер целиком заменим npm RST немного ждём Ну и видим что приложение у нас собралось успешно то есть теперь мы умеем обрабатывать scss файлы тоже Давайте ещё чтобы точно убедиться проверим какие-нибудь вложенные селекторы можем вот так вот например Просто ну давайте какой-нибудь Спан обработаем Спан внутри кнопки будет иметь красный цвет шрифта ифн сайз например 50 пикселей Давайте внутрь кнопки добавим Спан зде добавим какой-нибудь Случайный любой текст всё работает нормально Мы в этом Просто убедились давайте лишнее удалим и двигаемся дальше то как работает всё это в Watch режиме в принципе понятно Давайте попробуем сделать реальную сборку статики и посмотрим как CSS будет выглядеть там давайте соберём в де режиме чтобы у нас не было минификация чтобы код был Чита более-менее читаемым скажем так потому что он там тоже тяжело читается Вот и Давайте какой-нибудь из этих стилей Ну например background Red просто поиском попробуем здесь найти вот Как видите Да оно прямо вот такой вот строкой встраивается в JS файл и опять же если мы посмотрим на все вот эти этапы компиляции Мы в итоге видим что у нас из scss идёт преобразование в JS string То есть как раз вот в эти строки которые добавляются в эти JavaScript файлы Давайте ещё на всякий случай сравним с тем как это будет выглядеть в проде делаем прокш сборку открываем JS File Ну и поиском Ctrl F или Command F тоже убрав все лишние пробелы Да вот здесь вот в начале пробел Так это что-то не то ищем поиском Ну да вот background R Ping 20 пикселей это Всё конечно хорошо но хотелось бы вынести CSS всё-таки в отдельные файлы CSS файлы потому что браузер CSS файлы обрабатывает не так как JS файлы Именно они предназначены для CSS для наших стилей И для этого существует плагин который называется Min CSS extract устанавливаем его 2.7.6 возвращаемся к документацию Смотрим как его использовать во-первых необходимо добавить плагин это мы делать уже умеем возвращаемся к конфигурировать ещё Да вот Автоимпорт сработал нормально возвращаемся в документацию и также видим что помимо всего Нам необходимо добавить вместо стай Лора вот этот мини CSS EX PL Loader То есть это р который идт сразу в комплекте с плагином Давайте сразу его добавим вместо лора и Посмотрим как будет работать сборка Давайте прокш сборку соберём неважно можно было в принципе и сборку сделать и видим в папке Build вот такой вот Main CSS файл финны в котором находится как раз ве CSS который мы писали если мы заглянем в икс HTML файлик то мы увидим здесь вот такую вот ссылочку на этот CSS файл причём в сам плагин Также можно передавать опции то как будут называться файлы то по какому пути они будут сохраняться опять же я вот тут заранее подготовил уже шаблоны давайте я их просто вставлю и Давайте покажу где я это всё взял вот здесь если ниже пролистать есть опиш того какие опции принимает сам плагин и какие значения они могут принимать в данном случае мы сохраняем основной файл и все чанки мы сохраняем в папку CSS с вот с таким же названием в принципе как и JS файл то есть берём хш от контента делаем сборку видим что у нас появилась папка CSS и внутри как раз лежит Мейн Файлик Как видите ничего сложного нет всё делается максимально просто используем нужные плагины конфигурируется единственное Я думаю что в Def режиме нам использование Mini CSS extract плагина не требует в де режиме мы вполне можем обойтись лором создавать отдельные файлики нет необходимости поэтому По условию в Production режиме мы используем Mini CSS extract plugin в обратном случае используем Style Loader делаем де сборку видим что у нас CSS файлов нет пробуем сделать прок сборку так почему-то сборка упала с ошибкой Так вы забыли добавить Min CSS extract plin да На самом деле я вот здесь условие неправильное сделал здесь получается когда продакшн сборка мы используем то есть здесь отрицание нужно было добавить Да и Давайте запустим ещё раз npm Run Build про вообще можно чтобы не путаться прямо отдельную даже константу сделать из про просто чтобы семантически более понятно Была она может быть как отрицанием de так и сравнением с Production тут в принципе как удобно Ну и здесь используем уже ИП Ну да как видите сборка прошла и на этом этапе Я предлагаю немного притормозить и посмотреть на то что у нас получилось на самом деле конфиг потихоньку разрастается Хотя Мы только начали но он уже много что у нас умеет обрабатывать TS CSS конфигурируется под какие-то наши настройки используются Source Map тузы и так далее но как видите конфиг становится всё менее и менее читаемым удерживать его через какое-то время будет становиться всё сложнее и сложнее и по-хорошему его необходимо декомпозировать также как вы декомпозировать любой бизнеском отдельную папочку config внутри создадим отдельную папку Build Ну то есть вот в папке config может быть много разных конфигов storybook жест какие-то тестовые среды и так далее а папка Build будет отвечать именно за сборку отсюда мы экспортируем функцию которая будет называться buildpack и будет на некоторые опции эти опции мы опишем чуть позже укажем также что эта функция у нас будет возвращать configuration сразу tpt начинает ругаться то что мы ничего не вернули Ну и Давайте вот этот весь объект целиком прямо отсюда скопирую делаем вставляем туда этот объект и саму функцию сразу используем в файле webpack config.sys и вот эту вот строчку с импортом типа для конфигурации де сервера добавляем тоже сюда чтобы у нас всё корректно здесь обрабатывала Ну и Давайте сразу это дело всё декомпозировать как Изначально и договаривались создаём несколько файлов Build loaders это файл в котором мы будем конфигурировать Лоры как нетрудно догадаться по названию Build plugins следующий фай опять же вот когда вот это ВС разбито на какието такие у которой каждая зона ответственности какая-то своя это всё легче поддерживать легче масштабировать легче как-то вносить изменения и так далее Особенно это станет заметно когда мы будем кодить в мореп будем говорить про Mod Federation Итак что мы делаем по сути у нас эта функция каждая из этих функций возвращает просто какой-то участок конфигурации конкретно функция с которой мы сейчас работаем возвращает Def сервер вот этот вот импорт добавляем сюда и сразу же можно указать что эта функция возвращает нам Def Server configuration теперь вот здесь мы можем эту функцию просто вызвать и нужный участок конфигурации она нам уже вернёт сейчас у нас тут недостающие переменные используются из Def и про но мы их чуть позже перенесём пока Давайте всё это дело декомпозировать не вывозить отсюда мы его можем получить вот таким вот образом копируем название Вот это module Option Ну во-первых давайте функцию отсюда экспортируем называем по аналогии Build loaders и здесь указываем module options импортируем их из вебпак и через квадратные скобки вот так достаём оттуда Rules это как раз будет массив наших лоде и всё что у нас здесь есть внутри прямо целиком вот так вот берём отсюда вырезаем и сюда вставляем копируем название и здесь эту функцию просто вызываем вот таким вот образом Как видите typ не ругается потому что все типы он распознаёт тоже самое с плагинами смотрим Что здесь за тип здесь Тип configuration и внутри как раз лежит тип plugins Делаем всё абсолютно по аналогии ничего не придумываем достаём вот так через квадратные скобки plin Ну и не забываем сделать импорт типа config из возвращаемся в Build webpack копируем все плагины которые у нас есть вместе с т buan и возвращаем их из этой функции сейчас мы сюда ещё вернёмся и по рефакторинг настройки разрастаться тоже импортируем configuration и достаём поле resolve Ну прям целиком этот объект отсюда вырезаем используем новую функцию которую мы сделали и отсюда возвращаем этот объект так отлично так отлично основное Всё декомпозировать теперь давайте разберёмся с опциями которые будет принимать эта функция то есть мы хотим конфигурировать вот эту сборку вебпак откуда-то Извне чтобы для тех же микрофронтенд мы могли эту функцию переиспользовать не писать каждый раз сборку с нуля А переиспользовать уже существующее решение с какими-то разными входными аргументами во-первых на вход мы здесь ожидаем порт также у нас на вход будет прилетать объект с путями до HTML до папки паб до папки с исходным кодом В общем все пути которые у нас используются они опять же в разных приложениях могут быть разными поэтому хардко их вот прямо вот здесь вот смысла никакого не имеет тем более сейчас пути который используются здесь написаны относительно текущей папки в которой лежит вот эта функция Build webpack А изначально мы их писали относительно файла вы Pack config то есть эти пути они сейчас по сути и неактуальны Ну давайте пока что сделаем интерфейс который будет описывать поля которые мы на вход ожидаем во-первых это путь до entry поинта до ИК tsx файла путь до HTML и путь до аутпут то куда будет у нас сборка происходить также на вход мы ожидаем мод мод можно вот отсюда перенести единственно экспорт ещё добавим Ну и Давайте назовём Build Mode чтобы более понятно было вообще что такое Так и что мы ожидаем на вход ещё Ну в принципе пока что всё чуть позже мы это будем всё расширять Теперь давайте эти опции аргументом везде укажем из этих опций мы можем достать теперь порт копируем это вставляем вот сюда в сразу же можем здесь же добавить вот эти вот переменные из Def и про опять же поскольку они вычисляются из поля мод их можно в каждой отдельной функции вот так заново выводить чтобы не прокиды аргументом везде их здесь можно ещё пойти чуть дальше и добавить ещё определённой смысловой нагрузки определённой семантики и каждый отдельный лодер вынести в отдельную константу чтобы из названий было Хоть как-то понятно что они делают соответственно у нас будет scss Loader и будет TS Loader и здесь их в массив просто понятным языком перечисляем опять же такая структура плоская можно сразу увидеть в каком порядке лодер выполняются так отлично двигаемся дальше копируем Вот эту строчку то же самое добавляем в Build plugins тоже здесь из и про выводим копируем отсюда в принципе как я и сказал можно было их вот здесь добавить чтобы один раз прокинуть и всё но это особого смысла не имеет потому что они выводятся из мода а мод мы передаём и так здесь можно деструктуризация большую свалку со всякими и de и про можно сразу на две части это всё декомпозировать Изначально создадим массив с плагинами даже можно вот этот вот тип скопировать тя я вот эту строчку потеряю да давайте вот так вот её вставим скопирую и какие-то общие плагины например вот HTML плагин Который изначально и для де сборки и для прод сборки его можно сразу в этот массив добавить А теперь плагины которые специфичны для Дева или специфичны только для прода мы добавляем через обычный пуш в соответствующем блоке If так код У нас тоже семантически более понятный сразу разделённый на логические куски всё это у нас не скатывается вот в такую вот свалку по итогу и можно от вот этого фильтра избавиться Ну и в конце мы возвращаем просто этот массив плагинов если их будет много здесь код будет намного читаемые и намного понятнее и человек который первый раз с этим всем работает быстрее сможет разобраться так двигаемся дальше для Build loaders мы добавили для Build resolvers также добавляем опции Правда пока что они здесь не используются но в дальнейшем это может нам пригодиться теперь работаем с главным файлом buildpack Вот это sdf нам также понадобится здесь вывести выводим его опять же Уточняю что эта переменная нужна просто для удобства чтобы делать Вот это сравнение Mode равняется development каждый раз можно вот так вот деструктуризация здесь а заменяем на те пути которые мы принимаем в опциях Pass entry Pass output и ещё в плагин мы да вот здесь вот телей передаём HTML template па точка HTML единственное структурирует здесь вот ещё так вроде ничего не забыли кажется что путь у нас использовался только три раза не припоминаю чтобы мы где-то его ещё использовали Давайте личний импорты ещё так Ну и отлично Давайте теперь это всё сконфигурировать микро фронты чтобы приложение запускать на разных портах всё увидите И вот эта декомпозиция новыми красками заиграет Это скорее для тех говорю Кто сомневается что эта декомпозиция нужна потому что я уверен такие будут так здесь я чуть-чуть видео ускорю заполняем пути до атпу до entry поинта и до HTML файла это мы уже делали тут в принципе комментировать особо нечего и также чтобы ty Script у нас не ругался тип Mode заменяем на Build Mode лишние импорты также удаляем и пути передаём в опции конфигурации Отлично вот такой вот лаконичный конфиг у нас получился по сути того что мы сделали это только указали пути до соответствующих файлах опять же в каждом проекте они могут находиться в разных местах Поэтому эти пути лучше передавать из вне Теперь всё лежит по своим местам отдельно лоде у каждого из которых есть имя отдельно резол Веры отдельно сборка вебпак которая конфигурируется на уровне опций которые опять же от проекта к проекту могут меняться и Давайте убедимся в том что всё это работает запускаем Script npm R и что-то где-то у на сломалась не получается завить src идек TS Да я видимо там расширение неправильно указал индекс Файлик у нас с расширением tsx Да добавляем X на конце и делаем сборку ещё раз и на этот раз сборка проходит успешно видим У нас есть Папочка CSS видим Main bandle вроде бы проблем никаких нет Давайте попробуем ещё запустить в режиме чтобы убедиться что там у нас ничего немало Да всё запустило всё хорошо в принципе мы особо конфиг не меняли только его немного декомпозировать порезали на части следующим этапом поговорим про изоляцию стилей В чём собственно говоря проблема у нас есть модальное окно У нас есть выпадающий список и там и там есть состояние когда компонент открыт открыто модальное окно открыт выпадающий список и там и там селектор сам класс который накладывает какие-то стили называется Open но добавляют Они разные стили в одном случае у нас меняется прозрачность в другом случае у нас меняется размер опять же Это просто вымышленный код Главное понимать суть что код разный но за счёт того что селекторы у нас одинаковые стили естественно будут друг с другом конфликтовать будут возникать коллизии причём в большом проекте но очевидно что таких коллизий может быть миллиард потому что для названия классов обычно используют Ну какие-то понятные всем названия Существует множество различных решений этой проблемы Но Одно из самых популярных - это БМ методология блок элемент модификатор то есть блок - это у нас модальное окно элемент контент и модификатор Open То есть то что вот эта контентная часть у нас открыта за счёт этого практически гарантируется изоляция стилей но не на 100% потому что опять же при каких-то условиях нейминга в больших проектах всё-таки вот эти вот селекторы даже При таком нейминг они могут совпадать компонентов много элементов много и соответственно какие-то коллизии всё равно будут ну и плюс ко всему названия классов раздуваются то есть вместо четырёх символов Open нам приходится писать модел два нижних подчёркивания контент подчёркивание Open то есть в несколько раз просто увеличивается название селектора это и читаемость кода ухудшает ну и плюс Весь вот этот вот текстовый файл весь CSS вот с этим огромным количеством селекторов нам приходится по сети гонять нет нет нет но тоже на скорости это чуть-чуть будет сказываться хоть и текстовые данные хорошо сжимаются но всё же ну и соответственно существует другой способ как уже не трудно по моим рассуждениям догадаться он называется CSS modules более современное решение мы пишем классы в таком виде в котором нам удобно они могут дублировать хоть миллиард раз Главное чтобы они были в разных файлах по итогу всё это мы прогоняем через bandler wep вид или любой другой сборщик правильно настроенный и на выходе вот те классы Open превращаются у нас в набор Вот таких вот символов То есть это хэши аналогичные таким таким же который мы указывали в файне атпу при этом опять же название этого хэша берётся по содержимому если у нас будет два класса Open в разных файлах с одинаковым абсолютно кодом внутри с одинаковыми стилями то скорее всего они получат одинаковый нейминг и опять же ни на что это не повлияет то есть коллизии здесь также исключены причём у тех кто про эту технологию раньше не слышал скорее всего возникнет вопрос А как это всё дебажить вы открываете тулз в браузере хотите понять какой у вас класс Какие стили вам нужно поменять но при этом у вас вместо человека читаемого какого-то текста набор символов и здесь есть решение для деф режима можно делать вполне читаемые понятные уникальные какие-то названия селекторов например брать путь до файла э в котором этот код например написан а вконец подставлять сам се к таким образом он также будет уникальный и опять же это всё будет только на этапе разработки А в прок будете отправлять вот эти вот хэши которые никому читать в принципе в продакшене и не надо Ну и давайте сейчас на практике это всё посмотрим Как реализовать Как использовать откроем наш компонент и импорт мы делаем вот таким вот образом импортируем классы From CSS фа теперь для того чтобы этот класс на что-то повесить например на кнопку мся непосредственно к этому объекту который импортировались у нас не класс а просто селектор по кнопке Да вот теперь среда разработки увидела Баттон единственное здесь хочется остановиться компьютер на котором я обычно веду запись код я здесь пишу редко и у меня в вебшторме что-то случилось с настройками тайп скрипта и заметил я это уже в момент записи Останавливаться не стал здесь Прошу обратить внимание что именно в среде разработки слетел тайпскрипт то есть ориентироваться на ошибки тайп скрипта стоит именно при сборке а не на те ошибки которые подсказывает вам среда разработки то есть вот у меня эти настройки слетели из-за этого какие-то ошибки могут не подсказывать или подсказывать неправильно ориентироваться в нашем случай стоит именно на то что выдаёт нам сборка то есть вот сейчас по идее На вот эту конструкцию. Button typescript должен был ругнулся модуль с расширением S CSS Не распознан потому что мы нигде не объявили что это вообще у нас такое ошибку мы сейчас поправим пока Давайте сам файл переименую в module.css обычно так принято называть файлы с CSS модулями вот здесь тоже поправим название Ну и опять же не будем ничего придумывать какие-то решения самостоятельно пытаться нагороди открываем браузер в поисковике пишем CSS Mod typescript Вот здесь Да такая же проблема здесь есть несколько различных вариантов решения можно вот так вот модуль по-простому декларировать Но если пролистать чуть ниже Я уже на самом деле эту ссылочку открывал когда готовился к записи данного ролика здесь есть вот такое вот решение которая автоматически будет вам ещё и подсказывать какие классы внутри файла находятся Для этого нам необходимо создать файл с декларации типов назовём его например Global DTS создаём его в корне SR ф и сюда вот это вставляем единственное вот здесь я бы добавил расширение Mod scss потому что у нас scss файлы Вот и теперь typescript должен понимать что это у нас за модуль с таким расширением и ошибки быть не должно Ну и как видите Да сборка прошла успешно стили у нас работают при этом чтобы сами CSS модули впаке начали работать никаких дополнительных действий производить не надо Но единственное Если вы хотите как-то сборку кастомизировать под себя всё-таки настроить ведётся настройка происходит в CSS Лоре здесь есть вот прямо отдельный раздел с modules настройка этих модулей здесь куча всяких опций которые вы можете передать вот часть из них мы сейчас будем использовать А пока Давайте посмотрим вообще как это всё работает открываем инспектор наводим на кнопку и видим что вместо класса Button У нас вот такой вот набор символов Как раз за счёт генерации вот этих вот символов и происходит изоляция стилей Давайте в этот Файлик добавим ещё какой-нибудь селектор Ну пусть будет будет например value сделаем здесь н сайз 100 пикселей например опять же это не столь важно Ну и добавим на вот этот вот заголовок Как видите кстати вот за счёт того что мы сделали вот эту декларацию typescript сразу понимает какие классы у нас находятся внутри вот этого CSS файла Ну и смотрим теперь на заголовок видим да что для него тоже был сгенерирован уникальный вот этот вот хэш Ну и теперь давайте научимся управлять тем как этот хэш должен выглядеть и опять же сделаем отличие в продакшены де в сборке во-первых в документации нам говорят добавить вот такие вот опции в CSS Loader Давайте прямо целиком скопирую и вот здесь вот ставим вот этот вот тест можно исключить потому что у нас он выше уровнем уже и так стоит и ловит нужные файлы в принципе можно даже вынести в отдельную константу Ну чтобы семантически опять более понятно И наглядно это всё выглядело и вот сюда её вставляем Теперь давайте вернёмся к докумен посмотрим какие опции мы можем передать чтобы управлять названием Здесь много всяких настроек опять же про каждую можно почитать если вам интересно но нас сейчас интересует вот это Local ent name именно эта настройка отвечает за формирование названия класса здесь мы можем сделать такую конструкцию если у нас режим Def то мы будем использовать один вид селектора если прок соответственно другой здесь используются точно такие шаб можно взять также хэш например bas 64 и также можно указать сколько символов Вы хотите взять обычно во - это такая золотая середина Чтобы избежать коллизий опять же я это всё не придумываю Давайте прямо в документации Найдём место в котором показаны примеры этих шаблонов поиском поищем по странице вот Обратите внимание здесь прямо такой большой составной селектор сначала берётся путь до файла потом название потом там какой-то хэш прямо огромный такой селектор получается вот такой мы можем использовать например в деве А лаконичный с шом в проде Ну давайте вот этот кусочек прямо скопирую и его как раз будем использовать в де сборке единственно вот здесь вот скобочку закроем а хэш будем использовать в проде Ну давайте Теперь попробуем сделать два разных вида сборки делаем Build в режиме Def так и у нас сборка отваливается с ошибкой на самом деле вот здесь вот когда вы уже делаете какую-то конфигурацию модулей нужно передавать не просто бун значения А вот эти вот все настройки внутрь объекта Давайте доку откроем Да вот как Видите options Там modules и внутри как раз передаются настройки уже не туда добавил опцию делаем сборку ещё раз сборка прошла успешно Да единственное вот сейчас осознал что у нас Min CSS extract плагина нету в де сборке Поэтому вот так мы увидеть не можем нам придётся потом запустить сам проект npm R в инспекторе уже посмотреть давайте пока сделаем прод сборку откроем CSS Файлик Ну и да Как видите здесь были сгенерирован вот такие вот селекторы для каждого класса так Ну теперь давайте запустим сам проект npm RST и посмотрим как в деви он на Гене эти селекторы открываем инспектор Ну и здесь можно заметить вот такие вот уже человекочитаемый вы без проблем найдёте где эти стили расположены в каком файле и быстро сможете найти то есть в режиме Def никаких затруднений у вас не будет здесь опять же с нейминга можно поиграться и сделать так как вам будет удобно там много разных шаблонов можете использовать такие Какие подходят конкретно под вашу ситуацию и на этом CSS модулями мы заканчиваем и переходим к роутинг этих чанков как как вообще формируется итоговый бандл особенности в Def разработке потому что мы разрабатываем Single page Application там тоже есть свои нюансы В общем приступаем в первую очередь для роутинг для навигации установим react router dom думаю все так или иначе с этой библиотекой работали поэтому тут подробно не останавливаюсь не забываем установить нужную версию устанавливаем как Def зависимость react router dom очень часто обновляется поэтому тут особенно рекомендую поставить версию из ролика опять же на освоение материала это никак не повлияет но каких-то трудностей поможет вам избежать так отлично react дом установился Давайте теперь откроем документацию и Скопируй примеры использования открываем официальную доку листаем чуть ниже тут как раз Как установить Ну и вот этот кусок с созданием самого роутера прямо копируем импортируем Create браузер rter из react router до и теперь нам необходимо в роутер [музыка] провайдер обернуть этот роутер единственно вот здесь вместо вот этих дивов используем как раз наш корневой компонент Up Так ну и у нас будут ещё под роуты для отдельных страниц чуть позже отдельные роуты ближе к концу ролика превратятся у нас прямо в отдельные микрофронтенды с панелью и с магазином добавляем один Ro для about страницы и добавляем второй для магазина делаем npm RST приложение у нас открылось но если мы сейчас попробуем в строке запроса ввести about то мы увидим что по такому пути у нас никакого файла браузер Не запрашивает То есть если мы посмотрим прямо в Нетворк то мы увидим что он у нас запрашивает вот по такому адресу а роутинг у нас Single page Application клиентский То есть он за счёт жава скрипта происходит а не за счёт подгрузки вот этого HTML файла Ну и чтобы это заработало опять же одну строчку всего лишь добавить надо в де сервере надо Разрешить использование I history таким вот образом Давайте даже сейчас откроем доку почитаем про эту опцию вот Когда вы используете history IP нанана Вам необходимо установить это значение в True А мы как раз в Single page Application у нас навигация с помощью JS происходит Как раз за счёт history IP делаем сборку ещё раз запускаем приложение опять же вводим в строке запроса с about Как видите ошибку мы не получили но и саму страницу about Мы тоже не получили потому что забыли добавить то есть пока что приложение не понимает куда нам вот этот дочерний на строить в react router dom вот такой вот компонент есть Outlet Ну да И как Видите вот он снизу about страницу отрисовать отрисовывать Ну это так работает react router dom то же самое с Shop то есть страницы у нас открываются Нормально ничего не теряется давайте сделаем ещё ссылочки здесь about с about дублируем и делаем здесь SH Ну как видите Да по ссылочка без проблем переходит соответствующий контент рендерится вот здесь единственное Хочется ещё такую оговорку сделать вот эта опция она работает только для де сервера Если вы когда будете деплоить приложение статику будете раздавать через какой-нибудь то там необходимо будет также проксирование сейчас ссылочка если что на него всплывёт если не забуду добавить если забуду ищите на канале Так теперь давайте посмотрим как будут собираться у нас Lazy компоненты создаём папочку pages и наши страницы вынесем в отдельные компоненты рнм здесь компонент напишем опять же Давайте заголовок и рядышком создадим Файлик about Lazy tsx экспортируем Lazy компонент здесь используем классический react L здесь опять же я подробно не Поясняю потому что ну подразумевается что если вы смотрите этот ролик то скорее всего с ретом так или иначе вы знакомы Если нет то у меня на канале есть фундаментальный курс где я про все эти моменты подробно рассказываю и создаём такой же ленивый компонент для страницы Shop тоже создаём Lazy компонент отдельный Файлик под Lazy но заменяем здесь название Lazy about на Lazy Shop и правим ипор также для удобства можно ещё создать индекс файл из которого сделать реэкспорт Можно даже поменять название просто на SH чтобы снаружи мы как бы особо не думали о том ленивый он не ленивый ну здесь опять же это такое вкусовщина можно и так можно и так можно вообще этот индекс T файл не создавать Это здесь особого значения не имеет Lazy Shop Lazy about Shop Можно экспортировать из как раз индекс файла который мы сделали под капотом там как раз у нас ленивый компонент будет Так ну отлично компоненты мы сделали в роутинг мы их указали Остаётся только их завернуть в suspens чтобы какую-то индикацию загрузки показывать саспенс импортируем из реакта вот обращаю на это внимание Так что-то он не импортировала так ну ладно давайте руками импортируем webstorm Я как уже говорил на этом ноутбуке он у меня нерабочий использую его только для записи видео использую не часто он здесь устаревший не обновлённый как-то кося работает немного надо будет заняться его обновлением но опять же на сам ролик по в паку это никак не сказывается поэтому двигаемся дальше на доле секунды на самом деле можно уже заметить как работает саспенс Можно даже троттлинг включить чтобы чуть медленней всё подгружать страницу Да видим на какое-то время появляется индикация загрузки и только потом отрисовывать Нет подгружается это всё за доле секунды и вот даже можно заметить как эти ленивые чанки у нас подгружаются в Нетворк вы всегда можете видеть в какой момент и какие чанки у вас загружаются Так давайте Теперь попробуем собрать сборку давайте сделаем продо сборку и посмотрим что у нас на выходе будет Да можно заметить Сразу Main bandle и два чанка как раз один чанк с about страницей другой чанк сшоп страницей для чанков кстати можно также шаблоны задать для названия чанков Если Вам это требуется для чего вообще вот так вот лениво какие-то чанки нужно подгружать Давайте посмотрим сколько они весят Ну у нас там кода практически нет если мы зайдём в свойства Увидим что вес меньше килобайта 2118 байт Ну потому что там компоненты прямо пустые но Давайте попробуем эти компоненты каким-то контентом наполнить Ну например развернёт Здесь просто какой-то текст в большом количестве Ну хотя бы вот так даже можно несколько раз продублировать представим что у нас здесь просто много кода на 200 строк Ну в принципе то же самое сделаем во втором чанке Угу думаю этого хватит давайте сделаем сборку ещё раз И откроем папку с этими чанкам и уже можно заметить что один чанк У нас весит 16 КБ второй чанк весит 26 КБ при этом сейчас важно обратить внимание главный бандл у нас весит 188 КБ теперь Давайте попробуем вместо ленивых страниц вот здесь вот использовать обычные Вот это закомментировать дефолтный экспорт Да вот так вот делаем сборку Ещё раз чтобы у нас один Main bandle был без всяких чанков ждём Ну и да сразу можно заметить что у нас Main bandle стал весить 225 то есть был 188 стал весить 225 это у нас всего две страницы с текстом без каких-то вложенных компонентов огромного количества бизнес логики и так далее Суть в том что вот размер вот этого бандла влияет на первоначальную скорость загрузки при этом пользователь например хочет зайти в магазин а мы подгружаются пока у него загрузится вот этот Main бандл он может весить очень много а Метрика вот эта вот по первой загрузке по первому отображению контента Она одна из самых важных потому что большинство пользователей с сайта выходят если он не загружается там за 3-5 секунд поэтому вот какие-то части вашего приложения Вы можете подгружать лениво если они не требуются пользователю Здесь и сейчас то есть если их можно подгрузить отложено в виде такого ленивого чанка то лучше это делать отложено ну и исходя из того что мы сейчас узнали возникает вполне резонный вопрос как вообще за вот этими чанка бандла следить как анализировать размер Как смотреть сколько весят библиотеки Какой процент от размера бандла Они занимают и так далее на самом деле есть инструмен помогает за этим всем следить Называется он bule инструмент достаточно простой в использовании Ну и Давайте его сразу установим устанавливаем как зависимость Ну и Давайте посмотрим как его использовать во-первых он представлен просто в виде плагина этот плагин просто надо добавить в список плагинов то есть ничего здесь пря настраивать отде опции в деф режиме на самом деле особого смысла не имеет бандл анализировать потому что он там не минимизированы там куча лишнего поэтому использовать его можно в прот режиме где реально та картина с которой работает пользователь так видимо Чтобы ещё тайпскрипт нормально этот бандл аналайзер подхватил типы необходимо установить Давайте их установим тоже вот да он подхватил импорт Да вот Bundle Analyzer из webpack Bundle Analyzer Ну и теперь Давайте попробуем сделать продакшн сборку npm Run Build prod и автоматически в браузере у вас откроется вот такое вот окно где можно посмотреть какие у вас есть чанки какой бандл и какую долю из этого занимает та или иная библиотека вот как видите НОД модули здесь в отдельном таком квадратике src ваш Исходный код в другом квадратике и вот здесь вот сбоку на самом деле ещё можно посмотреть на чанки как они сжато форте как они в обычном формате выглядят но у нас сейчас всего один бандл Давайте вот здесь вот ленивые сейчас компоненты вернём чтобы понагнулась это tsx и Shop tsx два отдельных бандла можно посмотреть на их размер и вот здесь в списке они тоже отображаются 25 КБ 15Б и почти 180 даже 187 и2 это Main bandle у нас при этом там вот сверху можно переключать посмотреть как в сжатом ВП формате это будет выглядеть и так далее ну и чтобы каждый раз этот аналайзер у нас не открывался можно прямо в опции добавить флажок bu аналайзер который ну его сделаем да опциональный который мы будем передавать именно в тот момент когда мы хотим этот аналайзер запустить такое условие делаем и здесь этот аналайзер достаём так странно почему-то он здесь Не подхватывает а Да я его в Build Pass добавил а не в Build options не туда вот да ну и соответственно Теперь мы его как переменную окружения тоже можем здесь принимать и передавать в наш конфиг Ну если мы будем запускать обычную сборку у нас аналайзер открываться не будет если мы запустим сборку с флажком аналайзер то как видите у нас аналайзер открылся и опять же можно вот так вот прямо приближать здесь такой вот грубо говоря Граф строится зависимости и можно посмотреть что Сколько весит и как-то над вашим бандла поработать так с этим разобрались двигаемся дальше сейчас у нас все импорты в проекте указаны с помощью относительных путей это не всегда бывает удобно особенно когда много вложенных всяких директорий подпапок компонентов и уже давно придумали механизмы которые позволяют указывать абсолютные пути и использовать так называемые алиасы сейчас мы о них поговорим Ну как Видите вот здесь вот у нас относительный путь в принципе симпатичный потому что вложенность Небольшая но если появится ещё какая-то вложенная папка то появляется уже вот такой вот путь обычно вложенность бывает ещё больше ну зависит от того какая структура в вашем проекте какой подход вы используете Вот и хотелось бы использовать вот что-то типа такого чтобы был ас который ссылался бы на папку срц и относительно этой папки мы бы путь уже указывали алиасы настраиваются чно легко указываем значок который будет использоваться в качестве Алиса и путь до на который как бы этот АС будет заменяться в нашем случае это папка срц папка в которой находится Исходный код нашего приложения Давайте добавим этот путь в наш Build Pass и укажем путь до папки с т оставляем вот так Если бы вы использовали JavaScript у вас в принципе уже бы всё заработало но если мы попробуем сделать сборку сейчас то скорее всего у нас да всплывут какие-то тайп скриптовые ошибки потому что typescript опять же про вот эти модули ничего не знает ему надо об этом сообщить открываем Test config и добавляем здесь новое свойство выглядит это всё вот таким вот образом единственное вот здесь я уже на этапе монтажа заметил что я опечатался вот здесь вот вместо значка амперсанд которая говорит как бы что вот все участки по этому пути мы заменяем на срц Ну грубо говоря алиас такой через пару минут Я это замечу и поправлю Ну а вас просто предупредил чтобы вы сразу имели в виду вот таким вот образом это всё заполняется но если мы сейчас попробуем сделать сборку скорее всего ничего не изменится Да потому что нам необходимо указать ещё одну опцию ещё одно свойство которое называется Base URL здесь мы указываем путь до базового до базовой директории Да И вот на этом этапе Я заметил что опечатался исправляем здесь на звёздочку и пробуем сделать сборку ещё раз npm Run Build и на этот раз да на этот раз всё зелёное Как видите Даже webstorm начал эти пути подхватывает если зажатым контролом кликнуть то он переходит в соответствующий файл вот здесь можно тоже заменить на alias указываем абсолютные пути Давайте ещё разок проверим что всё работает уже в режиме Def npm RST Ну да всё отлично работает ссылки кликабельные приложение запускается Итак друзья двигаемся дальше сейчас поговорим про ассеты про то как обрабатывать картинки JPEG png Как работать с иконками с свш ками так чтобы это было удобно Ну и Давайте приступим в первую очередь Давайте создадим папку в которой эти ассеты будут у нас находиться Ну так её и назовём assets и я сюда Сейчас сразу вставлю три картинки разного расширения соответственно png JPEG и SG свш у нас иконка Вот такая теперь Давайте попробуем сразу добавить в компонент сделаем какой-нибудь ди здесь отдельный Ну и Давайте пробуем иконку привычным для нас уже образом импортировать Давайте Сначала с png попробуем разобраться Ну и выведем то что у нас получилось в результате импорта внутрь Дива делаем npm Start и вылезает Уже знакомая для нас ошибка то что не хватает лоде который мог бы обработать png файлы опять же Обращаемся к документации webpack asss для ассетов есть специальный Loader который так и называется здесь вот сбоку есть примеры как подгружать изображения шрифты Давайте начнём с изображений копируем прямо пример открываем лоде создаём новую константу так и назовём её asset Loader и туда вставляем то что скопировали Обратите внимание что сейчас asset Loader обрабатывает регулярка у нас png svg JPEG и GIF Ну и не забываем созданный asset Loader добавить в массив так отлично сохраняем здесь порядок не столь важен потому что у нас никакие другие лоде не обрабатывают эти файлы делаем сборку с точки зрения вебпак сборка проходит успешно даже на заднем фоне можно увидеть что проект собрался но ругается typescript опять же на то что он не понимает что за расширение у файла то png нечто похожее мы уже чинили когда использовали scss и Тоже самое по сути Нам необходимо сейчас сделать с png JPEG и другими расширениями файлов делается это вот так укажем JPEG svg пока что не трогаем его мы будем обрабатывать отдельно чуть позже перезапустить сборку npm Start теперь сборка прошла успешно и тайпскрипт не ругается можно увидеть вот такой вот путь до картинки который нам генерить asset Loader Ну и чтобы эта картинка у нас отобразилась воспользуемся Image и туда как раз передадим Аватар png то что мы импортировались ну лучше с маленькой наверное буквы ещё назвать так как это не компонент Ну и вот видим что картинка успешно отрисовать Давайте размер чуть поменяем чтобы она не такой огромной была и также попробуем использовать JPEG продублируйте что у нас теперь две картинки успешно отрисовать Ну можно ещё прямо здесь же попробовать вывести свш но свш мы в Global DTS файле не декларировать поэтому тайпскрипт сейчас руг в любом случае Ну да это в принципе предсказуемо давайте пока что тоже в таком же виде потом чуть-чуть доработан у нас тоже отрисовать немного иначе хочется использовать их сразу как реакторс компоненты передавать туда соответствующие пропсы цвета размеры чтобы с этим было удобно работать именно как с иконками И для этого есть лодер который называется сгр достаточно популярный лодер вообще с свш ками можно работать очень по-разному я показываю лишь один из вариантов с помощью как раз вот этого лоде Давайте в первую очередь его установим и после установки сразу же посмотрим на пример использования Ну добавляется он также как любой другой лодер который мы уже добавляли здесь как вы можете заметить можно какие-то опции в него передавать с ними тоже сейчас поработаем Ну и как можете заметить лодер достаточно популярный почти 6 млн скачиваний так Ну давайте его настроим копируем вот этот вот объект с настройкой самого лоде и переходим в нашу функцию Build loaders единственное не забываем удалить обработку свгк из Асет лоде иначе свг будут обрабатываться дважды и непонятно к чему это приведёт так объект сделали регуляр для обработки свгк указали и добавляем этот лодер в массив Так теперь вот этот вот календарь мы называем с большой буквы поскольку теперь sgr будет нам создавать автоматически реакт компоненты Ну и Давайте вот здесь где-нибудь снизу в отдельном диве этот компонент добавим опять же если вы вот эту вот строчку в Global DTS с объявлением модуля не добавили Не забудьте это сделать иначе тайпскрипт у вас руг Ну и Давайте запустим сборку npm Start и вон можно эту иконку заметить она маленькая Ну потому что там сама свш 20 на2 вот здесь даже это можно увидеть и если мы попробуем передать пропсы например поменять цвет Фил на красный то Увидим что цвет также поменялся и можем также и размеры поменять сделаем например 50 на 50 но с размером тут не всё так просто сейчас поймёте Почему Обратите внимание что иконка визуально осталась маленькая но если мы направим на вот эту свш то мы увидим что вот размер самой оболочки он действительно 50 на 50 всё ожидаемо это Те размеры которые мы указали но размер содержимого остался прежним То есть как бы сам сам вот объём заполняемый 50 на 50 но сама иконка осталась такой же и на самом деле Вот здесь мы уже в документации где-то видели такой прос который можно передать прос называется icon это бун значение и Он позволяет нам работать с свг ками именно как с иконками и удобно менять для них размеры Давайте прямо вот целиком Вот это всё с копируем отсюда и заменим вот здесь так немного отформатирую чтобы это всё получше читалось так Ну и отлично прокинулись вообще в сборке лучше её перезапускать размеры мы указали Давайте посмотрим как календарь от рисуется теперь Ну и как видите Да уже можно заметить что календарь ставил больше давайте сделаем его ещё больше ну и сейчас он прям стал вообще огромным то есть таким вот образом мы можем легко заменять размеры иконок ещё при работе с иконками особенно когда вы встраивается их куда-то в текст или как-то особенно обрабатывает цвета удобно менять цвет через свойство Color то есть цвет для шрифта например и цвет для иконки вы задаёте одновременно это во-первых а во-вторых у свгк за цвет отвечает обычно два свойства это и STR Color То есть первый отвечает за заполнение цветом а второй грубо говоря за обводку и не всегда это бывает удобно и вот если мы укажем Color сейчас например в зелёный Как видите у нас ничего не поменяется при этом тут можно подумать может быть Илан стили не применили Давайте попробуем сделать прямо отдельный класс тоже укажем значение Green и повесим этот класс на нашу иконку Ну и как Как видите тоже ничего не поменялось Ну и на самом деле Чтобы это начало работать необходимо добавить ещё один планчик для svg лоде немного поковырять и Погугли я нашёл конфигурацию я её сейчас сразу вставлю чтобы не переписывать выглядит она вот таким вот образом плагин называется convert Colors и внутрь необходимо передать параметр current Color это важный параметр который как раз позволит принимать иконки цвет вот текущий цвет Давайте вообще откроем свш и посмотрим как это работает прямо вот найдём какой-нибудь участок этой свш например вот здесь попробуем задать л красный Как видите окрасился сам квадратик если зададим строк то красится как бы область вокруг квадратика ещё дополнительно И на самом деле что в л что в Stroke можно передать как раз вот это значение current Color тогда оно будет брать его вот грубо говоря от родителя но чтобы не указывать это значение вот так для каждого вот участка в свш как раз вот этот плагин эту работу и упрощает он как раз это делает за вас так его мы добавили Давайте Теперь попробуем перезапустить сборку и посмотрим как это отработает сейчас иконка по идее должна стать зелёной и иконка по какой-то причине цвет не поменяла Давайте подумаем Почему [музыка] ХХХ сходу прямо трудно на это ответить есть догадка что это из-за того что вообще не указан никакой цвет вот здесь вот указан л Black л Black Да в двух местах он указан Давайте попробуем эту иконку свг импортировать посмотрим как с ней себя поведёт Да вот эта иконка Как видите окрасилась если мы попробуем сейчас передать какой-нибудь другой цвет прямо вот так лайном Ну да цвет меняется Очень странно почему на той иконке не поменялось надо на самом деле поковыряться поде бажи вообще по идее всё должно работать до этого я на десятки наверное иконок это обкатываю и всё было хорошо ладно двигаемся Дальше из-за того что мы вот здесь просто указали свг как модуль но не указали что из себя этот модуль представляет у нас никакого автокомплит по псам не будет потому что typescript не понимает что это вообще за модуль Как видите нет подсказок опять же Давайте эту ситуацию исправлять пишем sgr types и открываем первую же ссылочку опять же я когда готовил к ролику эту ссылочку уже открывал Здесь нам предлагают сделать вот такую вот декларацию в которой мы явно указываем что у нас экспортируется с вгш с соответствующим типом из реакта Давайте прямо скопирую и вставим этот кусок кода ну здесь если посмотреть ничего сложного нет для тех кто с тайп скриптом плохо знаком может конструкция показаться достаточно сложной но в это вникать особо не стоит если мы заглянем внутрь мы увидим как раз все вот эти значения col высота ширина и вот сейчас крипт должен все подсказки давать правильно единственное как я говорил вебшторм у меня сейчас с йп скриптом дружит очень плохо и подсказок он не даёт я вот прям тот же абсолютно проект открыл на другом компьютере Как видите здесь он тип определил правильно и автокомплит как раз все пропсы успешно подсказывает то есть с точки зрения тайп скрипта У нас сейчас всё отлично У меня барахлит именно вебшторм я там игрался с с версиями тайп скрипта и скорее всего он куда-то не туда сейчас смотрит так отлично с этим разобрались двигаемся дальше И сейчас мы говорим про переменные сборки переходим сразу к примеру начнём с того что откроем P и сразу же добавим там пару новых скриптов назовём Build mob и Build Desktop и будем передавать здесь дополнительные переменные окружения назовём её например ПТФ соответственно в одном скрипте будем передавать значение Mobile во втором будем передавать значение десктоп теперь эти переменные окружение укажем в нашем интерфейсе чтобы у нас была типизация на этом уровне Ну и также добавим в Build options создадим здесь отдельный тип назовём его Build platform ну и соответственно он будет принимать два значения Это либо Mile либо Деп возвращаемся к здесь указываем Тип который мы сделали bu ПТФ и также как я уже сказал добавляем его в Build options не забываем поменять название поля сейчас пока что может быть непонятно для чего я это всё делаю но погодите минутку Когда будет уже наглядный пример всё станет Понятно ну и прокиды соответственно Вот эту вот платформу в опции нашей сборки опять же сделаем эти флажки Все опциональная может быть передана а может быть и не передана и задаём дефолты чтобы как раз на случае если кто-то что-то не передал дефолт всегда у нас был Так теперь переходим к плагинам у в пака есть плагин который идёт по умолчанию то есть его дополнительно устанавливать не надо И называется он define плагин Давайте его в общий список добавим чтобы он в деви и в проде работал импортируем его из в пака и Давайте откроем документацию посмотрим что он вообще делает если кратко то он подменяет глобальные переменные которые вы используете в коде на те значения которые вы задаёте на этапе сборки это могут может быть значение версии вашего проекта environment Production или Def Ну в общем любые значения платформа как мы передали Ну и то есть значение вот этих глобальных переменных нужно просто передать в виде вот такого объекта ключ значения давайте так и сделаем назовём переменную платформ и чтобы задать её значение Нам необходимо достать его из options вот таким вот образом теперь переходим в компонент ректорский и попробуем значение этой переменной вывести напишем здесь платформ единственное вот сразу хочется сказать что вот такие вот переменные которые задаются на этапе сборки надо называть по какому-то особому шаблону или капсом или выделять какими-нибудь подчёркивания чтобы сразу всем было понятно что это вообще за переменная Откуда она взялась Потому что если просто строчными оставить это очень неочевидно Итак переменную мы добавили но сейчас пока что непонятно что это за переменная typescript её не видит эта переменная нигде не объявлена и для того чтобы она стала видна Как видите даже сборка у нас там на reil отвалилась необходимо декларировать эту константу и задать ей значение в нашем случае она принимает значение либо десктоп либо мой вот здесь опять же на этапе монтажа заметил опечатка вместо платформ должно быть Mobile Чуть позже я это исправлю так отлично константу декларировать Давайте пере запустим сборку Как видите Вот здесь Да тоже вебшторм её начал видеть делаем npm Run Start и сборка у нас почему-то отвалилась Desktop is not defined так вероятно вероятно Давайте откроем сейчас список плагинов скорее всего нужно было как в документации завернуть это в Jon string F вообще странно Это и так строка но видимо какой-то скрытый смысл там есть сходу затрудняюсь ответить почему так давайте да Как видите запустило всё нормально и платформа у нас отображается теперь но пока что на самом деле не очень понятно что я хотел показать этим примером Ну переменная и переменная но Давайте посмотрим как себя будет вести сборщик если мы добавим какой-то условный код если например платформа у нас равняется десктоп или равняется Mobile Давайте сначала десктоп условие напишем будем возвращать div Вот с таким вот текстом Да вот здесь я в момент записи видео увидел что я не то значение указал в декларации вот здесь конечно да вместо платформ должно быть Mile Ну и второе условие соответственно для мобилок здесь вот единственно заменим на десктоп Вот и теперь Давайте попробуем сделать две отдельные сборки как раз с помощью тех скриптов которые мы добавляли в P Son Давайте начнём с mobile так здесь я что-то не так вёл Давайте ещё раз npm Run Build Mobile сборка прошла успешно Давайте заглянем в файлик так здесь много всего но Давайте поиском попробуем найти текст Mobile Как видите этот текст сборки есть но если мы попробуем поискать поиском из десктоп платформ то как видите такие вхождения в строку отсутствуют то есть вот этот вот блок кода целиком выпилил из сборки потому что webpack понимает что это условие никогда не выполнится и соответственно он этот код из сборки выпиливают то же самое будет если мы сделаем сборку десктопную Давайте подождём пока она соберётся ещё как хороший пример для чего это нужно можно добавить какой-нибудь вот такой вот флажок из Def и при локальном запуске приложения в режиме Def можно отрисовывать какие-то дополнительные Я не знаю части интерфейса добавлять какие-нибудь де тузы В общем смотреть на вот этот вот флажок и быть уверенным что в продакшн он не попадёт если вы конечно правильное значение задали то есть всё что касается вот этого дева будет выпиливать из кода можно вот так вот передавать прямо и в коде уже смотреть если en development дела Это если прокш делай это опять же можно какие-нибудь дополнительные компоненты в общем всё что угодно Давайте даже убедимся в том что это работает смотрим на enf если development то можно там я не знаю опять какую-нибудь функцию вызвать которая вам там Def Tools будет добавлять Давайте я вот этот просто кусок кода оставлю вам Как пример чтобы потом в исходника это всё было Ну и да минута ранее мы сделали сборку десктопную Как видите теперь вхождение строки такое находится а is Mobile как раз наоборот отсутствует то есть опять же на основани этого мы можем сделать вывод о том что целая ветка кода из сборки была выпи тем самым можно разделять например бандлы на два один бандл для десктопа другой бандл для мобилки и соответственно по каким-то разным урла можно разные сборки раздавать в впаке много различных встроенных оптимизаций и как раз эта оптимизация называется Шейн И за счёт каких-то встроенных механизмов оптимизации wep может понять Какие импорты Какие функции Какие ветки кода не используются и соответственно он их из сборки выпиливают вот сейчас Вы можете заметить что тот консоль который мы написали to Fun он в главном бандлер ещё раз откроем M bule поиском пройдёмся Ну и Да вот он это н Нашёлся то есть вот эта функция до тех пор пока она была не использована она в итоговый бандл не попадала как только мы её за использовали внутри кода вебпак это понял и соответственно он её в итоговую сборку добавил и Давайте подытожим этот механизм называется ещё раз Шейн то есть происходит своего рода встряхивание дерева дерево импортом каких-то разветвлений в вашем коде если заранее их можно предпочитать какой-то неиспользуемый код который висит мёртвым грузом ВД его может встряхнуть и соответственно в итоговую сборку этот код не попадает Как сделать его наиболее эффективным это использовать динг ленивые чанки плюс грамотно всё декомпозировать Опять же об этом я говорил в своём ролике про оптимизации ссылочка будет в комментариях и всплывёт подсказка с этим думаю Понятно Ну а Мы двигаемся дальше И сейчас поговорим Про проверку типов отдельным процессом давайте сейчас наме сделаем какую-нибудь тайп скрипто ошибку вот да функция на вход у нас ожидает Number мы передаём стрин Ну и Давайте попробуем сделать сборку уже сейчас можно заметить что сборка у нас достаточно долгая 4-5 секунд на мощном железе Хотя проект у нас полупустой и при этом на любую тайпскрипт ошибку у нас сборка будет падать что тоже не есть хорошо типа мы можем проверять как-то отдельно с помощью какого-нибудь скрипта который просто запускает там TS Note или tsc заранее настроены и вот проверка вот этих типов сборку очень сильно замедляет особенно если проект Большой типов много сборка будет очень долгой Ну и вообще важно понимать что каждое действие которое вы производите в впаке добавляете новый плагин новый лодер какие-то оптимизации что-то док дручинина И на самом деле есть решение Давайте откроем документацию тест лоде и почитаем что нам там предлагают опять же как видите Мы очень много ходим по разной документации Но для начинающего собрать это всё воедино в цельную картину без вот такого видео практически нереально для того кто с этим никогда не сталкивался Вот и здесь есть флажок установив который мы можем значительно ускорить компиляцию флажок называется transpile Only то есть сам лодер будет осуществлять только сборку то есть компиляцию самого тайп скрипта и проверку типов он при этом делать не будет вот так вот выглядит этот флажок Давайте его добавим откроем Файлик с лоде найдём TS Loader Так давайте его пока удалять не будем Потому что у нас там есть наши комментарии [музыка] продублируйте добавим ещё exclude и вот эти вот комментарии так выровняли это всё ещё лишнее удалим так но ещё на самом деле опять же здесь можно как-то поиграться с этим опять же подстраивается сами Под свою Ситуацию которая нужна Вам на проекте можно такой режим оставить только в деве можно и в проди Давайте проект запустим посмотрим как это будет работать сборка упала потому что я забыл регуляр вот здесь ещё добавить так что-то как будто всё равно не то давайте скопирую прямо с документации пример прямо вот целиком Весь вот этот объект копируем и вот здесь вставляем и exclude добавим Да вот теперь выглядит лучше так ну и пробуем сделать сборку ещё раз сейчас должно быть всё ок да сборка прошла успешно и уже можно заметить что она стала в два раза быстрее вместо привычных 5 секунд стало 2 с по Ну и тайп скриптовая ошибка которую мы намеренно сделали никак в логах у нас не всплыла то есть сборка вместе с этой ошибкой прошла всё равно успешно Ну и как я говорил на самом деле можно сделать прямо отдельный скрипти в Pack Son с запуском именно тайпскрипт вой компиляции проверок ошибок запустить обычный тсц назвать как-нибудь это Script Type Check Ну и опять же где-нибудь вся его например прогонять чтобы тайп скриптовые ошибки не попадали в Мастер ветку Давайте попробуем внести какие-нибудь изменения видим что первая сборка у нас прошла За 2 с по секунды ребилд за 150 миллисекунд Давайте попробуем вернуть ещё раз вот этот transpile Only в значение false и посмотрим Сколько времени сборка будет занимать сейчас так ну во-первых у нас ругнулся с ошибкой тайп скриптовый а во-вторых сборка заняла 4,6 секунд Давайте вот эту ошибку тайп скрипто исправим сделаем сборку ещё раз Ну тоже 4,4 4,6 В общем в пределах 4,55 секунд сборка занимает То есть как видите изменение вот этого флашка ускорило сборку в два раза опять же цифры - это абсолютно не объективные потому что проект маленький тайп скрипта мало всего мало И здесь цифры очень относительные но Поверьте это в любом случае ускоряет Но что же делать если мы всё-таки хотим вот так вот в realtime типы проверять И для этого прямо здесь же нам рекомендуют специальный плагин который называется Fork TS Checker wep и он как раз выносит проверку типов в отдельный процесс это говорит нам о том что сборка замедляться не будет но и при этом отдельно в отдельном процессе типы Также будут в Реал тайме проверяться Давайте в первую очередь этот плагин установим и в документации посмотрим как его использовать Ну по сути всё что необходимо это добавить в список плагинов как раз плагин который мы установили Давайте прямо вот эту строчку скопирую откроем Файлик где у нас идёт настройка плагинов и опять же тут в зависимости от того как вы конфигурируется можно в де режиме его добавлять можно в прот режиме его добавлять зависит скорее от значения флажка который мы вот ранее делали transpile Only если он у вас всегда True то можно всегда этот плагин добавлять если По какому-то условию то тоже можно там посмотреть Ну в общем давайте сейчас запустим сборку посмотрим как это работает намеренно делаем опять п скрипто ошибку видим что проект билди всё хорошо сборка прошла успешно но видим Что также у нас отдельно идёт проверка типов и поскольку у нас есть ошибка он сразу же на неё ругается то есть мы сохранили по сути тот же функционал проверка типов у нас остаётся но при этом она вынесена в проце то есть мы рас параллели отдельно сборку и отдельно проверку типов тем самым сборку мы не нагружая какими-то дополнительными действиями и проходить она будет значительно быстрее Ну наверное всё же вот в общий список плагинов я бы не стал это добавлять Скорее это нужно для этапа разработки поэтому вынесем под флажок из Итак с этим разобрались двигаемся дальше И сейчас поговорим про такую концепцию как H modl Ну и Давайте сразу на предлагаю вот этот лишний код который у нас здесь есть пока что закомментировать удалять не хочу Пусть будет у вас потом в исходника чтобы можно было посмотреть и запустим проект так проект запустился Теперь давайте наполовину вот так вот откроем среду разработки чтобы видеть изменения которые мы вводим Ну и Давайте например вот здесь поправим цвет изображения сейчас ключевой момент обратить внимание вот сюда страница перезагружается на какие-либо изменения то есть Вот вводим какой-нибудь текст в div и видим как на долю секунды страница перезагружается если у вас заполнена какая-то форма или открыта модалка то понятное дело всё состояние которое вы натыкались будет слетать на любые изменения в коде и вот Hot module replacement - это функционал который позволяет обновлять код без перезагрузки страницы вообще в классическом сценарии для того чтобы он заработал в настройках Def сервера достаточно добавить опцию ход в значение True но Давайте всё же пойдём в документацию и посмотрим что нам предлагают там webpack hmr открываем первую ссылочку видим что здесь Да в Def сервер добавляется H True это мы уже как раз сделали давайте сейчас попробуем запустить опять сервер и посмотрим как это будет работать опять же открываем файлик пробуем заменить цвет и видим что страница всё равно перезагружается это происходит быстро за доли секунды потому что проект маленький Однако перезагрузку всё равно можно заметить то есть вот как раз то состояние формы или там открытая модалка у вас всё равно слет на самом деле если бы вы писали на чистом GS или ТС то у вас бы всё начало работать но с фреймворка там есть некоторые нюансы и для того чтобы на реакте у вас hmr начал работать надо проделать ещё пару манипуляций вот тут э документация опять же есть все необходимые ссылочки Ну и как вы можете заметить здесь в документации написано что вот этот react Hot Loader будет заменён react Fast Refresh и лучше использовать его если он поддерживается вашим окружением и webpack как раз поддерживает Fast Refresh плагин Как видите вот здесь вот есть ссылочка Давайте перейдём в него вот он этот плагин более актуальная штука ну и Давайте начнём с установки копируем скрипт вставляем в терминал Ну и пока он устанавливается Давайте посмотрим как использовать здесь вот сразу разные примеры для Death Middle W используя с реактора Fresh BB B мы пока что не используем мы используем для компиляции TS Loader Поэтому вот этот спойлер разворачиваем видим что для поддержки Лора вот этот вот react Refresh typ Script э штука не официальная но однако Давайте попробуем его за использо зави и Давайте посмотрим как это ВС подключается Ну в общем здесь кру добавляется ещё одна дополнительная опция вот он и вот здесь вот в подключается как раз tyt и в сами плагины мы добавляем вот этот плагин то есть для ра добавляем штуку которую мы только что установили А в лаги добавляем сам вот этото кото так Автоимпорт штормом не подхватил Давайте импортируем руками скопирую вот здесь название делаем импорт Да плагин сам мы добавили теперь добавим Вот эту вот настройку для Лора вот у нас лодер вот у нас Осы и сюда Это всё добавляем здесь оставляем флажок из то есть работать экат нас ну и импортируем то же сам react Refresh typ Script так всё вроде бы добавили Давайте ещё раз взглянем на документацию помимо bable TS лоде есть ещё Дока для свц лоде но вроде бы всё Давайте теперь посмотрим как это будет работать запускаем проект проект успешно запустился Давайте теперь тоже в пол окна ОТК среду разработки и откроем какой-нибудь компонент окошко чуть свернём и пробуем что-нибудь поменять опять же обращаем внимание Вот сюда сейчас страница перезагружаться на какие-либо изменения не должна пробуем поменять цвет обратно на красный видим что страница не перезагружается пробуем ещё какой-нибудь текст внутрь Дива добавить Ну как видите Да оно всё добавляется в ход режиме и как это на самом деле работает Давайте откроем тузы и попробуем что-нибудь поменять видим что у нас прилетает на каждый сейв какой-то кусок данных который он автоматически вход в таком режиме подменяет то есть мы не перезаправки страницы а вот в таком вот режиме именно запрос ответ мы эти данные подгружает тут в консоли как раз все вот эти махинации можно увидеть в логах видим что вот у нас Dev сервер запустился И hmr ждёт как раз сигнала и ещё если мы страницу Перезагрузи то мы увидим что у нас вот открывается websocket соединение и как раз по этому websocket соединению мы эти файлы и получаем то есть вот эти куски жава скрипта ещё вот уже на этапе монтажа я осознал надо было вам показать пример когда мы счётчик накли наш потом что-нибудь меняем и видим что состояние счётчика сохраняется то есть страница не перезагружается состояние остаётся и в этом основное преимущество hmr Ну ещё преимущество конечно то что это работает быстрее потому что нам страницу перезагружать не надо но и то что состояние всяких форм там опять же молок Ну и любые какие-то пользовательские данные которые он уже Накликай разобрались теперь поговорим про то как использовать фав иконки и Copy плагин Давайте в первую очередь в папку Public добавим какую-нибудь иконку в моём случае это вот такая вот иконка с моим логотипом Если вдруг кто не знает на всякий случай уточню эта иконка будет отображаться вот здесь так ну в общем в переносим любую иконку Теперь давайте проделаем дополнительные манипуляции во-первых Нам нужно будет путь до этой иконки указать предлагаю указать до папки па Даже его добавим ещё вот здесь вот в сам интерфейс так и теперь в самом HTML плагине есть такая настройка как здесь указы до папки и добавляем название фа иконки обычно оно статичное так Теперь давайте откроем HTML Файлик видим что у нас здесь никаких ссылок на фа иконку нет есть только title и Ди с ашнико Root давай Теперь попробуем сделать Билд например в продакшн режиме откроем теперь папку со сборкой Ну во-первых видим что у нас сама нка здесь появилась Во вторых если мы заглянем в саму HTML то да вот мы увидим Линк ссылкой на фав иконку то есть вот на неё даже можно вот так вот перейти с этим понятно здесь никаких трудностей Нет давайте теперь поговорим про то как вот тоже саму сборку перемещать какие-то дополнительные файлы представим что в папке Public у нас также находятся переводы например статичные какие-то Jon файлы на русском английском там французском турецком и любом другом языке и чтобы наша итоговая сборка эти файлы видела и могла с ними работать Нам необходимо их вот в эту папку Build каким-то образом переместить Ну и например представим что вот здесь у нас какие-то переводы думаю наполнять сами файлы особого смысла не имеет Наша задача сделать так чтобы они оказались внутри папки на самом деле опять же как я говорил любых плагинов На вкус и цвет каких только нет ну и соответственно плагин который перемещает файлы тоже есть Называется он Ну и думаю исходя из нания уже понятно что этот плагин делает Давайте его установим пока плагин устанавливается опять же возвращаемся к документации и видим пример использования Здесь тоже до предела всё просто копируем прямо этот пример открываем плагины нас интересует прод сборка потому что в деве нам никуда эти переводы перемещать не надо копи плагин импортируем из копи Пак плагин Ну и смотрим на то как это работает то есть указываем путь откуда и куда мы хотим переместить тот или иной кусок нашего проекта указываем путь From из папки Public единственное нам надо будет ещё склеить чтобы указать путь до папки с самими переводами LS и в качестве to указываем непосредственно путь до атпу до папки Build пробуем сделать прокш сборку чтобы посмотреть как это всё сработает немного ждём Ну и видим что у нас появилось два файлика внутри папки Build хотелось бы конечно чтобы они лежали В отдельной папке поэтому здесь можно чуть путь подправить он содержимое именно скопировал папки loes а не саму папку Ну это всё легко поправимо опять же склеиваем и просто добавляем папку npm Run Build ждём пока пройдёт сборка Ну и видим да что теперь у нас появилась отдельная папка и вот эти два файлика переместились именно туда сейчас за компиляцию ty скрипта и вообще всего кода у нас отвечает но также хочется поговорить B и рассмотреть его возможности в том числе написать небольшой плагин посмотреть как это всё работает чтобы так скажем расширить кругозор Но перед тем как начать говорить про B хочется сказать про более современные компиляторы опять же их без труда Вы настроите если мы сейчас поговорим про бел но просто чтобы вы были в курсе первый - это svc он использовался в нексте и он должен работать значительно быстрее чем B второй - это S build про Build У меня даже есть отдельный ролик на канале опять же сейчас всплывёт подсказка если не забуду её добавить и ссылка также будет в описании ну а мы переходим к Бейб настроим его поговорим про этот легендарный инструмент Ну и как я уже сказал Сейчас за компиляцию основного кода за typescript у нас отвечает TS Loader сейчас мы будем заменять его на B bable лучше поддаётся кастомизации на него можно написать куча различных плагинов которые вам нужны либо же использовать существующие ну как я уже сказал это компилятор который позволяет использовать новейшие функции жава скрипта даже которые плохо поддерживаются в браузере позволяет компилировать typescript писать jsx к которому мы так привыкли в реакте В общем позволяет использовать все современные фишки не переживая за то в каких браузерах они поддерживаются в каких не поддерживаются Ну и опять же Давайте идти по документации выбираем Билд систему в нашем случае это webpack и в первую очередь нам советуют установить bable Loader и Давайте их установим после установки следующим этапом Нам необходимо будет добавить лодер который будет обрабатывать JS файлы также создать ещё bable config но Давайте прямо по пунктам идти скопирую вот этот вот объект с лоде И откроем Файлик в котором мы Лоры как раз настраиваем создадим здесь отдельную константу и вставим то что мы скопировали единственно Здесь вы сразу можете заметить что регулярка обрабатывает только JS файлы А у нас вспоминаем наш T Loader обрабатывал TS и tsx файлы Давайте эту регуляр сразу заменим но из коробки если мы сейчас T Loader заком и оставим только B Loader у нас естественно ничего не заработает потому что какие-то Дополнительные настройки для тайп скрипта мы пока что не сделали Как видите Да сборка у нас отваливается с ошибкой Ну да здесь он и на jsx ругается вот синс jsx не поддерживается ещё на что-то там ругается Давайте разбираться Давайте двигаться по документации дальше откроем вкладку Docs и здесь откроем пресеты пресеты включают в себя всё необходимое для того или иного функционала Давайте прочитаем что здесь написано preset - это один из основных пресетов который позволяет использовать все новейшие функции жава скрипта здесь есть интеграция браузер L Ну в общем здесь я думаю всё понятно Давайте посмотрим какие ещё есть пресеты пресет для реакта чтобы jsx работал и пресет для тайп скрипта он нас интересует сейчас в первую очередь думаю что здесь объяснять особо не надо Для чего нужен пресет для тайп скрипта Это вроде бы и так из названия очевидно но Давайте его установим теперь посмотрим как использовать проем чуть ниже всё что необходимо сделать - это Добавить его в массив пресетов там сказано добавить конфигурационный файл Но поскольку у нас webpack отвечает за компиляцию можно добавить его вот здесь вот в опции прямо пробуем сделать сборку Ну и да сборка отвалилась здесь есть какие-то проблемы с jsx у нас и думаю Здесь тоже не трудно догадаться Какой пресет нам необходимо поставить кстати когда вы открываете пресеты у вас вот здесь сразу указано Какие плагины внутрь себя Они включают то есть вот здесь по умолчанию идёт плагин для трансформации тайп скрипта здесь вот кстати почему-то в preset не указано в preset react идут вот такие вот syntax jsx transform react jsx и transform react Display name Ну и Давайте этот пресет также установим вернёмся к документации Да здесь также необходимо добавить его просто в массив пресетов Ну и на этом по идее Всё Давайте попробуем сделать сбор npm R Ну и да на этот раз сборка прошла успешно Давайте попробуем сделать теперь де сборку Ну да де сборка тоже прошла успешно Хочется ещё убедиться что в режиме де сервера У нас тоже всё будет хорошо делаем npm Старт Как видите сама сборка прошла успешно но если мы откроем Local H 3000 сейчас вероятно мы получим ошибку Да react not Def Давайте разбираться Почему так опять же ничего не придумываем не гадаем копируем ошибку B Loader и вставляем ошибку видим пару ссылок с этой проблемой открываем и смотрим Что здесь за решение нам предлагают в ректорский пресет рекомендуют добавить вот такую вот опцию Run автомати Давайте ещё посмотрим что здесь пишут Ну вот здесь тоже да R по условиям давайте так и сделаем для того чтобы передать какие-то опции его вот так тоже необходимо завернуть в массив первым элементом массива идёт название а вторым элементом идут как раз опции Ну и здесь мы передаём объект с R ав на самом деле здесь можно вот так вот даже условие сделать если из DF автоматик иначе Classic выровняли всё это ну и Давайте перезапустить сборку посмотрим как сейчас это всё отработает ну и сейчас всё запустило отлично Всё работает по переходит как бы мы вернули тот функционал который у нас выполнял TS Loader и хочется ещ сказать поскольку мы используем webpack все настройки пресетов плагинов можно указывать прямо здесь Но если вы B используете как какой-то отдельный инструмент то можно использовать конфиг файл Давайте вообще рассмотрим на самом деле его и с вебком можно использовать можно так можно так Давайте попробуем здесь вот можно создать с разными названиями с разными расширениями эти Конфи ционные файлы Давайте создадим классические b.c. Jon и в принципе вот эти все настройки пресетов вот эти вот все опции которые мы передавали здесь можно задать тут единственное из-за того что это Jon файл необходимо будет Вот так вот в двойные кавычки всё это завернуть Ну и вот от этой конструкции тоже придётся избавиться оставим здесь только автоматик так вот здесь тоже одинарные кавычки на двойные заменим лишнюю запятую уберём и вот здесь options уберём если мы сейчас запустим npm ranst то по идее всё тоже должно полететь да Видите сборка прошла успешно он как бы этот файл автоматически в корне проекта находить умеет здесь опять же как удобнее Можно оставить здесь эти настройки можно оставить отдельный bable config но опять же если вы используете например какой-нибудь gest для которого вам тоже нужен bable тогда можно вынести вот так в этот файл чтобы он грубо говоря был универсальным здесь опять же по ситуации смотрите я показываю и такое и такое решение Так ну и Давайте двигаться дальше сейчас мы настроили пресеты по сути сделали такую минимальную конфигурации у Бейла при котором мы можем работать с TS можем работать с jsx и со всеми новыми функциями жава скрипта но пока что бел всё равно такой чёрный ящик непонятно как работают эти плагины как они обрабатывают код и хотелось бы реализовать свой собственный плагин для того чтобы понимать как это под капотом работается как обрабатывается Исходный код сечас мы на это ВС Будем смотреть и поскольку этот лодер можно очень гибко кастомизировать добавлять куча плагинов и он также может разрастаться его можно вот также вынести в отдельный Файлик то есть декомпозировать ещё дальше давайте так и сделаем здесь вот из здесь просто вот эту функцию вызовем опять же если захотим как-то бел кастомизировать что-то добавить то переходим уже в конкретный Файлик опять же все вот такие вот большие лоде с какой-то настройкой кастомизацией можно выносить в отдельные файлики если вам так удобнее так с этим разобрались пресеты добавили теперь как я и сказал Давайте напишем свой плагин Но перед тем как его писать хотелось бы обозначить сначала проблему которую мы с помощью него будем решать представ что у нас есть какие-то тесты юниты e2e там я не знаю интеграционные неважно И мы в коде указываем Data Test ID эти дата Test ID у нас указаны на кнопках инпута селекта В общем на всём с чем мы хотим работать в тестах но важно что вот эти Data Test ID нужны нам только на этапе разработки в Def режиме либо же когда мы запускаем тесты то есть в продакшн коде эти дата тест дишни нам не нужны ни при каких условиях и вот вот хочется сделать так чтобы эти Data Test ID из продакшн кода исчезали и вот наш плагин собственно говоря этим и будет заниматься давайте сделаем npm Run Start Да единственно вот здесь какая-то ошибка есть да здесь не из Def мы достаём а достаём мод А из Def уже выводим из этого мода скопирую здесь вот так вставим на единственно от этого options можно избавиться Да ну Давайте ещё раз запустим npm Run Да всё отлично запустило Давайте откроем инспектор И найдём те Data Test ID которые мы добавили Ну вот они соответственно есть и опять же понятно Для чего нам это нужно на этапе разработки но абсолютно непонятно для чего нам нужно это в продакшене При этом если мы сделаем npm Run Build prod дождёмся пока у нас сборка пройдёт и откроем наш бандл единственное Я вот здесь бы сделал какой-нибудь более такой понятный Data Test ID чтобы его поиском можно было найти Давайте ещё раз сделаем сборку откроем бандл и поиском попробуем его найти то да вот мы увидим Create Element div Data Test ID Up dat Test ID То есть это всё попадает в итоговый бандл И как я уже сказал Наша задача сейчас сделать так чтобы в бандл это всё не попадало и вот здесь вот самое время поговорить про а дерево абстрактное синтаксическое дерево которое строится из нашего кода давайте сейчас прямо какой-нибудь кусок кода скору Ну можно вот ну хотя нет Давайте вот здесь вот просто целиком Вот это всё скопирую сюда вставим и единственное вот здесь вот нужно будет выбрать что у вас Тап Script да и всё должно работать Давайте посмотрим как это абстрактное синтаксическое дерево выглядит Давайте всё вот это посвободнее мы делаем импорт Что именно мы импортируем и кстати говоря у меня на канале есть Прямо отдельный ролик Где мы создаём свой язык программирования и там мы делаем своё абстрактное синтаксическое дерево простенькое но делаем кому интересно такой Аля компью Science опять же ссылочка будет в описании либо ищите на канале если забуду добавить Ну и Давайте дальше посмотрим это дерево Вот идут наши импорты и потом видим function declaration объявление функции вот оно здесь есть идентификатор это название функци ключевое слово Number и собственно вот весь код он разбивается на вот такие вот ноды видим что у нас есть у функции параметры эти параметры мы можем получить видим что у нас вот есть variable declaration это наш компонент внутрь компонента этого если заглянем видим там тоже переменные какие-то блоки и вот весь код на вот такие вот ноды поделен это такое дерево где Корень это как бы сам Вот сама программа И вот оно вот так вот уходит каждая Функция может содержать в себе переменные другие функции файл может содержать в себе импорты какие-то константы ключевые слова и всё это вот так вот делится на вот такие вот ноды и в итоге с этими нодами мы можем работать это называется код Shift когда мы код как-то можем изменять И вот бел - это инструмент который как раз работает с вот этим абстрактным синтаксическим деревом и давайте сейчас посмотрим как это всё примерно выглядит единственно для того чтобы у нас сейчас но ВС подсказывал Нам необходимо установить типы для B Core давайте сейчас откроем браузер напишем types B Core как-то вот так этот пакет назывался Да вот он 23 милна скачиваний Да это точно он Давайте его установим единственно устанавливаем Как де зависимость Ну и Давайте писать Лагин во-первых сразу же укажем Что на вы плагин item этот тип как раз из bable Core Здесь вся нужная типизация для того чтобы написать свой плагин имеется опять же здесь в синтаксис какие-то детали абсолютно вникать не надо Это всегда можно посмотреть в документацию открыть опиш и посмотреть сейчас как бы мы смотрим более высокоуровневые саму концепцию как вот с этими нодами Мы работаем Как мы можем их обрабатывать изменять И вот это вот всё И вот Обратите внимание здесь мы уже сразу можем указать import declaration function declaration это именно те ноды абстрактного дерева которые мы собираемся искать как раз те что мы рассматривали вот здесь в А эксплорере здесь мы высокоуровневый указываем Program это функция которая принимает Pass и некоторый й из стейта мы сразу можем достать опции которые мы в этот плагин будем передавать в нашем случае это запрещённые пропсы которые как раз будут удаляться достаём вот таким вот образом State options props или же это будет пустой массив на всякий случай подстрахуй если никакие опции не передать далее используем функцию travers в которой как раз мы уже будем искать нужную ноду и как-то её обрабатывать в нашем случае мы ищем идентификатор jsx это как раз вот этот Data Test ID который нам нужен опять же сделаю вот прям важную оговорку на синтаксис Не обращайте внимани это всё на гуглить открыть доку посмотреть не проблема сейчас смотрим на основную суть мы получаем название ноды то есть вот наш jsx идентификатор и нам надо убедиться что мы находим именно Data Test ID то есть мы получили название вот этой вот ноды и теперь смотрим Есть ли это название как раз в запрещённых Псах используем includes и туда передаём название ноды если это условие выполняется Значит мы нашли нужный для нас прос в нашем случае Test ID и тогда ноду мы удаляем у шторма единственно опять какие-то затупы здесь Тап скриптом почему-то функцию вообще не видит но опять же думаю на сборку это никак не повлияет Это скорее опять же косяки шторма Давайте Теперь попробуем этот плагин заю посмотрим как вообще это всё будет работать открываем Build B loaders здесь у нас помимо пресетов также может быть массив плагинов Можно либо сразу передать сам плагин либо если мым передать вго оп то мы передам массив первый элемент - это сам плагин а второй опции точно также как мы делали в пресетах и указываем как раз опцию props в которую передаём dat Test ID это как раз тот атрибут который мы хотим удалить то есть вот здесь мы его получаем и потом в условий проверяем то есть мы находим запрещённые вот эти как раз пропсы которые мы хотим удалять и на этом по идее всё плагин мы добавили Давайте попробуем теперь сделать сборку npm Run build сборка прошла успешно Давайте теперь откроем Main bandle и попробуем как раз поиском найти вот этот Data Test ID Ctrl F Ну и как видите ноль вхождений если мы этот плагин закомментировать выпиливают давайте это раскомментировать только в продакшене вынесем плагины в отдельный массив в отдельную константу Ну и Здесь также По условию если у нас прок будем этот плагин как раз добавлять то есть в деве он нам не нужен потому что мы хотим в деве как раз эти Data Test ID Видеть чтобы писать тесты чтобы комфортно нам было а в продакшене мы всё это уем ну и соответственно вот этот массив плагинов вот сюда мы передаём единственно Да вот можно вот такое условие сделать ЕС хотя бы один плагин У нас есть то мы передаём массив иначе undef чтобы пустой массив туда не передавать делаем сборку в прок режиме открываем бал поиском не находим Test ID делаем теперь в режиме открываем получившийся бандл опять же Ctrl F Ну и здесь Как видите этот Data Test ID имеется Ну и Давайте немного подытожим в ходе последних 10-15 минут мы переехали на bab Loader отказались от TS Лора написали свой плагин и в принципе теперь за всю сборку основного исходного кода у нас отвечает B здесь опять же Смотрите по ситуации в зависимости от того что вам надо Если вы умеете настраивать B вам без труда составить настроить svc Loader о котором я говорил ранее настроить S Build Loader здесь опять же можете как домашнее задание закрепить поэкспериментировать попробовать сделать сборку через svc сделать сборку через S Build Loader посмотреть насколько быстрее или насколько лучше будет работать тот или иной лодер посравнить опять же для себя для общего развития можете посмотреть опять же ролик отдельный про Build вне контекста Вебка у меня на канале тоже думаю для общего развития очень даже будет полезно Так скажем расширяем Кругозор Ну и где-то в начале ролика Я обещал поподробнее рассказать про Source на наглядном примере Ну и Давайте приступим когда мы настраивали де сервер мы подключили вот здесь in Source Map Давайте эту строчку закомментировать чтобы у нас хоть какой-то был вот эти вот аргументы умбы не Мешались одну функцию вызовем в другой А здесь пробросить при нажатии на кнопку Ну и в принципе этого достаточно карты исходного кода обращаю внимание у нас выключены Ну и запускаем проект nm проек запу Давайте откроем консоль нажмём на кнопку Увидим что у нас вылетела ошибка но Давайте попробуем перейти в Исходный код и здесь можно увидеть вот такую вот картину абсолютно нечитаемый код непонятно что происходит при этом Если бы у нас файлов было гораздо больше это была бы одна огромная такая свалка непонятно где у нас возникла ошибка непонятно по какому стектрейс она пошла ну вернее что-то там можно будет разобрать но опять же для разработчика это неудобно и теперь давайте sce Map всё-таки включим и сделаем сборку ещё раз также открываем консоль также нажимаем на кнопку видим ошибку но если сейчас мы перейдём в Исходный код то мы увидим абсолютно читаемый код ровно такой же какой он у нас написан в среде разработки то есть отлавливать и дебажить ошибки становится намного проще и при этом Казалось бы всё понятно но Давайте ещё откроем документацию и посмотрим Какие виды Map у нас бывают там прямо такая табличка хорошая есть наглядная Давайте её откроем и посмотрим вот тут такая табличка с видами Source Map и Обратите внимание некоторые подходят для продакшена некоторые не подходят у каких-то качества лучше у каких-то хуже у каких-то сборка быстрая ребилд медленный у каких-то наоборот сборка замедляется но при этом ребилд мгновенный то есть здесь много-много разных видов которые подходят под продакшн под под разные режимы под размер проекта и здесь вам стоит выбрать именно тот вид Source Map который подойдёт больше вам то есть опять же вот здесь По условию можно для продакшена включать одни сорс мапы либо вообще их выключать для Dev выбирать другие Source мапы опять же вот например классический Source Map подходит под Production Build его вот даже рекомендуют с хорошим качеством этих карт исходных но единственно страдает скорость сборки и скорость ре билда соответственно для прода нас это устраивает для такой вариант вообще не подходит ищем вариант в котором быстрый ребилд То есть это максимально такой хороший вариант для именно де сборки чтобы быстрый ребилд был чтоб разработка никак из-за этого не тормозила Ну и вот здесь тоже есть варианты которые рекомендуются для девелопмент билдов есть вот такой Evil Chip module Source Map есть просто Evil Source Map опять же почитайте Посмотрите разные как-то посравнить Ну и собственно говоря вот так вот это всё работает Прошло уже 2 с поло часа и мы переходим наверное к самой интересной части этого курса и будем рассматривать мы сейчас как делать манаре позии с переиспользовать на основе этих пакетов микрофронтенды с помощью Federation modules webpack в первую очередь Давайте сохраним На гитхабе текущий проект для того чтобы у вас в исходника всё это было и вы по ходу просмотра видео смогли к этому вернуться создадим сюда добавим папку Build потому что сборку нам нет никакой необходимости отправлять на github и также добавим папку No modules и поскольку я пользуюсь штормом там создаётся ещё папка ID служебная её тоже соответственно игноре далее инициализирует проек видим что файлы у нас проинициализировать переходим на github и создаём здесь новый репозиторий после того как репозиторий создался копируем Вот эту вот строчку для того чтобы добавить ссылку на удалённый репозиторий далее индексирует Add git commit пишем любой commit message и после того как все файлы закоммитить сделаем git Push Единственное он у меня сейчас Да наверное потребует авторизоваться потому что я давно с этого ноутбука ничего не отправлял но через webstorm у меня авторизация уже есть поэтому я отправлю файлы через кнопочку через UI чтобы не авторизоваться сейчас Да отлично файлы у нас успешно улетели в удалённый репозиторий обновим здесь страничку Да вот они все доехали срц config Всё у нас здесь хорошо сможете по ходу видео этими исходниками пользоваться возвращаемся обратно к среде разработки и создаём новый проект но проект мы будем делать на базе текущих настроек то есть вот тот конфиг который мы писали на протяжении всего курса у нас будет использоваться в новом проекте мы его туда Просто нем назовём проект например mona module Federation и после создания проекта минутка теории Итак в ходе этого курса Мы разработали хоть и маленькое но монолитное приложение весь Исходный код вся конфигурация тесты все настройки если бы мы делали какой-то C pipeline сборку Всё это находится как бы в одном таком большом монолитном приложении Я очень подробно рассказывал об этом в ролике про архитектуру frontend приложений здесь пройдёмся по Хам и Вот исходный код этого приложения имеет какое-то ядро Представьте что в этом ядре есть у нас админ-панель интернет-магазин новостная лента какая-то B2B система и Казалось бы у каждой этой частички Монолита какая-то своя зона ответственности за счёт того что мы всё это разделим мы можем что-то выиграть например довозит до прода быстрее эти частички то есть отдельные микросервисы повыситься отказы устойчивость за счёт того что один сервис Не связан с другим В общем тут Можно бесконечно перечислять какие-то отличия микросервис от Монолита опять же это очень холивар ная тема кто-то считает что они нужны кто-то считает что они не нужны здесь ролик не про это здесь мы будем смотреть как вот такой вот манаре пози торий с микросервисами построить опять же если более в детали хотите вникнуть на канале ролик про архитектуру фронтенд приложений опять же ссылочка будет в описании подсказка всплывёт но давайте сейчас так схематично взглянем вообще как вот эти приложения они друг с другом вообще никак не связаны за исключением того что у нас есть некоторый entry Point точка входа определённая хост приложение которое все эти микрофронтенд По отдельности за счёт чего у нас будет быстрее сборка быстрее C CD pipeline и так далее но в каждом из сервисов У нас есть какие-то переиспользовать всякие кнопки селекты инпуты и так далее какие-то модули там сабар header какие-то ссылки в общем какие-то модули которые переиспользование ну и всякое прочее весь Share код который может использоваться в разных сервисах Ну давайте Чуть более детальнее взглянем есть UI Kit который используется вообще во всех проектах у нас опять же как я уже сказал это всякие кнопки модал всплывала скелетоны лодер и всё такое модули опять же Могут представлять из себя как отдельные страницы так какие-то виджеты фичи бизнес сущности например сущность пользователя Может быть одна и та же на все эти четыре микросервиса и соответственно мы их Вот в такой переиспользовать же общая конфигурация - Это тот же сборщик webpack вид и так далее те sty lint lint jest настройки тестов Cypress там я не знаю playwright storybook В общем всё что у вас есть в в инфраструктуре вашего сервиса и соответственно вот это вот всё хранится в одном так называемом норе для того чтобы мы без всяких npm пакетов и прочих неудобств могли использовать и UI Kit и модули и общую конфигурацию и при этом иметь внутри независимые микросервисы и соответственно Чтобы построить такой репозиторий существуют разные инструменты это воркспейс pnpm Яр или NP но npm это прямо самый простейший кстати его мы в курсе Сейчас как основу и возьмём также есть NX lerna и для построение именно уже микросервисов часто используется Single SPA или webpack module federations вот как раз последний Мы в ходе этого курса и рассмотрим для мано репозитория Ещё раз повторюсь будем использовать классический npm workspace у которого очень ограниченный функционал и при этом для микросервисов будем использовать webpack module federations но как бы ту основу которую мы разберём она позволит вам в дальнейшем строить свои полноценные микросервисы Итак переходим к практике мы сделали пустой проект и в первую очередь Давайте создадим внутри две ключевые папки директории в нашем приложении Первое - это сервисы непосредственно полноценные приложения те самые микрофронтенд Далее в корне приложения про инициализирует проект это будет корень нашего манорен Давайте поубирать скрипты пока что Ну наверное нам они здесь сейчас не нужны ну в общем всё лишнее что нам сейчас мозолит глаза Давайте уберём и самая важная настройка которую нам сейчас стоит сделать - это воркспейс именно они позволяют моно репозиторию работать Всё что будет находиться у нас в папке packages и всё что будет находиться у нас в папке сес будет пейсами то есть с помощью Вот таких вот паттернов мы это указываем чуть позже поймёте Для чего то есть вот эти вот пакеты мы сможем устанавливать прямо как npm модули Хотя таковыми они по сути не являются Только вот за счёт вот этой настройки workspaces мы их сможем вот так вот использовать Ну пока что не очень понятно Может быть но чуть позже поймёте о чём я говорю Итак давайте создадим три сервиса Admin и Shop соответственно админ панели какой-то магазин и Host - это будет Как раз вот тот самый entry Point вот тот контейнер который будет в себя другие микрофронтенды как бы включать теперь даём пакеты Первое - это Share там будет находиться весь переиспользовать в первой половине курса тот самый VP config который мы разрабатывали и сейчас я предлагаю вот эти все файлы которые находятся у нас в папке Build старого проекта скопировать и перенести их вот сюда в Build config и вот эту папку Build которую я скопировал корневую Давайте переименую просто в src То есть это у нас такой полноценный отдельный проект можно считать и у него даже будет свой отдельный package Son то есть этот проект он по сути Независимый Давайте вот прямо под каждый проект у нас отдельная вкладка в терминале будет чтобы не путаться перейдём в папку packages и откроем Build config и здесь же сразу же проинициализирован PM init - Y у нас появляется здесь package Son сейчас скрипт пока что удалим и также предлагаю в проекте сделать файл Index TS из которого мы всё необходимое будем наружу отдавать своего рода такой entry Point Public этого модуля этого пакета и как раз путь до этого файла мы указываем как Main в package Son вот здесь вот указываем точка src Main TS вернее ИК TS вот лишнее тоже Давайте удалим оно как бы в продакшене не лишнее но нам оно сейчас не нужно для того чтобы дальше кодить теперь нам нужно перенести все зависимости которые мы в ходе курса устанавливали Давайте их прямо вот так целиком скопирую и сюда добавим единственное вот эти dependency Production dependency нам здесь не нужны потому что у нас здесь только сборка вы паков ся так Давайте ещё посмотрим чтобы лишнего ничего не было Нана Да вот types react react дом Вот эти два можно удалить ну в принципе остальное наверное можно оставить вроде ничего лишнего Нет ещё предлагаю чтобы нас тайп скриптовые ошибки не мучили в ходе курса Кстати да вот тут он ругается надо модули сами установить Чуть позже это сделаем чтобы typescript нас пока что сейчас в ходе разработки не мучил Я предлагаю вот этот вот Fork TS Checker V Pack plin пока что закомментировать мы уже посмотрели как он работает вот и в Build loaders предлагаю вернуть TS Loader А B Loader пока что заморозить то есть Test Loader у нас и так сейчас типа там не проверяет потому что transpile Only у нас стоит в True и пока что будем использовать Test Loader Ну и теперь Остаётся только модули которые мы в Def dependency добавили установить Обратите внимание что npm Install я делаю из корня то есть не конкретно из папки Build config А из корня моно репозитория Таким образом он установит все пакеты для всех ваших воркспейс и также самое важное Обратите внимание что папка node modules после установки из корня море появилась у нас не в папке Build Config для которой мы фактически эти модули устанавливали Она появилась в корне То есть если у нас например три пакета используют одни и те же зависимости они не будут в каждом пакете дублировать они единожды вынесут в корень этого манорен node modules это вот особенность работы воркспейс преимущество даже я бы сказал работы воркспейс так двигаемся дальше тайпскрипт у нас по-прежнему здесь ругается на модуле если мы обратим на это внимание это всё связано с тем что у нас нет тес конфига вот тес конфиг придётся здесь создать Но чуть позже мы тоже посмотрим как сделать один TS конфиг грубо говоря на весь проект и просто его расширять СТ config добавляем здесь в принципе все настройки нас устраивают Давайте единственно вот эти лишние комментарии по удаляем просто чтобы они не нагромождать саму конфигурацию Хотя вот этот Base URL и пас можно убрать потому что внутри у нас там абсолютных импортом и не нужны вот этот TS Note тоже уберём мы его добавим в итоговые проекты единствен нужно будет добавить опцию composit True для того чтобы все вот эти вот наши манорен настройки в конце концов работали полноценно потому что мы будем указывать потом референсы с одного проекта на другой чтобы typescript работал у нас корректно Так здесь у нас вроде всё хорошо проблем нет первый пакет мы сделали Единственное что нам здесь осталось - это указать name который мы будем использовать для импорта чего-то из этого пакета обычно указывают что-то типа вот такого используется знак собаки потом название например мано репозитория или папки в которой этот пакет находится в нашем случае это packages и затем название самого пакета всё в принципе мы настроили Теперь давайте настроим ещё один пакет В нём сделаем какую-нибудь простейшую функцию и посмотрим как мы с этим вообще будем работать вот только сейчас у вас у тех кто не работал с этим ранее начнёт появляться понимание для чего вообще всё это нужно и как это использовать здесь будет обычная функция которая складывает А + B но нам этого достаточно для того чтобы эту функцию в каком-то другом проекте за использовать опять же создаём отдельную вкладку в терминале переходим в папку Share it инициализирует для нас командой пакет npm init Y здесь должен появиться Pack Son также предлагаю Test config тоже сразу скопировать опять же как я уже сказал мы научимся Test config позже расширять всё это покажу расскажу наглядно посмотрим Ну и указываем название пакета лишнее также удаляем Main заменяем На ИК TS - это главный наш файл description тоже удаляем лишнюю запитую удаляем и всё базовый пакет готов делается это максимально быстро максимально Просто теперь Давайте попробуем вот эту функцию сам использовать в каком-нибудь сервисе Пусть это будет хост опять также создаём src ИК TS и тоже В отдельной вкладке в терминале всё это дело инициализирует вкладку пишем здесь хост мы много пакетов и сервисов сейчас создаём поэтому какие-то действия дублируются Но единожды это настроив потом к этому возвращаться уже не придётся так единственное написал npm Install надо было написать npm ждём пока у нас появится P вот он появился Да и сейчас ключевой момент здесь мы должны обозначить С какими пейсами Мы хотим работать это максимально просто по сути мы указываем dependency это обычные dependency Когда вы устанавливаете какую-нибудь там библиотеку или ещё что-то но здесь в качестве названия указывается как раз тот workspace который вы хотите в этом проекте использовать в нашем случае это workspace shared из packages и также Build config в качестве версии указываем звёздочку Это значит что нам подходит любая версия ещё раз обращаю внимание на то что в качестве названия мы указываем name из Pack Son которы ВС базовая настройка КСВ готова И теперь мы можем использовать пакеты внутри наших сервисов Давайте посмотрим как это работает единственно поскольку мы здесь используем рипт он нам также понадобится предлагаю IG скопировать из старого проекта он здесь максимально правильно у нас настроен под сервис Да вот в таком вот виде опять же комментарий удалим чтобы это нам глаза не моз вот ну и в остальном вро бы навы вз попробуем импортировать наш пакет Как видите авто compete сразу подхватывает Share Build config и также он подхватывает функцию которую мы оттуда экспортировали Давайте попробуем вывести в логе результат работы этой функции единственное с помощью обычной ноды нам не получится этот Файлик сейчас запустить Давайте воспользуемся тсц да единственное я путь неправильно указал нам надо было указать путь до папки src я сразу указал до индекс файла Т SR ИК запускаем видим что у нас сбился JavaScript фай и в нём как раз у нас вызов функции SH вот так вот это реализовано с помощью обычный ипор J Нам сейчас не нужен Давайте его удалим основная суть в чём в том что мы локальные Вот Эти пакеты используем по сути как npm модули но при этом мы не мся с версионирование с публикацией этих пакетов они все находятся у репозитории но при этом каждый пакет каждый сервис ВС равно остатся такой независимой переиспользовать в разных сервисах и сейчас предлагаю настроить react и уже посмотреть на это всё на практике прямо вот целиком вот это вот всё можно в принципе отсюда скопировать из старого нашего проекта Ну за исключением разве что асетов они нам там не нужны по всем этим файлика Давайте пройдёмся сейчас вставим их здесь и всё лишнее по удаляем чтобы у нас вот максимально Чистый лист был так здесь в принципе всё норм это пока что оставим здесь сейчас тоже много красного Но это у нас не настроено пока что всё сейчас мы это всё сделаем но лишнее поудалял удаляем Вот это всё удаляем ну страницу about пока что можно оставить Хотя нет тоже Давайте удалим просто сделаем заголовок и напишем здесь что-нибудь хотя бы внутри просто чтобы убедиться что у нас ре приложение работает так Теперь для этого проекта Нам необходимо все зависимости установить react react дом все типы опять же копируем их из старого проекта и вставляем в наш новый Pack Son единственно вот эти вот нужно добавить в уже существующий раздел Да вот это точ дубликат удаляем так вот он подсвечивает зависимости которые у нас не установлены устанавливаем их и опять же Обратите внимание что у нас не появляются НОД модули в папке Host они у нас на самом верхнем уровне в корне моно репозитория так здесь Как видите все ошибки исчезли так единственно для того чтобы это всё запустить Нам сейчас нужно будет скрипты перенести в Pack Son тоже которые мы делали Давайте старый проект откроем и вот эти скрипты прям целиком все скору они нам ещ пригодятся и добавляем их в новый P так Отлично Теперь нам понадобится vack config добавляем его сюда в корень и здесь мы будем использовать Build webpack уже не из локального проекта а будем импортировать его из нашего морея из нашего пакета Build config Но предварительно вот отсюда из инкс файла Давайте его экспортируем нам понадобится Build webpack и также нам понадобятся типы всё остальное инкапсулировать теперь импортировать импортируем из нашего пакета опять же если раньше мы использовали это локально м одного Монолита то сейчас мы это ВС подтягиваем из нашего пакета и по сути ВС наш config готов Обратите внимание как мы переиспользование декомпозировать переиспользовать в админке и в нашем магазине в папке SH так единственно пока что вижу что всё равно файлы красным подсвечиваются вот эти пу может най пото да яде сделать прямо в корень папки вывалил все файлы components pages А у нас там в тест конфиге относительно папки src всё это настроено и также ещё папку па мы забыли Давайте её отсюда скопирую и перенесём в наш новый проект и также сделаем срц и вот как раз вот эти вот компоненты страницы Index Test Global Test переносим туда то есть это у нас прям такой отдельный проект можно счи самостоятельно так вроде сейчас все проблемы ушли Здесь тоже всё хорошо Ну и Давайте Теперь попробуем Этот проект запустить npm Run Start и Как видите сборка прошла успешно видим наше приложение на трём порту Давайте ещё вот ссылочки до этих страниц добавим Да about и Shop они нам позже пригодятся так здесь указываем about и делаем такую же ссылочку для шопа единственно разделитель здесь добавим чтобы ссылки Не слипались и не забываем алет чтобы страницы у нас отрисовывать да Единственное у нас там много хлама всякого осталось когда мы размер бандла тестировали не почистили Давайте здесь просто укажем название страниц about и здесь укажем Shop тоже лишнее удаляем Угу Ну и Давайте теперь убедимся что всё это работает Ну да страницы переключаются Нет не переключаются что-то мы не так указали Давайте вернёмся Да вот здесь я ссылочку не поменял да вот теперь всё хорошо страницы переключаются реак приложения у нас работает максимально быстро за счёт декомпозировать в рамках хаста необходимо переместить в SH и в админ ноно потом мы их чуть-чуть модернизируем чтобы это у нас прям получились отдельные приложение Так давайте начнём с админа первое что мы сделаем это так здесь у нас по идее всё одинаковое здесь в принципе тоже вот в P название стоит поменять здесь у нас будет админ зависимости все те же но они могут быть и разные в принципе Здесь тоже меняем название в P и что я предлагаю У нас сейчас есть две папочки about и Shop Вот здесь мы удаляем так это мы пока оставим тоже удаляем А вот SH пока что оставим А вот из админки мы как раз наоборот вот этот вот SH удалим а оставим То есть это у нас вот можно Ну представим что это у нас прям полноценные отдельные приложения со своими страницами со своей бизнес логикой А вот в Хосте мы теперь вообще обе эти страницы удалим и подключать мы их будем как раз как отдельные будем использовать вот единственно вот эти вот чины Мы отсюда удалим из роутера и позже как раз мы их туда добавим то есть вот это приложение у нас будет как обёртка для перехода на на конкретные микросервисы то есть будет Вот как раз по адресу about по адресу SH у нас доступны разные это будут не микро фронты это будут монолиты который просто разделён на разные папки в папке Services это не будет микрофронтенд Вот хост контейнер они подключались по какому-то вот урлу как независимые приложения Нам необходимо будет дополнительно настроить webpack те те самые module Federation о которых я говорил обычно в корне проекта создают Файлик bootstrap который является энтри понтом то есть по сути он сейчас как вот ИК TS файл у нас а ИК TS файл как раз вот этот вот Сам он делает ленивый импорт вот этого bootstrap файла то есть приложение у нас грубо говоря будет лениво подгружать вот в этот хост контейнер также в документации ещё добавляют вот этот вот экспорт Наверное это нужно для typescript The elated modules особо не разбирался зачем они так сделали но Давайте двигаться дальше сейчас вот такую вот махинации с Index TS и bootstrap нам необходимо будет проделать везде опять если сейчас вам не понятно досмотрите до результата увидите что у нас В итоге получится и вернитесь и пересмотрите заново потому что как бы не представляя Конечный результат сейчас действительно может быть непонятно что мы делаем и для чего Но чуть позже это всё должно проясниться по сути саму мореп мы настроили И сейчас мы настраиваем уже микро фронты bootstrap Файлик сделали идек tsx Файлик сделали и теперь мы делаем уже реакторс какие-то изменения Я предлагаю вот этот вот роутер в котором мы ка страни у нас в приложении по какому маршруту они располагаются вынести в отдельный Файлик именно этот Файлик мы будем подключать в хост контейнер вот это вот всё отсюда выносим добавляем сюда сам роутер наружу мы экспортируем А вот сюда мы его импортируем так ну и лишнее отсюда можно поудалял обратно к роутеру и вот этот вот массив с настройками Мы вынесем в отдельный объект Ну назовём его Roads например в рамках этого приложения мы передаём его в Create brower router А наружу делаем дефолтный экспорт именно с помощью этого дефолтном будем эти роуты подключать в наш хост контейнер опять же чуть позже поймёте для чего и почему мы это делаем теперь то же самое делаем в админке создаём здесь роутер внутри создаём Файлик под этот роутер то есть опять же сейчас у нас в этом роутере только одна страница но в будущем там может быть их много с какими-то вложенными ротами с вложенными маршрутами с большим количеством всяких компонентов вот здесь в принципе Делаем всё тоже самое И наружу через дефолтный экспорт отдаём сюда лишне тоже удаляем и на этом по сути всё с админкой и с магазином мы разобрались эти два отдельных проекта даём Файлик вот этот вот браузер роутер мы выносим туда здесь мы уже ничего выносить отдельно не будем единственное экспортируем этот роутер чтобы в bootstrap файлики его добавить лишнее тоже удаляем Вот и теперь Наша задача в чилдрен нашего вот этого роутера добавлять дочерние приложения сюда добавляем например Shop Roads и Admin Roads и вот в таком формате мы как бы с этими приложениями будем работать то есть они будут частью навигации нашего вот этого корневого проекта здесь вот стоит немного притормозить мы сейчас пошли по пути того что мы внедряем как бы вот в этот хост контейнер просто роутеры Но на самом деле туда можно внедрять всё что угодно можно внедрять какие-то корневые компоненты которые внутри себя всё необходимое и весь роутинг и весь функционал все лейауты содержат либо можно внедрять какие-то отдельные страницы в общем здесь как вашей душе угодно здесь какого-то строгого правила Нет я лишь показываю вам пример И сейчас мы на примере вот этого роутинг и нам необходимо подготовить все настройки которые позволят нам вот эти Mod Federation использовать и внедрять приложение вот этот хост контейнер Mod Federation настраивается через плагин Давайте наш config дефолтный расширим в каждом сервисе отдельно плагин этот находится по умолчанию vacciner module Federation plin для самих сервисов и для хост контейнера настройки немного будут отличаться Как видите настроек здесь не так уж и много и давайте я сейчас заранее подготовленный конфиг уже вставлю в нём Там абсолютно ничего непонятного нет и прямо по пунктам пройдёмся и прежде чем приступать к разбору самого конфига Давайте импортируем сюда Pack G Son потому что нам понадобится оттуда забрать зависимости P From прямо сам Файлик P импортируем и чтобы typescript мог этот Файлик завить необходимо добавить вот такую вот опцию нам прямо ошибка сама подсказывает в Test config и называется она resolve Jon Mod просто ставим значение True и Давайте во всех сервисах эту опцию добавим добавил здесь она не нужна это P нам надо именно в сервисы добавляем вот сюда в админ панель и в Shop так в T config и вот здесь добавляем Да теперь мы можем спокойно импортировать J файлы Как видите ошибка ушла и теперь вот это P мы разворачиваем вот здесь единственно здесь Давайте с маленькой буквы сам файл назовём Вот теперь давайте пройм по настройкам единственное я вот эту настройку не туда добавил Это изначально настройка подразумевалось для Shop Давайте начнём с неё сюда также package Son импортируем Вот и теперь давайте смотреть на сам config первая настройка - это name грубо говоря название самого микро фронтенда далее указывается название файла которая вот грубо говоря будет удалённо подключаться Вот в этот вот хост контейнер обычно его называ называют по умолчанию всегда Remote entry tojs двигаемся по настройкам дальше exposes - это наверное самая важная опция здесь мы указываем что мы хотим предоставить приложению контейнеру в нашем случае наружу грубо говоря мы отдаём наш роутер Это как раз вот та часть приложения которую мы будем внедрять в хост контейнер единственное здесь вот с другого проекта копировал вот этот components у нас не существует здесь у нас сразу идёт роутер папка и внутри роутер tsx поэтому путь немного изменяем Вот и остаётся последний блок - Это shared здесь мы указываем Какие библиотеки у нас общие и какие библиотеки должны шариться здесь Также можно указать требуемую версию для реакта react Router dom и react до мы указываем IG значение True И это говорит нам о том что эту библиотеку необходимо будет как бы подгрузить сразу то есть есть вот Lazy loing отложенная загрузка А вот это как бы противоположность Lazy Лонга значит что она нам нужна не немедленно в принципе здесь можно было Просто оставить package Son dependency но основные как бы зависимости важные лучше выносить вот так отдельно и как бы указывая конкретные версии с package Son на самом деле здесь можно тоже чуть дальше пойти и можно сделать вот это вот webpack module config общий какой-то тоже создать отдельный Файлик для него куда-то вынести какие-то базовые настройки зафиксировать версии библиотек опять же вот как я говорю всё можно декомпозировать куда-то выносить Можно опять на уровень Билд конфига вынести можно на уровень каждого сервиса какие-то специфичные настройки вынести но тут особое пока что необходимости Я в этом не вижу здесь можно в принципе вот этот вот конфиг продублировать потому что в принципе в сервисах он может отличаться и какой-то дублирование кода оно в принципе нормально Ничего страшного в этом нет Теперь давайте такой же конфиг настроим для нашей админки Ир копируем здесь добавляем и что здесь надо исправить во-первых изменяем название файне у нас остаётся тем же путь до роутера У нас здесь в принципе такой же если бы он был какой-то другой или мы бы хотели какой-то другой файл наружу отдать опять же путь бы здесь необходимо было поменять но роутер у нас что там что там сделан по одному и тому же принципу поэтому здесь ничего не меняем опять же если бы нам наружу нужно было отдать несколько файлов мы бы просто их по порядочнейшего [музыка] немного отличаться давайте я опять же заранее подготовленные настройки вставлю и мы по ним пройдёмся чтобы сейчас всё это не переписывать так готово и Давайте прямо по пункти кам тоже пройдёмся опять же name F name здесь в принципе ничего не меняется shed здесь остаётся всё то же самое версии библиотек у нас фиксированный но Обратите внимание если здесь у нас был exposes то здесь у нас есть remes и здесь мы указываем путь до вот этих entry файлов которые мы указывали в самих сервисах вот здесь вот это всё указывалось F и название самого вот этого модуля но также здесь необходимо указать URL на котором крутится приложение То есть например Local Host 3000 и Local Host 3001 и соответственно в продакшене у нас эти адреса могут быть одни в деве могут быть другие То есть в де у нас Local Host с каким-то конкретным портом А в продакшене уже конкретный URL у нас будет и для того чтобы мы имели возможность эти адреса определять на одни в продакшене другие мы будем принимать эти адреса как N в переменное точно также как и любые другие гибкие настройки и также для этих переменных можно задать какие-нибудь дефолты Давайте создадим прямо отдельные константы будем присваивать им значение как раз N в переменных и в случае если в переменные не заданы то задам ttp Local Host Ну и Давайте здесь определим что например Shop у нас будет крутиться на Local Host 3001 а админ на Local Host 3002 и вот эти вот константы которые мы здесь объявили уже используем Mod Federation единственное вот здесь Давайте сразу порт переодели здесь укажем 31 в Shop А в админ укажем 32 то есть вот опять же за счёт того что мы вот эти опции прокиды мы легко порт можем переопределить для каждого сервиса указываем свой а сам хост контейнер у нас будет крутиться на тысячном порту вот в принципе ничего сложного если на эти конфиги посмотреть они выглядят максимально просто ничего там Сверхъестественного нет отдаём что-то наружу а в Хосте это как раз подключаем Ну и Давайте теперь запустим каждый сервис по отдельности запускаем админку запускаем Shop переходим в папку Services Shop тут тоже делаем npm Start видим что приложение запустило на 3002 порту и SH на 3001 единственное вот здесь вот нам сейчас корневой компонент немного надо будет поправить Давайте здесь напишем прям конкретное название сервиса Shop module вот эти ссылки уберём они у нас в сте будут находиться алет оставим ID тоже можно убрать чтоб не мозоли в глаза и в админке делаем тоже самое здесь напишем Admin module ссылочки убираем Outlet оставляем Data Test ID тоже удаляем так обновим здесь страничку И здесь тоже видим Shop module Admin module отлично Два независимых приложения крутятся на разных портах здесь пока что всё хорошо спом и админкой разобрались Теперь давайте разберёмся с контейнером его мы будем запускать отдельно но пока что запускать Рано ведь мы ещё не указали роутеры которые мы хотим внедрить в наше приложение вот эти две строчки пора раскомментировать Они уже готовы к работе и остаётся теперь из вот этих вот наших модулей в хост контейнер внедрить Shop и Admin Ro и как это делается делается это с помощью обычных импортом указываем указываем название модуля и затем фай кото м импортировать Давайте откроем прямо config то есть вот здесь мы указывали name и expose то есть указываем вот этот вот name и файл который хотим импортировать То есть если бы вот здесь было какое-то отлично от роутера название мы бы при импорте указали Именно его единственный момент что сейчас typescript ругается но это не удивительно потому что typescript про этот модуль ничего не знает мы его настроили только впаке точно такой же импорт Ротов Делаем из админки теперь и пока что давайте добавим здесь просто TS ignore чтобы убедиться что у нас всё заработает а чуть позже ещё саму тайп скрипто вю ошибку тоже поправим Давайте наш хост Перезагрузи админку и магазин перезагружать смысла нет Там мы ничего не меняли при этом Как видите приложение у нас загрузилось на трёх сся порту видим что у нас отрисовать Shop модуль если мы сейчас заглянем в логи то мы увидим что у нас подключены как бы External модули на 3000 первом порту и на 3.000 втором порту то есть настроили в этом месте мы всё правильно И если мы сейчас потыкать что у нас как раз подгружается SH модуль и админ модуль То есть это вообще сторонние приложения которые крутятся в рамках одного общего приложения и Как видите мы можем их запускать как вместе так и независимо чтобы В терминалах ещё не путаться вот это вот последней это у нас SH Давайте его тоже переименую вот предлагаю ещё добавить какие-нибудь изменения на страницу посмотреть как вообще наше приложение на это всё отреагирует Давайте какой-нибудь div добавим Ну и здесь просто 1 2 3 не столь важно и как можно заметить в терминале хост у нас при этом не пересобрать у нас только конечное приложение в которое мы вносим изменения то есть видите Да вот тут вот ребилд происходит на каждую правку а хост при этом остаётся статичным вот обновляем страницу видим что у нас изменения также доехали то есть в этом плане всё работает хорошо Ну и Давайте посмотрим как это работает на самом деле в Нетворк обновляем страницу так Давайте ещё раз очистим ещё раз обновим и прямо поэтапно пойдём Ну и вот тут сразу можно заметить два reme entry JS и видим как подгрузило один из роутеров давайте сейчас вот это вот всё очистим и попробуем переключиться на другую страницу видим как она у нас лениво подгрузило обновим ещё раз страницу и заглянем внутрь этих файлив видим что у нас в одном случае warsh в другом AD Ну то есть файлы сами по себе отличаются Ну и предлагаю ещ эти роутеры которые мы делали немного до тюнить чтобы они вот прям за отдельные куски приложения отвечали здесь вот прям можно для каждого из них на корневой ро указать прямо отдельно SH А здесь например й страница и Давайте ещё какую-нибудь вторую создадим Давайте особо думать прям не будем над названием просто сделаем внут добавим какой-нибудь с красным шрифтом Ну и просто какой-нибудь текст туда добавим не столь важно вот просто чтобы у нас в самом вот магазине две вложенные страницы было и мы посмотрели что всё действительно у нас работает правильно единственное вот здесь вот ссылки нужно будет немного поправить здесь будем на вести Давайте глянем обновим страничку Так что-то у нас ВС перестало загружаться Давайте глянем Да из-за того что у нас вложенный маршрут нам надо было там вот часть пути вот эту вот SH продублировать то есть вот здесь не просто Main а SH Main потому что это дочерние роуты вот так вот сейчас всё должно заработать обновляем страничку Ну да видим что сразу всё загрузилось видим что у нас подгружается страница При этом если мы сейчас заменим участок ла Ну и по ошибке в логах можно заметить проблему что у нас Чан пытается подгрузить по маршруту Shop SL Main и мы на самом деле такую проблему уже решали помните когда мы добавляли hist fallback в Def север то есть из-за того что у нас Single page Application из-за того что у нас все вот эти вот чанки бандлы они лежат на Верхнем уровне нам нужно их заправа запрашивать не через Slash Shop а напрямую SL Main то есть С корня папки это на самом деле тоже легко исправляется то есть в рамках одного приложения оно у нас с history PB работало Нормально А как видите мы настроили вот эти микрофронтенд мы увидим что у нас чанк просто Не подгружается он запрашивается не по тому пути на самом деле Нам необходимо просто поправить HTML плагин Так давайте откроем Build plugins вот он HTML пги Давайте немного его отформатирую чтобы получше читалось и здесь необходимо добавить это как раз то откуда будет Вот эта статика запрашивать грубо говоря давай теперь все эти три приложения пере запустим на самом деле можно сделать общий скрипт который будет запускать всё одновременно в корневом вот в этом вот сделать Старт через какой-нибудь concurrent который умеет параллели просто взять и все три проекта запустить Вот давайте сейчас попробуем обновить страничку перей Ну и видите по статика запрашивается по правильному урлу Теперь давайте вообще посмотрим Для чего нам вот эта вся манаре нужна Теперь мы можем в Share создавать какие-то файлы папки функции константы в общем всё-всё-всё что может переиспользовать в разных сервисах и поскольку у нас может быть такое что один сервис может вести в другой из-за того что ссылки могут находиться где-то в каких-то компонентах сайдбаре хедере ещё где-то по-хорошему вот эти вот ссылки хранить где-то отдельно и вот мы можем создать на уровне shed пакета какие-нибудь константы отдельно для каждого сервиса которые будут эти ссылки содержать получается в ротах для шопа У нас два рота это и Second соответственно вот так вот их указываем и для админки у нас одна страничка about теперь внутри хост контейнера либо внутри самих сервисов мы эти ссылки можем использовать импортируем их как обычные константы таким вот образом Roads Admin Road Shop импортируем нужные константы Shops Admin Roads и теперь вот здесь их используем единственно Да вот здесь вот не about Road Admin Ro уже ошибаюсь тяжело столько записывать так здесь Ну теперь их используем таким образом если у нас по какой-то причине ссылка поменяется мы её поправим потом в одном месте Вот в этой вот константе и оно сразу во всех сервисах автоматически поменяется так здесь ссылки поправили теперь поправим эти ссылки внутри самого приложения вот здесь вот можно сделать ссылку которая будет вести Как раз на Ну и Давайте посмотрим как это работает опять же Это просто пример того как мы код из пакетов переиспользовать что я пропустил там в ссылке Shop здесь Давайте добавим чтоб ул у нас соответствовал А здесь можно Амин Кстати мы это в админке вообще не сделали Давайте сразу сделаем Да вот здесь вот админ чтобы у нас как бы сервис за конкретным урловской была для каждого сервиса в этом плане Так ну и сейчас всё должно работать переходим на about Да здесь админ переходим на се ну как видите Да все ссылки Работают но теперь они как бы у нас вынесены отдельно и с одного сервиса на другой у нас ссылки спокойно могут вести Ну ссылками на самом деле пример может не очень удачны на самом деле вот в этом shed пакете может лежать всё что угодно какие-то переиспользовать по типу там я не знаю объединение двух массивов глубокий Ёрш какое-нибудь там копирование объектов копирование массивов сортировка какая-нибудь там особая хитрая и всё это вот таким вот образом в сервисах используется мы просто импортируем как будто бы из какой-то внешней библиотеки из какого-то npm пакета Но на самом деле просто Эти пакеты лежат не где-то там в npm удалённо Они лежат прямо в нашей манорен вот образом импортируем и уже внутрь компонента или каких-то там хелпера тоже используем опять же в любом из сервисов и также Вот в этом shed пакете могут лежать какие-то переиспользовать какой-нибудь хедер модальное окно с оплатой например Ну давайте какой-нибудь такой сейчас компонент переиспользовать юзернейм пользователя и мы его здесь просто выводить будем давайте опциональный сделаем его если юзернейм не передан будем писать просто юзер Ну и для примера тоже чтобы чуть-чуть компонент у нас по объёмнее выглядел Давайте вот так вот пароль ещё напишем Ну и какие-нибудь ещ стили добавим рамку сдела и динги так Отлично Теперь давайте этот компонент в сервисах за используем Давайте начнём с магазина где-нибудь вот здесь под ссылкой можно добавить хотя у нас есть вот эта вот секон страница можно прямо на неё добавить а то она у нас сейчас пустая прямо Вот здесь Давайте добавим какой-нибудь заголовок и сюда как раз вот дом Как видите у нас даже А подхватывает этот компонент и из пакета его импортирует автоматически Ну и здесь напишем From SH Да импорт у нас сработал всё хорошо Теперь давайте тоже самое добавим в админку прямо Вот здесь добавим но напишем From Admin сохраняем открываем обновляем страницу видим что открываем админку видим From Admin Итого Делаем выводы какие-то общие компоненты которые от сервиса к сервису [музыка] разобрались Давайте теперь поговорим про тест конфиги Я обещал что мы научимся их также расширять потому что у нас сейчас по сути Ctrl C Ctrl V во всех этих конфигах очень много повторяющихся моментов Ну и на самом деле Здесь тоже ничего сложного нет Эти конфиги очень легко расширяются Давайте создадим на уровне сервисов отдельный tsconfig назовём его tsconfig. base.js То есть это будет базовый config который в каждом сервисе мы уже будем расширять и какие-то свойства специфичные для каждого сервиса будем добавлять то есть вот сюда мы выносим ВС это дело давайте сейчас де серверы все Постав так Ну и что мы теперь делаем вот это вот всё дублирование кода мы можем поудалял также как и папка куда собирается у Насри Поэтому вот этичные сервиса моменты мы оставляем внутри каждого ТС конфига А всё что общее Мы выносим в Base config и затем мы делаем extends и указываем путь до базового конфига То есть за счёт вот этого свойства у нас как бы будет расширяться этот конфиг и дублируем это во все сервисы в Host и в админ опять же получаем преимущество от моно репозитория то что сборка webp TS config у нас всё это вынесено отдельно и Мы это можем переиспользовать от сервиса к сервису Ну как видите сборка Да у нас прошла успешно сейчас сервис у нас хорошо собрался без каких-либо ошибок можем убедиться даже что всё работает Ну да проблем никаких нет опять же можете заметить что SH у нас крутится на 3001 порту и если нам не надо разрабатывать админку или какой-то другой микросервис мы можем хост вообще не поднимать мы поднимаем отдельный микросервис кодим в него и как бы за счёт этого у нас достигается такая изоляция сервисов Но если нам надо поднять всё вместе посмотреть как в интеграции это работает мы поднимаем админку поднимаем магазин поднимаем хост и всё это в купе уже в связке проверяем как вот это большое огромное приложение состоящее из микрофронтенд у нас работает в пакетах у нас хранится вся конфигурация storybook Just cyprus Play Right любые инструменты которые у вас есть опять же вот также выделяйте в отдельные конфигурационные функции файлы и всё это потом от сервиса к сервису пере используете И за счёт такого получится что развернуть какой-то Новый сервис развернуть какой-то новый микрофронтенд у вас вообще труда не составит потому что вся необходимая инфраструктура все необходимые конфигурационные файлы у вас уже есть просто делаете по аналогии с другими сервисами и всё у вас будет работать здесь вообще можно ещё дальше пойти и сделать какой-нибудь свой аналог Create react App который вот эти сервисы будет такой Аля генератор кода в который вы там пишете npm там Create Service и и он будет на основании ваших конфигов на основании вашей вот этой вот всей сборки будет всё это ну автоматически сервис разворачивать со всеми тест конфигами вебпак конфигами со всеми настройками и так далее каждый сервис за счёт того что у нас вот эта сборка переиспользование со своими путями со своими какими-то портами платформами и так далее можно тоже гибко настраивать на уровне входных каких-то параметров вот тест конфиги У нас тоже пере используемые То есть у нас нет дублирование в этом плане в сервисах находится специфичный код для этих сервисов какая-то бизнес-кард кой которая все эти сервисы внутри себя объединяет опять же вот здесь вот можно сделать какой-нибудь йу йу этот хранить где-нибудь в пдж опять же shed то есть леау из себя там представляет опять же какую-нибудь менюшку слева менюшку справа р футер а сам контент вот эти микросервисы они в этот леау будут встраиваться Ну и получается вот здесь у нас вместо вот этих вот ссылок вот этого всего будет леау который опять же мы из пакетов просто подтянули но опять же при этом важно помнить что хост контейнер вот этот у нас это всего лишь обёртка и здесь никакой бизнес логики никаких компонентов сложных никаких утилит хелперов по сути быть не должно это всего лишь обёртка которая объединяет в себя всё остальное ещё момент что для того чтобы запустить какую-то команду мы переходили в пр в папку конкретного сервиса Но на самом деле можно и из корня мореп их запускать есть вот такая вот команда Вы запускаете npm RST то есть указываете скрипт затем указываете workspace и он в рамках этого РК спейса скрипт будет запускать Ну единственно да Он сейчас говорит что порт Уже занят Давайте его сейчас остановим Ну и вот он админку запускает то есть делаем мы это из корнем на репозитория за сч того что мы указали workspace в котором мы хотим это запустить на самом деле там есть команда которая позволяет запускать скрипты сразу во всех Ворк спейсах вот так вот как-то это выглядит workspaces оно запустит сразу во всех Но единственное там да сейчас ошибки посыпались потому что в пакете shed Например у нас вообще команды Старт нет в Билд конфиге тоже её нет ну в общем это всё ещё понастроили чтобы у вас какой-то одной командой всё поднималось одной командой тесты для нужных сервисов прогоняли опять же можно пользоваться concurrent пакетом который позволяет параллели какие-то скрипты И вот так вот параллельно можно делать npm Старт для магазина для Хоста для для админки то есть вот здесь есть прям примеры как это всё работает указываете вот так вот по порядочную Если вы дошли до этого момента всё настроили разобрались поняли что я вам рассказывал уж сделать запуск всех проектов одновременно через concurrent для вас эта задача максимально простая и на этом друзья мы подходим к финалу такого большого фундаментального курса рассмотрели много всего и предлагаю текущий код отправить на github опять же давайте сделаем G ignore добавим сюда все необходимые директории проделываем уже знакомые для нас действия добавляем удалённый репозиторий индексирует делаем пуш убеждаемся что все файлы у нас успешно загрузились сервисы пакеты всё здесь вроде хорошо опять же все ссылочки будут в описании к этому всегда можно вернуться и на этом всё Друзья вот такое вот видео получилось если досмотрели До конца если видео было Полезно если оно вам понравилось очень надеюсь на вашу поддержку в виде лайков комментариев Вам не трудно займёт буквально пару минут а мне поможет с продвижением канала такие видео очень долго записывать даже Элементарно на то чтобы написать тайм-коды уходит 2-3 часа надо всё пересмотреть тайм-коды эти написать добавить их на YouTube В общем я думаю вы прекрасно понимаете что времени уходит много особенно совмещать с основной работой это всё тяжело но я стараюсь работаю на выходных работаю вечерами Ну и поэтому лайк и комментарий от вас обязательно жду Всем спасибо и также ещё е хочется добавить что у меня есть курс повышения квалификации в котором помимо вебпак разбираются архитектура оптимизации все виды тестов по пирамиде тестирования тайпскрипт виртуализация инфраструктура CD нормализация данных дебаг кольцевые зависимости рефакторинг автоматизированный код Shift различные линтер теры в том числе свои плагины самописный в общем всё-всё-всё что нужно для разработки и всё это в последовательной разработке одного большого Продакшен проекта для всех заинтересованных ссылочка будет в описании Ну и на этом всё друзья Всем спасибо всем пока