Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:


MVP 2010, 2011
- Консалтинг
- Проектирование
- Разработка
- Обучение
MVP 2010, 2011
Динозавр осваивает Modern Web - Часть четвертая
Запись от Артем Enot Грунин размещена 18.10.2017 в 15:27
Обновил(-а) Артем Enot Грунин 27.10.2017 в 13:37
Обновил(-а) Артем Enot Грунин 27.10.2017 в 13:37
Часть четвертая - Практический пример
Предыдущая статья серии: Динозавр осваивает Modern Web - Часть третья
В прошлой статье мы определились с тем, что будем осваивать библиотеку React и писать на языке TypeScript. Вынужден признать, что я довольно нехило размазал теоретическую часть, но, думаю, это было оправданно. У меня еще свежи воспоминания, о том, как я начинал погружался в предметную область. Нет такого количества пива, которое могло бы облегчить мои муки в тот момент. Мне тогда страшно хотелось убивать авторов всех статей, которые я читаю, так как ни одна не давала ответ на вопрос: "Где здесь находится ебаный Build, который выложит готовый сайт в папку Deploy". Так как эта серия статей рассчитана, в первую очередь, на таких же динозавров, как я, я уверен, что они мои старания оценят
Итак, приступим. В первую очередь скачаем и установим Node.js: https://nodejs.org/en/. Какая-то его версия входит в состав Visual Studio, но нам она подходит. Не нужно гнаться за новизной, нам подходит последняя стабильная версия. При установке, обязательно разрешите Node.js прописаться в переменной %PATH%.
Теперь запустите командную строку (не обязательно в папке, куда установили Node, достаточно просто cmd) и выполните команду
или
Вы должны увидеть номер установленной версии:

Это никак не пригодится нам в разработке, мы просто проверили что все работает.
Обратите внимание на каталог пользователя по умолчанию. Сюда менеджер пакетов будет сваливать все глобально устанавливаемые инструменты. Возможно, это поведение как-то можно изменить, но я никогда этим не заморачивался. Нужно отметить, что NuGet и .Net Core ведут себя в этом плане одинаково плохо.
Теперь откройте проводник перейдите в папку где живут ваши проекты. Пусть это будет C:\TempProjects. Теперь введите в строке адреса cmd и нажмите enter:

Вуаля! Консоль откроется в нужном каталоге и не нужно париться с >cd/
Теперь настал черед грязной магии. Скачаем через NPM утилиту, которая сгенерирует шаблон нашего будущего проекта:
Будьте готовы, что это займет некоторое время:

Флаг -g говорит о том, что инструмент нужно установить глобально. На практике это обозначает, что модуль будет скачан в каталог пользователя по умолчанию и будет доступен для запуска из любой папки. У глобальной установки есть противники, позже вы сами займете сторону.
Теперь не покидая нашу папку выполним создание проекта:
Первый параметр говорит, как назвать наш проект, второй - что мы будем использовать TypeScript в паре с React.
Опять же, эта процедура займет куда больше времени, чем потребовалось бы для создания проекта в Visual Studio. К слову, поэтому и существуют горячие поклонники альтернативных менеджеров пакетов, так как они могут выполнять эту задачу быстрее, и/или эффективнее.
В результате, в каталоге TempProjects будет создана папка crmreactapp с некоторым содержимым:

Теперь перейдем в каталог crmreactapp:
И выполним следующую магическую команду:
Откроется окно браузера, и вы увидите нечто подобное:

Самое время подключить студию!
Запустите VS и выберите открыть "Открыть веб сайт":

И выберите каталог C:\TempProjects\crmreactapp. В итоге, в Solution Explorer вы должны увидеть содержимое сайта, который создали:

Теперь, давайте попробуем сделать то, что советует нам наш сайт! Откройте файл App.ts в каталоге src и измените в нем что-нибудь (странный синтаксис мы обсудим позже)! Например, измените фразу Welcome to React на что-то свое и сохраните изменения:

Вы увидите, что уже через секунду браузер сам обновит страницу и вы увидите изменения:

