Makina Blog

Le blog Makina-corpus

Créer une application en tant que composant web avec Stencil


Mise en place dans le cadre de Geotrek, cette solution permet de se passer d'une iFrame pour afficher une application dans n'importe quel site.

Stencil est un framework permettant de créer des composants web. Il est utilisé pour créer un design system avec des composants web utilisables avec tous les frameworks majeurs ou même sans framework. En poussant le concept un peu plus loin, rien n'empêche de l'utiliser pour créer une application intégrable dans n'importe quel site web.

Tout d'abord, l'idée de créer une application en tant que composant web vient de la nécessité d'afficher le contenu d'un site web distant dans n'importe quel autre site web.

Pour ce faire, il existe une solution simple : L'iFrame. Cependant, celle-ci n'est pas assez puissante. En effet, une iFrame charge l'ensemble du site, ce qui n'est pas performant car celui-ci peut-être d'une taille conséquente. Un autre point négatif, elle nécessite que ce site distant soit hébergé, ce qui a un coût supplémentaire.

Un composant web, lui, est personnalisable. De plus, il est beaucoup plus léger et nous pouvons aussi utiliser qu'une partie de l'application. Par exemple, si nous souhaitons afficher le composant détail et pas toute l'application. Nous pouvons accéder aux fichiers nécessaires à son fonctionnement depuis un CDN, depuis les fichiers de notre site web ou depuis un hébergement externe.

Cet article est orienté technique et permet de voir concrètement comment a été implémenté le système utilisé par le widget Geotrek, présenté dans cet autre article qui se focalise sur un exemple concret. À la fin de cet article, un exemple sera tout de même introduit afin de mieux vous présenter le résultat.

Création des composants

L'objectif de cette section est d'illustrer la manière de créer plusieurs composants qui interagissent ensemble.

Commençons par créer notre projet avec Stencil :

npm init stencil

Nous choisissons component puis nous donnons un nom de projet.

Maintenant, rentrons dans le dossier du projet afin de supprimer le composant créé automatiquement et d'installer les paquets nécessaires.

cd nomduprojet
rm -rf src/components/my-component
npm install

Nous créons un premier composant :

npx stencil generate component-one

Remplaçons le code dans src/components/component-one.ts par :

import { Component, Host, h } from '@stencil/core';

@Component({
  tag: 'component-one',
  styleUrl: 'component-one.css',
  shadow: true,
})
export class ComponentOne {

  render() {
    return (
      <Host>
        <slot>Component one</slot>
      </Host>
    );
  }

}

Ce composant affiche le texte Component one.

Puis, nous créons un second composant :

npx stencil generate component-two

Nous remplaçons le code dans src/components/component-two.ts par :

import { Component, Host, h } from '@stencil/core';

@Component({
  tag: 'component-two',
  styleUrl: 'component-two.css',
  shadow: true,
})
export class ComponentTwo {

  render() {
    return (
      <Host>
        <slot>Component two</slot>
      </Host>
    );
  }

}

Ce composant affiche le texte Component two.

 

Assemblage des composants

Maintenant que nos composants web sont créés, ils peuvent être utilisés indépendamment si nous le souhaitons.

Cependant, un composant de type application peut être créé afin de les assembler :

npx stencil generate component-main

Le code dans src/components/component-main.ts est remplacé par :

import { Component, Host, h, State, Prop } from '@stencil/core';

@Component({
  tag: 'component-main',
  styleUrl: 'component-main.css',
  shadow: true,
})
export class ComponentMain {
  @State() showComponentOne = true;
  @Prop() color = "blue";
  
  handleComponentVisibility() {
    this.showComponentOne = !this.showComponentOne
  }

  render() {
    return (
      <Host>
        <slot>
          <button style={{ backgroundColor: this.color }} onClick={this.handleComponentVisibility}>
            {!this.showComponentOne ? "Show Component one" : "Show Component two" }
          </button>
          {this.showComponentOne ? <component-one></component-one> : <component-two></component-two>}
        </slot>
      </Host>
    );
  }

}

Le composant component-main assemble nos deux autres composants préalablement créés et permet de gérer leur affichage à l'aide d'un bouton. Ce dernier appelle une fonction changeant la valeur de la variable showComponentOne qui est définit comme State. Lorsque celle-ci change de valeur, notre composant se met à jour.

