Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
MVP 2010, 2011
- Консалтинг
- Проектирование
- Разработка
- Обучение
MVP 2010, 2011
Динозавр осваивает Modern Web - Часть пятая
Запись от Артем Enot Грунин размещена 27.10.2017 в 13:32
Часть пятая - Как работает сборка?
Предыдущая статья серии: Динозавр осваивает Modern Web - Часть четвертая
В прошлой статье мы с вами успешно собрали и разместили в CRM наше первое приложение на React. Теперь осталось понять почему все так сложно и где там был сам реакт. В общем-то это нормальная реакция человека, который только начал во все это погружаться. Непривычные инструменты, новый синтаксис и идеология собьют с толку кого угодно. Но, не все так плохо. Давайте разбираться как все это работает!
Для это вернемся в студию и посмотрим из чего состоит наш проект. Начнем в порядке значимости - с файла package.json. Не путать с packages.config! У них похожи не только названия, но и назначения. packages.config - это список NuGet пакетов, которые используются в решении, а package.json - это, в некотором роде, конфигурация NPM (менеджера пакетов Node):
В корне этого файла описывается информация о нашем пакете на тот случай если мы захотим разместить его в NPM. Это, пожалуй, ключевое отличие от NuGet каждый проект - кандидат сдать утилитой в другом проекте. Далее, идут разделы dependencies, devDependencies и scripts:
Раздел dependencies - аналог Reference в .NET. Тут содержится перечень своих, или сторонних "библиотек", которые нужны для работы нашего приложения. В данном случае, количество зависимостей минимально - это библиотеки react и react-dom, которые всегда идут в паре. Насколько понял, их разделили, чтобы независимо развивать React Native - библиотеку для работы с мобильными приложениями. Здесь же мы видим библиотеку react-scripts-ts, которая, вообще-то инструмент разработки, а не библиотека, которую мы используем в своем решении, но разработчикам должно быть виднее. Видимо какие-то ее части нужны для работы приложения, которое компилируется по этому шаблону.
Раздел devDependencies похож на предыдущий, с той лишь разницей, что он содержит компоненты, которые не войдут в приложение, но используются как инструментарий для его создания. В данном случае мы видим несколько библиотек @types. Зачем они нужны мы разберем чуть позже. Если кратко, это некий аналог h. -(header) файлов в C/C++, но для TypeScript. Они добавляют недостающие описания типов для библиотек которые написаны на чистом JS, чтобы лучше работала подсветка синтаксиса, а компилятор TypeScript мог лучше отлеживать типы данных.
Раздел "scripts" отвечает за ту магию, которая выполняется командами start и build, а также теми, которые мы еще не использовали. Команда start является стандартной, поэтому может использоваться без инструкции run, а остальные должны использоваться с ней. Например:
Обратите внимание, что все команды выполняются при помощи инструмента react-scripts-ts. Именно он делает за нас всю работу по горячей загрузке обновленных файлов во время отладки и сборку готового решения по команде build.
Идем далее. Папка "node modules". Как нетрудно догадаться, сюда будут складываться все пакеты из разделов dependencies и devDependencies. Нужно отметить, что студия имеет встроенную поддержку NPM и сама умеет "читать" изменения в package.json. Если мы добавим какой-то модуль, он автоматически будет скачан и размещен в каталоге node modules. Важный момент! Версия Node, которая входит в состав студии может быть устаревшей. Это может приводить к проблемам при загрузке пакетов, или при запуске команд из окна студии.
Чтобы этого избежать, щелкните правой кнопкой на файле package.json и выберите Configure External Tools:
В открывшемся окне, нужно переместить PATH на верхнюю строчку:
Теперь студия будет использовать ту же версию Node, которую мы используем в консоли.
Следующие два файла, которые отвечают за конфигурацию решения - это tsconfig.json и tslint.json. Первый из них - файл конфига компилятора TypeScript. Он отсутствует в версии create-react-app c использованием Java Script. Второй - настройки другого специфичного инструмента - линтера. Изначально линт - это программа проверки исходных кодов для языка C на предмет типовых ошибок и корявых конструкций, типа if (a=1). Позже, линтерами стали называть весь класс подобных программ. В большинстве случаев, вы не будете изменять эти конфиги. Оба этих инструмента поддерживаются студией, так что все ошибки компиляции, или варнинги линтера вы увидите в консоли ошибок:
Все прочие элементы решения отвечают за его наполнение, а не настройку. Подробно назначение каждого из них описано в документации по create-react-app: https://github.com/facebookincubator...-configuration, так что я расскажу лишь о них лишь кратко. По концепции решения, все исполняемые файлы должны быть расположены в каталоге src. Именно там сборщик будет искать наши TypeScript файлы для компиляции. В папке public должны быть расположены статичные "асеты" проекта, такие как картинки, библиотеки, которые недоступны через NPM и пр. файлы, которые не нужно "компилировать". Так же, тут располагается шаблон стартовой страницы index.html над которым тоже поработает сборщик. В частности, в страницу автоматически будут добавлены ссылки на скомпилированные скрипты.
Давайте теперь посмотрим, как выглядит сам сборщик. Если вы пробовали что-то делать по мануалам из интернета, вы наверняка провели несколько увлекательных минут с настройкой вебпака, который мы пока что совершенно не касались. Что ж, самое время оценить тот колоссальный труд, который проделала команда разработки create-react-app, чтобы избавить нас от необходимости настраивать сборку от проекта к проекту.
Для этого, откроем консоль в корне решения и выполним
Эта операция необратима, о чем нас честно предупредят. Возможно вы захотите сохранить резервную копию проекта до ее выполнения.
В итоге мы увидим, что в наш проект добавилось много всего нового:
Изменился и package.json. В него добавилось много новых зависимостей, которые заботливо прятал от нас пакет react-scripts-ts. Изменилась и секция со скриптами. Мы по-прежнему можем выполнить build и start, но теперь вместо react-scripts-ts будут выполняться локальные скрипты в каталоге проекта.
Давайте теперь обновим каталог решения в Solution Explorer и перейдем в новый каталог "config" где находится сердце нашего сборщика - файл конфигурации webpack:
В одной из прошлых статей этой серии, мы выяснили, что сборка модерн веб приложений, как правило делается с использованием этого инструмента. Сразу скажу, что конфигурация не обязана быть такой монструозной. Чаще всего достаточно конфига на 5-10 строчек, но тут мы видим высший пилотаж! Почти 300 строк хитрой конфигурации, оптимизации и компоновки решения, на выходе из которой мы и получим наши уродливые имена файлов. Впрочем, теперь мы можем все изменить!
Давайте откроем webpack.config.prod.js и найдем в нем следующий фрагмент:
Загрузчики (loaders) - это элемент процесса сборки, который отвечает за выбор инструмента "компиляции" для каждого конкретного файла. Давайте уберем вхождение блока [hash:8] во всех загрузчиках, чтобы убрать хеши из имен файлов. Дополнительно придется поискать по ключевому слову hash, чтобы найти другие места конфига, где они могут использоваться, например:
const cssFilename = 'static/css/[name].[contenthash:8].css';
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
Так же следует закомментировать подключение плагина SWPrecacheWebpackPlugin, так как он, в любом случае не будет работать в CRM.
Если все было сделано правильно, мы получим приемлемый "статичный" билд:
Не забудьте убрать хэши из имен файлов в spkl.json, так как теперь мы в них не нуждаемся.
И вот мы, наконец, разобрались как создать, скомпилировать и опубликовать решение в CRM. Осталось понять кто такие React и TypeScript и чем они могут быть нам полезны. Об этом я расскажу в следующих статьях серии.
Предыдущая статья серии: Динозавр осваивает Modern Web - Часть четвертая
В прошлой статье мы с вами успешно собрали и разместили в CRM наше первое приложение на React. Теперь осталось понять почему все так сложно и где там был сам реакт. В общем-то это нормальная реакция человека, который только начал во все это погружаться. Непривычные инструменты, новый синтаксис и идеология собьют с толку кого угодно. Но, не все так плохо. Давайте разбираться как все это работает!
Для это вернемся в студию и посмотрим из чего состоит наш проект. Начнем в порядке значимости - с файла package.json. Не путать с packages.config! У них похожи не только названия, но и назначения. packages.config - это список NuGet пакетов, которые используются в решении, а package.json - это, в некотором роде, конфигурация NPM (менеджера пакетов Node):
В корне этого файла описывается информация о нашем пакете на тот случай если мы захотим разместить его в NPM. Это, пожалуй, ключевое отличие от NuGet каждый проект - кандидат сдать утилитой в другом проекте. Далее, идут разделы dependencies, devDependencies и scripts:
Раздел dependencies - аналог Reference в .NET. Тут содержится перечень своих, или сторонних "библиотек", которые нужны для работы нашего приложения. В данном случае, количество зависимостей минимально - это библиотеки react и react-dom, которые всегда идут в паре. Насколько понял, их разделили, чтобы независимо развивать React Native - библиотеку для работы с мобильными приложениями. Здесь же мы видим библиотеку react-scripts-ts, которая, вообще-то инструмент разработки, а не библиотека, которую мы используем в своем решении, но разработчикам должно быть виднее. Видимо какие-то ее части нужны для работы приложения, которое компилируется по этому шаблону.
Раздел devDependencies похож на предыдущий, с той лишь разницей, что он содержит компоненты, которые не войдут в приложение, но используются как инструментарий для его создания. В данном случае мы видим несколько библиотек @types. Зачем они нужны мы разберем чуть позже. Если кратко, это некий аналог h. -(header) файлов в C/C++, но для TypeScript. Они добавляют недостающие описания типов для библиотек которые написаны на чистом JS, чтобы лучше работала подсветка синтаксиса, а компилятор TypeScript мог лучше отлеживать типы данных.
Раздел "scripts" отвечает за ту магию, которая выполняется командами start и build, а также теми, которые мы еще не использовали. Команда start является стандартной, поэтому может использоваться без инструкции run, а остальные должны использоваться с ней. Например:
X++:
npm run test
Идем далее. Папка "node modules". Как нетрудно догадаться, сюда будут складываться все пакеты из разделов dependencies и devDependencies. Нужно отметить, что студия имеет встроенную поддержку NPM и сама умеет "читать" изменения в package.json. Если мы добавим какой-то модуль, он автоматически будет скачан и размещен в каталоге node modules. Важный момент! Версия Node, которая входит в состав студии может быть устаревшей. Это может приводить к проблемам при загрузке пакетов, или при запуске команд из окна студии.
Чтобы этого избежать, щелкните правой кнопкой на файле package.json и выберите Configure External Tools:
В открывшемся окне, нужно переместить PATH на верхнюю строчку:
Теперь студия будет использовать ту же версию Node, которую мы используем в консоли.
Следующие два файла, которые отвечают за конфигурацию решения - это tsconfig.json и tslint.json. Первый из них - файл конфига компилятора TypeScript. Он отсутствует в версии create-react-app c использованием Java Script. Второй - настройки другого специфичного инструмента - линтера. Изначально линт - это программа проверки исходных кодов для языка C на предмет типовых ошибок и корявых конструкций, типа if (a=1). Позже, линтерами стали называть весь класс подобных программ. В большинстве случаев, вы не будете изменять эти конфиги. Оба этих инструмента поддерживаются студией, так что все ошибки компиляции, или варнинги линтера вы увидите в консоли ошибок:
Все прочие элементы решения отвечают за его наполнение, а не настройку. Подробно назначение каждого из них описано в документации по create-react-app: https://github.com/facebookincubator...-configuration, так что я расскажу лишь о них лишь кратко. По концепции решения, все исполняемые файлы должны быть расположены в каталоге src. Именно там сборщик будет искать наши TypeScript файлы для компиляции. В папке public должны быть расположены статичные "асеты" проекта, такие как картинки, библиотеки, которые недоступны через NPM и пр. файлы, которые не нужно "компилировать". Так же, тут располагается шаблон стартовой страницы index.html над которым тоже поработает сборщик. В частности, в страницу автоматически будут добавлены ссылки на скомпилированные скрипты.
Давайте теперь посмотрим, как выглядит сам сборщик. Если вы пробовали что-то делать по мануалам из интернета, вы наверняка провели несколько увлекательных минут с настройкой вебпака, который мы пока что совершенно не касались. Что ж, самое время оценить тот колоссальный труд, который проделала команда разработки create-react-app, чтобы избавить нас от необходимости настраивать сборку от проекта к проекту.
Для этого, откроем консоль в корне решения и выполним
X++:
npm run eject
В итоге мы увидим, что в наш проект добавилось много всего нового:
Изменился и package.json. В него добавилось много новых зависимостей, которые заботливо прятал от нас пакет react-scripts-ts. Изменилась и секция со скриптами. Мы по-прежнему можем выполнить build и start, но теперь вместо react-scripts-ts будут выполняться локальные скрипты в каталоге проекта.
Давайте теперь обновим каталог решения в Solution Explorer и перейдем в новый каталог "config" где находится сердце нашего сборщика - файл конфигурации webpack:
В одной из прошлых статей этой серии, мы выяснили, что сборка модерн веб приложений, как правило делается с использованием этого инструмента. Сразу скажу, что конфигурация не обязана быть такой монструозной. Чаще всего достаточно конфига на 5-10 строчек, но тут мы видим высший пилотаж! Почти 300 строк хитрой конфигурации, оптимизации и компоновки решения, на выходе из которой мы и получим наши уродливые имена файлов. Впрочем, теперь мы можем все изменить!
Давайте откроем webpack.config.prod.js и найдем в нем следующий фрагмент:
Загрузчики (loaders) - это элемент процесса сборки, который отвечает за выбор инструмента "компиляции" для каждого конкретного файла. Давайте уберем вхождение блока [hash:8] во всех загрузчиках, чтобы убрать хеши из имен файлов. Дополнительно придется поискать по ключевому слову hash, чтобы найти другие места конфига, где они могут использоваться, например:
const cssFilename = 'static/css/[name].[contenthash:8].css';
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
Так же следует закомментировать подключение плагина SWPrecacheWebpackPlugin, так как он, в любом случае не будет работать в CRM.
Если все было сделано правильно, мы получим приемлемый "статичный" билд:
Не забудьте убрать хэши из имен файлов в spkl.json, так как теперь мы в них не нуждаемся.
И вот мы, наконец, разобрались как создать, скомпилировать и опубликовать решение в CRM. Осталось понять кто такие React и TypeScript и чем они могут быть нам полезны. Об этом я расскажу в следующих статьях серии.
Всего комментариев 0