Пока что я не показал вам ничего принципиально нового. Все это вы могли видеть в официальных мануалах Microsoft и Facebook которые я рекомендую вам потыкать, если вы все еще это не сделали, чтобы как-то освоиться:
https://github.com/Microsoft/TypeScript-React-Starter
https://reactjs.org/docs/installation.html
Теперь давайте остановим выполнение предыдущей команды через Clrl+C и запустим сборку решения:
Не забудьте указать ключевое слово run! В итоге вы должны увидеть что-то похожее:

А в каталоге сайта должна появиться папка build.
Ее содержимое чем-то похоже на структуру нашего проекта, но она содержит какие-то очень странные файлы и папки, типа main.9a0fe4f1.css и main.aad7ae77.js (имена ваших файлов могут отличаться). Это, собственно, результат сборки утилитой react-scripts-ts, которая установилась вместе с create-react-app. Позже мы разберемся как работает все это хозяйство и почему у файлов такие кривые имена.
Гораздо интереснее другое: попробуйте открыть в браузере файл C:\TempProjects\crmreactapp\build\index.html и увидите пустой экран. Если открыть консоль браузера мы увидим, что документ содержит ошибки:

Как же так, ведь нам обещали нормальный билд? Судя по всему, такие относительные пути будут корректно работать при запуске сайта под Node, хотя я не до конца понял логику разработчиков. Чтобы исправить ошибку, откройте файл package.json в корне сайта и добавьте строчку "homepage": ".":

Обратите внимание, что студия даже будет подсказывать нам параметры по мере набора! Однако не ведитесь на ее провокации. Точка - вполне себе корректная домашняя страница.
Повторно выполните сборку приложения (не в студии, через командную строку!). Не нужно удалять, или чистить каталог build - за нас его очистят автоматически.
Обновите окно браузера, и вы увидите, что теперь статичная страница корректно работает:

Самое время сохранить результаты наших трудов, чтобы они не пропали! В главном меню студии нажмите File - Save all, или просто нажмите Ctrl+Shift+S. Студия предложит вам сохранить файл решения (Solution). Очень важно, чтобы он находился в родительской папке решения! По умолчанию, студия может попытаться сохранить его в "Мои документы", или другом каталоге. В нашем случае, файл решения нужно поместить в папку TempProjects где размещен наш сайт. Если вы предпочитаете создавать директорию для решения - сделайте это сейчас.
Давайте теперь снова откроем отладчик и на этот раз перейдем в раздел со скриптами:

Боже, какой кошмар! Загрузится такое, конечно, быстро, но как это отлаживать? Не бойтесь, к нам на помощь спешат Code Maps! Эта технология позволяет браузеру сопоставить минимизированный/дотфуцированный код и оригинал. К счастью, ничего делать не нужно наш оригинальный TypeScript код находится в соседнем разделе:

Более того, его даже можно отлаживать!
Все что нам осталось - это правильно разместить полученные веб-ресурсы в CRM c сохранением всех виртуальных путей. Для этого, можно воспользоваться XrmToolbox и плагином Web Resource Manager, или попробовать автоматизировать эту операцию. Лично я предпочитаю второй подход.
Давайте так и сделаем. Зайдите в Tools - NuGet Package Manager и вызовите Package Manager Consloe