De plus, nous avons la variable color, définit comme Prop, qui permet de renseigner à ce composant à l'aide d'un paramètre cette valeur. Ici, par défaut, la couleur de fond de notre bouton est bleu.

Remplaçons le code dans src/index.html par :

<!DOCTYPE html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
    <title>Component main</title>

    <script type="module" src="/build/article.esm.js"></script>
    <script nomodule src="/build/article.js"></script>
  </head>
  <body>
    <component-main color="yellow"></component-main>
  </body>
</html>

Nous en profitons pour définir la valeur de la variable color avec yellow.

Nous pouvons maintenant voir le rendu final :

npm start

Le composant component-main est donc affiché avec son état de base, c'est à dire un bouton avec le libellé Show component two et le texte Component one. Et, il est interactif puisqu'au clic sur le bouton le libellé de celui-ci change en Show component one et le texte est alors Component two.

Intégration du composant de type application

Nous créons les fichiers nécessaires au déploiement :

npm run build

Maintenant, il faut les charger dans le site où nous voulons afficher nos composants.

À partir d'ici, notre exemple s'appuie sur les composants de Geotrek-Rando Widget, afin d'avoir un rendu plus intéressant.

Geotrek-Rando Widget est un projet créé avec Stencil permettant d'afficher des données liées à Geotrek. Plusieurs composants existent dont un de type applicatif.

Pour afficher celui-ci, il suffit de copier-coller ces lignes dans le head de notre site, ces fichiers sont les équivalents de ceux que nous venons de créer :

<link rel="stylesheet" href="https://rando-widget.geotrek.fr/latest/dist/geotrek-rando-widget/geotrek-rando-widget.css" />
<script type="module" src="https://rando-widget.geotrek.fr/latest/dist/geotrek-rando-widget/geotrek-rando-widget.esm.js"></script>
<script nomodule src="https://rando-widget.geotrek.fr/latest/dist/geotrek-rando-widget/geotrek-rando-widget.js"></script>

Puis ajouter ces lignes dans le body :

<div style="width: 100%; height: 50vh">
  <grw-app api="https://demo-admin.geotrek.fr/api/v2/" color-primary="#d0dd2a" color-primary-shade="#919a1d" color-primary-tint="#dee769"></grw-app>
</div>

 

Voici le résultat :

 

Grâce au composant web et à leur possible imbrication, beaucoup de cas d'usages peuvent être envisagés. Par exemple, un composant qui permet d'afficher la météo avec une vue simple et l'enrichir avec une interaction afin d'afficher une vue détaillée.

C'est une solution performante, personnalisable et capable d'être déployée partout.

Bonus

Afin de faciliter la création des composants web et donc de l'application, Storybook peut être utilisé.

Storybook est une application qui permet d'isoler nos composants. Nous pouvons donc visualiser indépendamment chaque composant mais aussi d'interagir avec eux. Les paramètres à la volée peuvent aussi être changés, ce qui facilite la personnalisation des composants afin de les intégrer ensuite dans notre site web, une fois le résultat voulu obtenu.

Voici par exemple le Storybook de Geotrek rando widget.

Formations associées

Formations Geotrek

Formation Utilisation de Geotrek

Toulouse Nous contacter

Voir la formation

Formations Geotrek

Formation Administration et personnalisation de Geotrek

Toulouse Nous contacter pour des dates

Voir la formation

Actualités en lien

Image
Encart article Protomaps : Illustration d'une portion de pyramide de tuiles
14/02/2024

Protomaps, stockez vos pyramides de tuiles plus simplement

Présentation d'un nouveau format de stockage de tuiles cartographiques

Voir l'article
Image
Read The Docs
01/02/2024

Publier une documentation VitePress sur Read The Docs

À l'origine, le site de documentation Read The Docs n'acceptait que les documentations Sphinx ou MKDocs. Depuis peu, le site laisse les mains libres pour builder sa documentation avec l'outil de son choix. Voici un exemple avec VitePress.

Voir l'article
Image
Vue détail widget Geotrek
28/03/2023

Développement de Geotrek Widget financé par le Parc Naturel Régional du Haut-Jura

Geotrek Widget est un nouveau composant web permettant de valoriser une offre de contenus touristiques et de randonnées auprès des usagers du territoire.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus