Неоднозначный компонент Microsoft Graph Toolkit

Набор средств Microsoft Graph создан с использованием веб-компонентов. Веб-компоненты используют имя тега в качестве уникального ключа при регистрации в браузере. Любая попытка зарегистрировать компонент с помощью ранее зарегистрированного имени тега приводит к ошибке при вызове CustomElementRegistry.define(). В сценариях, когда несколько пользовательских приложений можно загрузить на одну страницу, это создает проблемы для Microsoft Graph Toolkit, особенно при разработке решений с использованием SharePoint Framework.

Пакет mgt-spfx помогает устранить эту проблему. С помощью mgt-spfxможно централизовать регистрацию веб-компонентов Microsoft Graph Toolkit во всех решениях SPFx, развернутых в клиенте. Повторно используя компоненты набора средств из центрального расположения, веб-части из разных решений можно загружать на одну страницу без возникновения ошибок. При использовании mgt-spfxвсе веб-части на основе Microsoft Graph Toolkit в клиенте SharePoint используют одну и ту же версию набора средств.

Функция дизамбига позволяет создавать веб-части с помощью последней версии Microsoft Graph Toolkit и загружать их на страницы вместе с веб-частями, использующими версию 2.x. С помощью этой функции можно указать уникальную строку для добавления в имя тега всех веб-компонентов набора средств в приложении. При использовании дизамбига указанное значение вставляется как второй сегмент имени тега, поэтому при использовании customElementHelper.withDisambiguation('foo')<mgt-login> тега ссылается с помощью <mgt-foo-login>.

При регистрации пользовательских элементов, вызывающих CustomElementRegistry.define(), введенное имя должно быть допустимым именем пользовательского элемента. Для лучшего взаимодействия с разработчиком withDisambiguation метод автоматически преобразует предоставленное значение в нижний регистр и выдает предупреждение в консоли разработчика, если указанное значение содержит символы, не являющиеся строчными. Этот вспомогательный метод не полностью очищает входные данные, и вызов базового define метода по-прежнему может завершиться ошибкой, например DOMException: Failed to execute 'define' on 'CustomElementRegistry': "mgt-MyName-flyout" is not a valid custom element name.

Использование веб-частей SharePoint Framework с React

При создании SharePoint Framework веб-частей с помощью React любой компонент, импортируемый @microsoft/mgt-react из библиотеки, должен быть асинхронно загружен после настройки параметра дизамбига. Вспомогательная lazyLoadComponent функция существует для упрощения использования React.lazy и React.Suspense отложенной загрузки этих компонентов из веб-части верхнего уровня. Функция lazyLoadComponent предоставляется в пакете @microsft/mgt-spfx-utils . Так как значение disambiguation используется только при отрисовке веб-компонента, то нет никаких изменений в способе ссылки на данный компонент в React коде.

В следующем примере показана минимальная веб-часть, которая показывает, как использовать Microsoft Graph Toolkit с дизамбигом в веб-частях SharePoint Framework на основе React. Более полные примеры см. в примере веб-части React SharePoint.

// [...] trimmed for brevity
import { Providers } from '@microsoft/mgt-element/dist/es6/providers/Providers';
import { customElementHelper } from '@microsoft/mgt-element/dist/es6/components/customElementHelper';
import { SharePointProvider } from '@microsoft/mgt-sharepoint-provider/dist/es6/SharePointProvider';
import { lazyLoadComponent } from '@microsoft/mgt-spfx-utils';

// Async import of component that imports the React Components
const MgtDemo = React.lazy(() => import('./components/MgtDemo'));

export interface IMgtDemoWebPartProps {
  description: string;
}
// set the disambiguation before initializing any webpart
// Use the solution name to ensure unique tag names
customElementHelper.withDisambiguation('spfx-solution-name');

export default class MgtDemoWebPart extends BaseClientSideWebPart<IMgtDemoWebPartProps> {
  // set the global provider
  protected async onInit() {
    if (!Providers.globalProvider) {
      Providers.globalProvider = new SharePointProvider(this.context);
    }
  }

  public render(): void {
    const element = lazyLoadComponent(MgtDemo, { description: this.properties.description });

    ReactDom.render(element, this.domElement);
  }

  // [...] trimmed for brevity
}

