Utiliser des bibliothèques JavaScript existantes dans les composants WebPart côté client pour SharePoint Framework

Quand vous générez des composants WebPart côté client pour SharePoint Framework, vous pouvez utiliser des bibliothèques JavaScript existantes pour générer des solutions puissantes. Cependant, certains aspects doivent être pris en compte pour vous assurer que vos composants WebPart ne réduiront pas les performances des pages SharePoint sur lesquelles ils sont utilisés.

Référencement des bibliothèques existantes sous forme de packages

La méthode la plus courante pour référencer des bibliothèques JavaScript existantes dans des composants WebPart côté client pour l’infrastructure SharePoint consiste à les installer sous forme de package dans le projet.

  1. Pour utiliser Angular dans un composant WebPart côté client, par exemple, vous devez tout d’abord installer Angular à l’aide npm :

    npm install angular --save
    
  2. Pour utiliser Angular avec TypeScript, installez les déclarations de type à l’aide de npm :

    npm install @types/angular --save-dev
    
  3. Référencez Angular dans votre composant WebPart à l’aide de l’instruction import :

    import { Version } from '@microsoft/sp-core-library';
    import {
      BaseClientSideWebPart,
      IPropertyPaneConfiguration,
      PropertyPaneTextField
    } from '@microsoft/sp-webpart-base';
    import { escape } from '@microsoft/sp-lodash-subset';
    
    import styles from './HelloWorld.module.scss';
    import * as strings from 'helloWorldStrings';
    import { IHelloWorldWebPartProps } from './IHelloWorldWebPartProps';
    
    import * as angular from 'angular';
    
    export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
      public render(): void {
        this.domElement.innerHTML = `
          <div class="${styles.helloWorld}">
            <!-- omitted for brevity -->
          </div>`;
    
          angular.module('helloworld', []);
    
          angular.bootstrap(this.domElement, ['helloworld']);
      }
    
      // omitted for brevity
    }
    

Regroupement des ressources WebPart dans un fichier groupé

L’infrastructure SharePoint utilise une chaîne d’outils de génération qui contient des outils open source tels que Gulp et Webpack. Quand vous générez des projets SharePoint Framework, ces outils de génération regroupent automatiquement toutes les ressources référencées dans un même fichier JavaScript (fichier groupé).

Fenêtre de commande avec la tâche de regroupement Gulp visible en regard du dossier dist de SharePoint Framework, qui contient les fichiers de sortie

Les fichiers groupés ont de nombreux avantages. Tout d’abord, toutes les ressources nécessaires à votre composant WebPart sont disponibles dans un seul et même fichier JavaScript. Cela simplifie le déploiement car le composant WebPart se compose d’un seul fichier et il est impossible d’oublier une dépendance pendant le déploiement.

Comme votre composant WebPart utilise des ressources différentes, il est important qu’elles soient chargées dans le bon ordre. Créé par Webpack pendant la génération, le fichier groupé du composant WebPart gère le chargement des différentes ressources à votre place, y compris la résolution des dépendances entre ces ressources.

L’utilisation de fichiers groupés pour les composants WebPart a également des avantages pour les utilisateurs finals : en règle générale, il est plus rapide de télécharger un seul fichier volumineux, que plusieurs petits fichiers. En combinant plusieurs petits fichiers dans un fichier groupé volumineux, votre composant WebPart se charge plus rapidement sur la page.

Cependant, le fait de regrouper les bibliothèques JavaScript existantes avec les composants WebPart côté client de SharePoint Framework présente des inconvénients.

Lorsque vous regroupez des infrastructures JavaScript existantes dans l’infrastructure SharePoint, tous les scripts référencés sont inclus dans le fichier groupé qui est généré. Dans l’exemple suivant, un fichier groupé de composant WebPart optimisé et contenant Angular fait plus de 170 Ko.

Taille du fichier groupé mise en surbrillance dans l’Explorateur

Si vous ajoutez au projet un autre composant WebPart, qui utilise également Angular, et que vous générez le projet, vous obtenez deux fichiers groupés, un pour chaque composant WebPart, faisant chacun plus de 170 Ko.

Deux fichiers groupés mis en surbrillance dans l’Explorateur

Si vous ajoutez ces composants WebPart à une page, chaque utilisateur télécharge Angular plusieurs fois, une fois avec chaque composant WebPart sur la page. Cette approche est inefficace et ralentit le temps de chargement des pages.

Référencement des bibliothèques existantes en tant que ressources externes

Pour tirer parti des bibliothèques existantes dans un composant WebPart côté client SharePoint Framework, référencez-les comme des ressources externes. Ainsi, la seule information sur le script incluse dans le composant WebPart est l’URL du script. Une fois ajouté à la page, le composant WebPart tente automatiquement de charger toutes les ressources nécessaires à partir des URL spécifiées.

Le référencement des bibliothèques JavaScript existantes dans SharePoint Framework est simple et ne requiert pas de modifications spécifiques dans le code. Étant donné que la bibliothèque est chargée lors de l’exécution, à partir de l’URL spécifiée, il n’est pas nécessaire de l’installer en tant que package dans le projet.

Pour référencer Angular, par exemple, en tant que ressource externe dans votre composant WebPart côté client, commencez par installer ses déclarations de type TypeScript à l’aide de npm :

npm install @types/angular --save-dev

Dans le fichier config/config.json, ajoutez l’entrée suivante à la propriété externals :

"angular": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
  "globalName": "angular"
}

L’intégralité du fichier config/config.json aurait l’aspect suivant :

{
  "entries": [
    {
      "entry": "./lib/webparts/helloWorld/HelloWorldWebPart.js",
      "manifest": "./src/webparts/helloWorld/HelloWorldWebPart.manifest.json",
      "outputPath": "./dist/hello-world.bundle.js"
    }
  ],
  "externals": {
    "angular": {
      "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
      "globalName": "angular"
    }
  },
  "localizedResources": {
    "helloWorldStrings": "webparts/helloWorld/loc/{locale}.js"
  }
}

Référencez Angular dans votre composant WebPart :

import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import { escape } from '@microsoft/sp-lodash-subset';

import styles from './HelloWorld.module.scss';
import * as strings from 'helloWorldStrings';
import { IHelloWorldWebPartProps } from './IHelloWorldWebPartProps';

import * as angular from 'angular';

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.helloWorld}">
        <!-- omitted for brevity -->
      </div>`;

      angular.module('helloworld', []);

      angular.bootstrap(this.domElement, ['helloworld']);
  }

  // omitted for brevity
}

Si vous générez votre projet maintenant, la taille du fichier groupé généré fait uniquement 6 Ko.

Taille du fichier groupé mise en surbrillance dans l’Explorateur

Si vous ajoutez à votre projet un autre composant WebPart, qui utilise également Angular, et que vous générez à nouveau le projet, les fichiers groupés font 6 Ko chacun.

Deux fichiers groupés mis en surbrillance dans l’Explorateur

Il n’est pas correct de supposer que vous avez enregistré plus de 300 Ko. Les deux composants WebPart ont toujours besoin d’Angular et le chargent la première fois que l’utilisateur visite la page où l’un des composants WebPart est placé.

Angular mis en surbrillance dans les outils de développement pour une page comportant un composant WebPart

Même si vous ajoutez les deux composants WebPart Angular à la page, SharePoint Framework ne télécharge toujours Angular qu’une seule fois.

Angular mis en surbrillance dans les outils de développement pour une page comportant les deux composants WebPart

Le référencement des bibliothèques JavaScript existantes en tant que ressources externes présente un avantage réel si votre organisation dispose d’un emplacement centralisé pour tous les scripts couramment utilisés ou si vous utilisez un CDN. Dans ce cas, il est possible que la bibliothèque JavaScript voulue existe déjà dans le cache du navigateur de l’utilisateur. Par conséquent, le seul élément qui doit être chargé est le fichier groupé de composant WebPart, ce qui accélère le chargement de la page.

Onglet Réseau des outils de développement n’affichant pas Angular bien que les deux composants WebPart de la page l’utilisent

L’exemple précédent montre comment charger Angular à partir d’un CDN. L’utilisation d’un CDN public n’est pas obligatoire. Dans la configuration, vous pouvez pointer vers n’importe quel emplacement : un CDN public, un référentiel hébergé en privé, une bibliothèque de documents SharePoint, etc. Tant que les utilisateurs qui utilisent vos composants WebPart peuvent accéder aux URL spécifiées, vos composants WebPart fonctionneront comme prévu.

Les CDN sont optimisés pour un transfert rapide des ressources dans le monde entier. Le référencement des scripts à partir de CDN publics a un autre avantage : il est possible que le même script ait été utilisé sur un autre site web consulté par cet utilisateur dans le passé. Comme le script existe déjà dans le cache du navigateur local, il ne serait alors pas nécessaire de le télécharger spécifiquement pour votre composant WebPart, ce qui accélérerait le chargement de la page contenant le composant WebPart.

Certaines organisations n’autorisent pas l’accès à des CDN publics à partir du réseau de l’entreprise. Dans ce cas, l’utilisation d’un emplacement de stockage hébergé en privé pour les infrastructures JavaScript fréquemment utilisées constitue une excellente solution. Si votre organisation héberge les bibliothèques, elle peut également contrôler les en-têtes de cache, ce qui peut vous aider à optimiser vos ressources pour en accroître les performances.

Formats des bibliothèques JavaScript

Les bibliothèques JavaScript sont générées et empaquetées de différentes manières. Certaines sont empaquetées sous forme de modules, d’autres sont des scripts simples qui s’exécutent dans l’étendue globale (ces scripts sont souvent appelés scripts non-module). Lorsque vous chargez des bibliothèques JavaScript à partir d’une URL, la façon dont vous inscrivez un script externe dans un projet de l’infrastructure SharePoint dépend de son format. Il existe plusieurs formats de module, comme AMD, UMD ou CommonJS, mais vous devez uniquement savoir si le script concerné est un module ou non.

Lorsque vous inscrivez des scripts sous forme de modules, la seule information que vous devez spécifier est l’URL à partir de laquelle un script donné doit être téléchargé. Les dépendances avec d’autres scripts sont gérées à l’intérieur de la construction de module du script.

Les scripts non-module nécessitent au minimum l’URL à partir de laquelle le script doit être téléchargé et le nom de la variable avec laquelle le script est enregistré dans l’étendue globale. Si le script non-module dépend d’autres scripts, il peut être répertorié en tant que dépendance. Pour illustrer ce principe, examinons quelques exemples.

Angular v1.x est un script non-module. Vous l’enregistrez sous forme de ressource externe dans un projet SharePoint Framework en spécifiant son URL et le nom de la variable globale avec laquelle il doit être inscrit :

"angular": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
  "globalName": "angular"
}

Il est important que le nom spécifié dans la propriété globalName corresponde à celui utilisé par le script. De cette façon, il peut correctement s’exposer lui-même à d’autres scripts susceptibles de dépendre de lui.

ngOfficeUIFabric, qui regroupe les directives Angular pour Office UI Fabric, est un module UMD qui dépend d’Angular. Cette dépendance à Angular est déjà gérée à l’intérieur du module. Il vous suffit donc de spécifier son URL pour l’enregistrer :

"ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.12.3/ngOfficeUiFabric.js"

jQuery est un script AMD. Pour l’inscrire, vous pouvez simplement utiliser :

"jquery": "https://code.jquery.com/jquery-2.2.4.js"

Imaginons maintenant que vous vouliez utiliser jQuery avec un plug-in jQuery qui est lui-même distribué sous forme de script non-module.

Si vous avez enregistré les deux scripts à l’aide du code suivant, le chargement du composant WebPart générera probablement une erreur. En effet, il est possible que les deux scripts soient chargés en parallèle et que le plug-in ne puisse pas s’enregistrer avec jQuery.

"jquery": "https://code.jquery.com/jquery-2.2.4.js",
"simpleWeather": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/jquery.simpleWeather/3.1.0/jquery.simpleWeather.min.js",
  "globalName": "jQuery"
}

Erreur lors d’une tentative de chargement d’un composant WebPart à l’aide d’un plug-in jQuery non-module

Comme indiqué précédemment, SharePoint Framework vous permet de spécifier des dépendances pour des plug-ins non-module. Ces dépendances sont spécifiées à l’aide de la propriété globalDependencies :

"jquery": "https://code.jquery.com/jquery-2.2.4.js",
"simpleWeather": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/jquery.simpleWeather/3.1.0/jquery.simpleWeather.min.js",
  "globalName": "jQuery",
  "globalDependencies": [ "jquery" ]
}

Chaque dépendance spécifiée dans la propriété globalDependencies doit pointer vers une autre dépendance dans la section externals du fichier config/config.json.

Si vous essayiez de générer le projet maintenant, vous obtiendriez une autre erreur, qui indiquerait cette fois que vous ne pouvez pas spécifier de dépendance à un script non-module.

Erreur lors d’une tentative de création d’une solution SharePoint Framework avec un script non-module spécifiant une dépendance à un script qui est un module

Pour résoudre ce problème, il vous suffit d’inscrire jQuery comme script non-module :

"jquery": {
  "path": "https://code.jquery.com/jquery-2.1.1.min.js",
  "globalName": "jQuery"
},
"simpleWeather": {
  "path": "https://cdnjs.cloudflare.com/ajax/libs/jquery.simpleWeather/3.1.0/jquery.simpleWeather.min.js",
  "globalName": "jQuery",
  "globalDependencies": [ "jquery" ]
}

Ainsi, vous indiquez que le script simpleWeather doit être chargé après jQuery et que jQuery doit être disponible sous une variable jQuery globalement disponible, requise par le plug-in jQuery simpleWeather pour être enregistré.

Notes

L’entrée d’enregistrement de jQuery utilise jquery pour le nom de la ressource externe et jQuery pour le nom de la variable globale. Le nom de la ressource externe est celui que vous utilisez dans les instructions import de votre code. C’est également le nom qui doit correspondre aux déclarations de type TypeScript. Le nom de la variable globale, spécifié à l’aide de la propriété globalName, est le nom connu des autres scripts, par exemple ceux des plug-ins créés sur la bibliothèque. Même si ces noms sont identiques pour certaines bibliothèques, ce n’est pas une condition obligatoire. Vérifiez bien que vous utilisez les noms corrects pour éviter tout problème.

Il est difficile de déterminer manuellement si le script que vous essayez de charger est un script de module ou non-module. C’est notamment le cas si le script que vous essayez de charger est minimisé. Si votre script est hébergé sur une URL accessible au public, vous pouvez utiliser l’application gratuite Rencore SharePoint Framework Script Check, qui détermine le type de script à votre place. De plus, cet outil vous permet de savoir si l’emplacement d’hébergement à partir duquel vous chargez le script est correctement configuré.

Considérations relatives aux scripts non-module

De nombreux scripts et bibliothèques JavaScript développés par le passé sont distribués sous forme de scripts non-module. Bien que SharePoint Framework prenne en charge le chargement de scripts non-module, évitez autant que possible d’en utiliser.

Les scripts non-module sont enregistrés dans l’étendue globale de la page : un script chargé par un composant WebPart est accessible par tous les autres composants WebPart sur la page. Si vous avez deux composants WebPart utilisant différentes versions de jQuery, tous deux chargés sous forme de scripts non-module, le composant WebPart chargé en dernier remplace toutes les versions enregistrées de jQuery.

Comme vous pouvez l’imaginer, cela peut entraîner des résultats imprévisibles, et il serait difficile de déboguer des problèmes qui se produisent uniquement dans certains scénarios, comme uniquement avec d’autres composants WebPart à l’aide d’une version différente de jQuery sur la page et uniquement lorsqu’ils se chargent dans un ordre particulier. L’architecture du module résout ce problème en isolant les scripts et en les empêchant de s’affecter mutuellement.

Cas dans lesquels les fichiers groupés sont une bonne option

Le regroupement des bibliothèques JavaScript existantes dans le fichier groupé de votre composant WebPart peut générer de grands fichiers de composants WebPart et risque de nuire aux performances des pages qui utilisent ce composant. Bien que vous deviez en général éviter d’inclure les bibliothèques JavaScript avec vos composants WebPart dans un fichier groupé, il existe certains cas de figure dans lesquels cette méthode peut avoir des avantages.

Si vous générez une solution standard qui doit fonctionner sur tous les intranets, le regroupement de toutes vos ressources avec votre composant WebPart peut être un moyen d’assurer le bon fonctionnement de votre composant WebPart. Comme vous ne savez pas à l’avance où votre solution sera installée, le fait d’inclure toutes les dépendances dans le fichier groupé de votre composant WebPart vous permet de garantir son bon fonctionnement, même si l’organisation n’autorise pas le téléchargement de ressources à partir d’un CDN ou d’un autre emplacement externe.

Si votre solution se compose de nombreux composants WebPart qui partagent certaines fonctionnalités entre eux, il est préférable de créer la fonctionnalité partagée sous la forme d’une bibliothèque distincte et de la référencer en tant que ressource externe dans tous les composants WebPart. De cette façon, les utilisateurs n’ont besoin de télécharger la bibliothèque commune qu’une seule fois et de la réutiliser avec tous les composants WebPart.

Résumé

Quand vous générez des composants WebPart côté client dans SharePoint Framework, vous pouvez utiliser des bibliothèques JavaScript existantes pour générer des solutions puissantes. L’infrastructure SharePoint vous permet d’inclure ces bibliothèques dans le fichier groupé de vos composants WebPart ou de les charger sous forme de ressource externe. Même si le chargement des bibliothèques existantes à partir d’une URL est généralement la méthode recommandée, l’utilisation des fichiers groupés peut être utile dans certains scénarios. Ainsi, il est essentiel d’évaluer attentivement vos exigences pour choisir l’approche qui répond le mieux à vos besoins.

Voir aussi