В открывшейся внизу консоли выполните
Это относительно новый замечательный инструмент от Scott Durow https://github.com/scottdurow/SparkleXrm/wiki/spkl
По сути, это альтернатива брошенному CRM Developer Toolkit выполненная на современный Modern Web лад. Иными словами, мы все будем делать привычным путем: через консоль и конфиги
После установки в каталоге с решением (вот для чего нужно, чтобы оно лежало рядом) будет создана папка packages, где помимо всего прочего, будет развернута утилита spkl. В самом решении будет создан ее файл конфигурации spkl.json (на остальные файлы пока внимание не обращаем).
В настоящий момент нас интересует раздел "webresources", который описывает параметры публикации ресурсов в CRM. Нам необходимо изменить его следующим образом:
• Параметр "root" должен указывать на папку "build"
• Параметр "solution" должен содержать уникальное имя решения, в которое производится публикация (иначе будет выбрано решение по умолчанию)
• Параметр "files" должен содержать путь ко всем необходимым файлам в папке build. Помимо ресурсов нашего приложения, build содержит различные манифесты, которые не нужны CRM. Их не нужно перечислять в этом списке
В результате, ваш spkl.json должен выглядеть похожим образом:
Обратите внимание на 2 вещи! Префикс издателя и имена файлов. В примере используется префикс по умолчанию: "new", не забудьте его изменить, если будете копировать конфиг. Вторая проблема: при сборке решения в оригинальное имя файла добавляется его хэш. В мире полноценной веб-разработки это очень даже здорово, так как не нужно париться насчет кэша браузера - имена файлов изменили, браузер пометит кэш как устаревший и обновит файлы. Нам такой подход, разумеется не подходит. Во-первых, так нам потребуется менять конфиг каждый раз после сборки (если изменился код, изменится и хэш), а во-вторых придется каждый раз удалять старые версии из CRM, что может быть сложно.
Тем не менее, для первого раза попробуем опубликовать как есть. Для этого, откроем каталог сайта, зайдем в каталог spkl и выполним в нем команду:
В данном случае, мы уже не используем NPM, это обычный батник, который разыщет утилиту spkl.exe и вызовет команду spkl webresources
Вам будут заданы стандартные вопросы по поиску вашего сервера и организации, после чего, если конфиг не содержит ошибок, решение будет опубликовано в CRM.
Чтобы проверить, что все работает, не обязательно вставлять страницу в какие-то фреймы и помещать на форму. Достаточно открыть index.html в редакторе веб ресурсов, или по прямой ссылке вида http(s)://crm-srv/OrgName/WebResources/prefix_/index.html?preview=1 - как вам будет удобно. Забавный момент: поддержка формата svg только недавно появилась в онлайн версии, так что если вы экспериментируете с онпремис, вы должны увидеть что-то подобное:

Итак, мы собрали и опубликовали в CRM наше первое реакт приложение. Вопросов должно было только прибавится: как это вообще работает, что делать с хэшами, что это вообще за синтаксис такой и так далее. Об этом я расскажу в следующих статьях серии:
Динозавр осваивает Modern Web - Часть пятая
Предыдущая статья серии: Динозавр осваивает Modern Web - Часть третья
В прошлой статье мы определились с тем, что будем осваивать библиотеку React и писать на языке TypeScript. Вынужден признать, что я довольно нехило размазал теоретическую часть, но, думаю, это было оправданно. У меня еще свежи воспоминания, о том, как я начинал погружался в предметную область. Нет такого количества пива, которое могло бы облегчить мои муки в тот момент. Мне тогда страшно хотелось убивать авторов всех статей, которые я читаю, так как ни одна не давала ответ на вопрос: "Где здесь находится ебаный Build, который выложит готовый сайт в папку Deploy". Так как эта серия статей рассчитана, в первую очередь, на таких же динозавров, как я, я уверен, что они мои старания оценят