Примечание: Если веб-часть верхнего уровня импортирует любой код из @microsoft/mgt-react или @microsoft/mgt-components, то дизамбиг не будет действовать.

Затем базовые компоненты могут использовать компоненты набора средств из пакета в обычном @microsoft/mgt-react режиме. Из-за предыдущих шагов настройки набор средств React компонентов будет отображать HTML с использованием неоднозначных имен тегов:

import { Person } from '@microsoft/mgt-react';

// [...] trimmed for brevity

export default class MgtReact extends React.Component<IMgtReactProps, {}> {
  public render(): React.ReactElement<IMgtReactProps> {
    return (
      <div className={ styles.mgtReact }>
        <Person personQuery="me" />
      </div>
    );
  }
}

Использование в React

Чтобы использовать дизамбиг в приложении React, вызовите customElementHelper.withDisambiguation() перед загрузкой и отрисовкой корневого компонента. Чтобы упростить отложенную загрузку в этом сценарии, React предоставляет lazy функцию и Suspense компонент в React версии 16.6 и выше.

import React, { lazy, Suspense } from 'react';
import ReactDOM from 'react-dom';
import { customElementHelper, Providers } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";

customElementHelper.withDisambiguation('contoso');

Providers.globalProvider = new Msal2Provider({ clientId: 'clientId' });

const App = lazy(() => import('./App'));
ReactDOM.render(<Suspense fallback='...'><App /></Suspense>, document.getElementById('root'));

Использование в стандартном HTML и JavaScript

Чтобы использовать функцию дизамбига при использовании стандартного HTML и JavaScript, вызовите customElementHelper.withDisambiguation() перед импортом @microsoft/mgt-components модуля.

<script type="module">
  import { Providers, customElementHelper } from '@microsoft/mgt-element';
  import { Msal2Provider } from "@microsoft/mgt-msal2-provider";
  // configure disambiguation
  customElementHelper.withDisambiguation('contoso');

  // initialize the auth provider globally
  Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

  // import the components using dynamic import to avoid hoisting
  import('@microsoft/mgt-components');
</script>

<mgt-contoso-login></mgt-contoso-login>
<mgt-contoso-person person-query="Bill Gates" person-card="hover"></mgt-contoso-person>
<mgt-contoso-agenda group-by-day></mgt-contoso-agenda>

Важно!

mgt-components Класс import должен использовать динамический импорт, чтобы убедиться, что дизамбиг применяется перед импортом компонентов. Если используется статический импорт, он будет поднят , и импорт будет выполняться до применения дизамбига.

Динамические импорты (отложенная загрузка)

С помощью динамического импорта можно асинхронно загружать зависимости. Этот шаблон позволяет загружать зависимости только при необходимости. Например, может потребоваться загрузить компонент только тогда, когда пользователь нажимает кнопку. Это отличный способ сократить время начальной загрузки приложения. В контексте дизамбига необходимо использовать этот метод, так как компоненты регистрируются в браузере при импорте.

Важно: Если вы импортируете компоненты до применения дизамбига, дизамбиг не будет применен и использование имени неоднозначного тега не будет работать.

При использовании import инструкции import запускается и выполняется перед любым другим кодом в блоке кода. Чтобы использовать динамические импорты, необходимо использовать функцию import() . Функция import() возвращает обещание, которое разрешается в модуль. Вы также можете использовать then метод для выполнения кода после загрузки модуля, а catch метод — для обработки любых ошибок, если это необходимо.

Пример использования динамического импорта

// static import via a statement
import { Providers, customElementHelper } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";

customElementHelper.withDisambiguation('contoso');
Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

// dynamic import via a function
import('@microsoft/mgt-components').then(() => {
  // code to execute after the module is loaded
  document.body.innerHTML = '<mgt-contoso-login></mgt-contoso-login>';
}).catch((e) => {
  // handle any errors
});

Пример использования статического импорта

// static import via a statement
import { Providers } from '@microsoft/mgt-element';
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";
import '@microsoft/mgt-components';

Providers.globalProvider = new Msal2Provider({clientId: 'clientId'});

document.body.innerHTML = '<mgt-login></mgt-login>';

Примечание: Нельзя использовать дизамбиг со статическими импортами.