Наверняка вы уже слышали о том, что продукт SharePoint Framework вошел в состав платформы Office 365 — появилось сообщение о его доступности для всех желающих. Это важное событие, безусловно, заслуживает нашего внимания. Однако мой опыт однозначно свидетельствует о том, что непосредственно после выпуска какого-либо нового компонента, первичной реализации какой-нибудь услуги или внесения изменений в существующий продукт сотрудники большинства организаций попросту не готовы воспринять нововведение. Часто это объясняется тем, что занятые решением безотлагательных повседневных задач специалисты просто не могут уделять достаточно внимания отслеживанию разного рода перспективных новинок. В итоге мы нередко занимаемся поисками в Интернете и перебираем материалы, отобранные поисковиками Google или Bing в надежде, что кто-то другой уже столкнулся с такой же проблемой и поделился своим решением в блоге. Здесь, кстати, надо отметить, что специалисты Microsoft сделали доброе дело: задокументировали большинство проблем, с которыми потребители могут столкнуться или о которых они должны знать. Впрочем, проведенная в Microsoft работа охватывает не весь круг интересующих нас вопросов.

Как раз один из таких вопросов всегда встает перед нами, когда мы разрабатываем решения с помощью SharePoint Framework. Речь идет о структуре создаваемого нами кода, в первую очередь о существующих сценариях JavaScript или программных решениях на стороне клиента, на которые нам приходится переходить. Когда мы пишем код на языке JavaScript, мы должны иметь в виду, что существуют три представления о том, как это делается. Первая схема — асинхронное определение модуля Asynchronous Module Definition (AMD). Этот метод прост и логичен. Он позволяет нам определять функции и представлять методы, которые могут использоваться на всем пространстве нашего кода. Код AMD может выглядеть так, как показано на экране 1.

Пример кода Asynchronous Module Definition
Экран 1. Пример кода Asynchronous Module Definition

Если бы мы захотели сгенерировать тот же фрагмент кода с использованием второй схемы, которая именуется CommonJS, нам пришлось бы несколько изменить его. Данный подход обычно применяется в тех случаях, когда программист написал кодовый фрагмент для Node.js (экран 2).

Пример кода для Node.js
Экран 2. Пример кода для Node.js

Наконец, мы можем написать код в формате Universal Module Definition (UMD). Этот формат становится все более популярным, и если мы присмотримся к некоторым фрагментам базового кода SharePoint Framework, то убедимся, что разработчики кое в чем следуют его схеме (экран 3).

Код в формате Universal Module Definition
Экран 3. Код в формате Universal Module Definition

Каждый из форматов работает, каждый выполняет одну и ту же задачу, но при этом каждый имеет свои достоинства. Если бы мне нужно было написать относящуюся к среде веб-часть кода SharePoint Framework, я лично выбрал бы синтаксис, представляющий нечто среднее между схемами CommonJS и UMD. Поясню это на примере: решение задачи включения jQuery в веб-часть кода SharePoint Framework предполагает не только ссылки на данный код. В дополнение к этому его нужно будет включить в код веб-части (экран 4).

Включение jQuery в веб-часть кода SharePoint Framework
Экран 4. Включение jQuery в веб-часть кода SharePoint Framework

Как видите, нам приходится употреблять термин require — заимствование из модели CommonJS, а затем мы выполняем операцию импорта в базовый объект, тем самым следуя схеме UMD. Определенные трудности представляет и использование внешних библиотек, которые создавались без применения новейших форматов, внутри SharePoint Framework и исключительно на основе того, как вызываются и используются функции. Если мы захотим установить связь с внешним файлом, расположенным внутри нашей среды, это можно будет сделать двумя способами в зависимости от версии JavaScript, на которой он написан.

Прежде всего, все внешние ссылки JS должны быть добавлены в файл config.json внутри проекта. Внутри данного файла имеется раздел Externals; именно в него следует помещать внешние ссылки JavaScript. При этом синтаксис не меняется в зависимости от того, является ли данный указатель URL внешним по отношению к вашему решению или вы скопировали его в исходную папку (экран 5).

Два способа связи с внешним файлом
Экран 5. Два способа связи с внешним файлом

Обратите внимание на следующее обстоятельство. Поскольку при написании этих файлов новейший формат UMD не использовался, мы должны обращаться к ним именно таким образом, указывая имя фрагмента кода, путь и глобальное имя, которым мы далее будем пользоваться внутри инструкций по импорту в веб-части. Если мы добавляем вновь сформированный модуль UMD, то можем просто обращаться к нему таким образом, как показано на экране 6.

Обращение к модулю UMD
Экран 6. Обращение к модулю UMD

Как видите, это обстоятельство может заметно осложнить процесс преобразования существующего кода во фрагмент, готовый к использованию внутри SharePoint Framework. Разумеется, мы не хотим реорганизовывать весь исходный код. Мое предложение состоит в том, что, может быть, имеет смысл рассматривать возникшую ситуацию как часть общей задачи, то есть действовать таким же образом, как в ситуации, когда мы преобразуем код полного доверия SharePoint в данную новую среду. Чтобы мы могли корректно обращаться к внешним файлам, специалисты компании Rencore создали инструмент, который может быть использован для решения этой задачи. Более подробную информацию о нем вы можете найти по адресу: https://rencore.com/blog/correctly-reference-scripts-rencore-script-check/.

Истинная цель в данном случае состоит в том, чтобы вы задумались о создаваемых вами решениях и, возможно, преобразовали исходный код так, чтобы модули решений следовали принципам, заложенным в базовую структуру SharePoint Framework.

Чтобы помочь вам разобраться с тем, как выполнить реорганизацию исходного кода, предлагаю ознакомиться c перечисленными во врезке дополнительными материалами и примерами.

Дополнительные ресурсы

  • https://blog.mastykarz.nl/migrate-sharepoint-javascript-customizations-sharepoint-framework-reference-functions/
  • https://github.com/SharePoint/sp-dev-docs/blob/master/docs/spfx/web-parts/guidance/use-existing-javascript-libraries.md
  • https://github.com/OlivierCC/spfx-40-fantastics