Итак, приступим. В первую очередь скачаем и установим Node.js: https://nodejs.org/en/. Какая-то его версия входит в состав Visual Studio, но нам она подходит. Не нужно гнаться за новизной, нам подходит последняя стабильная версия. При установке, обязательно разрешите Node.js прописаться в переменной %PATH%.
Теперь запустите командную строку (не обязательно в папке, куда установили Node, достаточно просто cmd) и выполните команду
X++:
node -v
X++:
npm -v
Это никак не пригодится нам в разработке, мы просто проверили что все работает.
Обратите внимание на каталог пользователя по умолчанию. Сюда менеджер пакетов будет сваливать все глобально устанавливаемые инструменты. Возможно, это поведение как-то можно изменить, но я никогда этим не заморачивался. Нужно отметить, что NuGet и .Net Core ведут себя в этом плане одинаково плохо.
Теперь откройте проводник перейдите в папку где живут ваши проекты. Пусть это будет C:\TempProjects. Теперь введите в строке адреса cmd и нажмите enter:
Вуаля! Консоль откроется в нужном каталоге и не нужно париться с >cd/
Теперь настал черед грязной магии. Скачаем через NPM утилиту, которая сгенерирует шаблон нашего будущего проекта:
X++:
npm install -g create-react-app
Флаг -g говорит о том, что инструмент нужно установить глобально. На практике это обозначает, что модуль будет скачан в каталог пользователя по умолчанию и будет доступен для запуска из любой папки. У глобальной установки есть противники, позже вы сами займете сторону.
Теперь не покидая нашу папку выполним создание проекта:
X++:
create-react-app crmreactapp --scripts-version=react-scripts-ts
Опять же, эта процедура займет куда больше времени, чем потребовалось бы для создания проекта в Visual Studio. К слову, поэтому и существуют горячие поклонники альтернативных менеджеров пакетов, так как они могут выполнять эту задачу быстрее, и/или эффективнее.
В результате, в каталоге TempProjects будет создана папка crmreactapp с некоторым содержимым:
Теперь перейдем в каталог crmreactapp:
X++:
cd crmreactapp
X++:
npm start
Самое время подключить студию!
Запустите VS и выберите открыть "Открыть веб сайт":
И выберите каталог C:\TempProjects\crmreactapp. В итоге, в Solution Explorer вы должны увидеть содержимое сайта, который создали:
Теперь, давайте попробуем сделать то, что советует нам наш сайт! Откройте файл App.ts в каталоге src и измените в нем что-нибудь (странный синтаксис мы обсудим позже)! Например, измените фразу Welcome to React на что-то свое и сохраните изменения:
Вы увидите, что уже через секунду браузер сам обновит страницу и вы увидите изменения:
Пока что я не показал вам ничего принципиально нового. Все это вы могли видеть в официальных мануалах Microsoft и Facebook которые я рекомендую вам потыкать, если вы все еще это не сделали, чтобы как-то освоиться:
https://github.com/Microsoft/TypeScript-React-Starter
https://reactjs.org/docs/installation.html
Теперь давайте остановим выполнение предыдущей команды через Clrl+C и запустим сборку решения:
X++:
npm run build
А в каталоге сайта должна появиться папка build.
Ее содержимое чем-то похоже на структуру нашего проекта, но она содержит какие-то очень странные файлы и папки, типа main.9a0fe4f1.css и main.aad7ae77.js (имена ваших файлов могут отличаться). Это, собственно, результат сборки утилитой react-scripts-ts, которая установилась вместе с create-react-app. Позже мы разберемся как работает все это хозяйство и почему у файлов такие кривые имена.
Гораздо интереснее другое: попробуйте открыть в браузере файл C:\TempProjects\crmreactapp\build\index.html и увидите пустой экран. Если открыть консоль браузера мы увидим, что документ содержит ошибки:
Как же так, ведь нам обещали нормальный билд? Судя по всему, такие относительные пути будут корректно работать при запуске сайта под Node, хотя я не до конца понял логику разработчиков. Чтобы исправить ошибку, откройте файл package.json в корне сайта и добавьте строчку "homepage": ".":
Обратите внимание, что студия даже будет подсказывать нам параметры по мере набора! Однако не ведитесь на ее провокации. Точка - вполне себе корректная домашняя страница.
Повторно выполните сборку приложения (не в студии, через командную строку!). Не нужно удалять, или чистить каталог build - за нас его очистят автоматически.
Обновите окно браузера, и вы увидите, что теперь статичная страница корректно работает:
Самое время сохранить результаты наших трудов, чтобы они не пропали! В главном меню студии нажмите File - Save all, или просто нажмите Ctrl+Shift+S. Студия предложит вам сохранить файл решения (Solution). Очень важно, чтобы он находился в родительской папке решения! По умолчанию, студия может попытаться сохранить его в "Мои документы", или другом каталоге. В нашем случае, файл решения нужно поместить в папку TempProjects где размещен наш сайт. Если вы предпочитаете создавать директорию для решения - сделайте это сейчас.
Давайте теперь снова откроем отладчик и на этот раз перейдем в раздел со скриптами:
Боже, какой кошмар! Загрузится такое, конечно, быстро, но как это отлаживать? Не бойтесь, к нам на помощь спешат Code Maps! Эта технология позволяет браузеру сопоставить минимизированный/дотфуцированный код и оригинал. К счастью, ничего делать не нужно наш оригинальный TypeScript код находится в соседнем разделе:
Более того, его даже можно отлаживать!
Все что нам осталось - это правильно разместить полученные веб-ресурсы в CRM c сохранением всех виртуальных путей. Для этого, можно воспользоваться XrmToolbox и плагином Web Resource Manager, или попробовать автоматизировать эту операцию. Лично я предпочитаю второй подход.
Давайте так и сделаем. Зайдите в Tools - NuGet Package Manager и вызовите Package Manager Consloe
В открывшейся внизу консоли выполните
X++:
Install-Package spkl
По сути, это альтернатива брошенному CRM Developer Toolkit выполненная на современный Modern Web лад. Иными словами, мы все будем делать привычным путем: через консоль и конфиги

После установки в каталоге с решением (вот для чего нужно, чтобы оно лежало рядом) будет создана папка packages, где помимо всего прочего, будет развернута утилита spkl. В самом решении будет создан ее файл конфигурации spkl.json (на остальные файлы пока внимание не обращаем).
В настоящий момент нас интересует раздел "webresources", который описывает параметры публикации ресурсов в CRM. Нам необходимо изменить его следующим образом:
• Параметр "root" должен указывать на папку "build"
• Параметр "solution" должен содержать уникальное имя решения, в которое производится публикация (иначе будет выбрано решение по умолчанию)
• Параметр "files" должен содержать путь ко всем необходимым файлам в папке build. Помимо ресурсов нашего приложения, build содержит различные манифесты, которые не нужны CRM. Их не нужно перечислять в этом списке
В результате, ваш spkl.json должен выглядеть похожим образом:
X++:
"webresources": [ { /* Option - profile - Provide a comma delimitered list of profile names that can be referenced when calling spkl */ "profile": "default,debug", /* Optional - root - Provide the relatative path of the webresources. */ "root": "build/", /* Optional - solution - Add webresources to a solution when deploying */ "solution": "reactapp", /* Required - files - List the webresources to deploy relatative to the root of this file (or the the root parameter above) */ "files": [ { "uniquename": "new_/index.html", "file": "index.html", "description": "" }, { "uniquename": "new_/static/css/main.c17080f1.css", "file": "static\\css\\main.c17080f1.css", "description": "" }, { "uniquename": "new_/static/js/main.b047ec63.js", "file": "static\\js\\main.b047ec63.js", "description": "" }, { "uniquename": "new_/static/media/logo.5d5d9eef.svg", "file": "static\\media\\logo.5d5d9eef.svg", "description": "" } ] } ]
Тем не менее, для первого раза попробуем опубликовать как есть. Для этого, откроем каталог сайта, зайдем в каталог spkl и выполним в нем команду:
X++:
deploy-webresources
Вам будут заданы стандартные вопросы по поиску вашего сервера и организации, после чего, если конфиг не содержит ошибок, решение будет опубликовано в CRM.
Чтобы проверить, что все работает, не обязательно вставлять страницу в какие-то фреймы и помещать на форму. Достаточно открыть index.html в редакторе веб ресурсов, или по прямой ссылке вида http(s)://crm-srv/OrgName/WebResources/prefix_/index.html?preview=1 - как вам будет удобно. Забавный момент: поддержка формата svg только недавно появилась в онлайн версии, так что если вы экспериментируете с онпремис, вы должны увидеть что-то подобное:
Итак, мы собрали и опубликовали в CRM наше первое реакт приложение. Вопросов должно было только прибавится: как это вообще работает, что делать с хэшами, что это вообще за синтаксис такой и так далее. Об этом я расскажу в следующих статьях серии:
Динозавр осваивает Modern Web - Часть пятая
Всего комментариев 0