- Publié le
Utiliser des Custom Elements Angular 7 dans une application Spring Boot
- Auteurs
- Nom
- Code Smarter
- @codesmarter_dev
Spring Boot devient de plus en plus intéressant pour le développement et la configuration des applications basées sur Spring.
De son côté, Angular s’impose comme l’un des frameworks JavaScript les plus appréciés.
Il est donc très pertinent de combiner les deux pour créer des applications puissantes.
Dans ce contexte, je vais te montrer comment utiliser l’une des fonctionnalités d’Angular, Angular Elements, et l’intégrer dans ton application Spring Boot.
Création du projet avec Spring Initializr
Spring Initializr est un outil qui permet de générer rapidement des projets Spring Boot et d’ajouter des configurations par défaut.
Créons notre projet :
Choisissez :
- Project : Maven Project
- Language : Java
- Spring Boot : (dernière version stable)
- Dependencies : Spring Web, Thymeleaf (optionnel), et toute autre dépendance nécessaire
Ensuite, cliquez sur Generate pour télécharger le projet.
Étape suivante

Génération du projet Maven avec Spring Boot
Dans la capture d’écran ci-dessus, nous indiquons simplement :
« Je veux que tu génères la structure d’un projet Maven avec Java et Spring Boot ».
Choix des dépendances
Dans la section Dependencies, tu peux sélectionner les packages dont tu as besoin.
Dans notre cas, la seule dépendance nécessaire pour l’instant est Web.
En choisissant cette dépendance, nous ajoutons le package spring-boot-starter-web, qui est le starter permettant de créer des applications web (y compris RESTful) avec Spring MVC.
Ce starter inclut également Tomcat, via le package spring-boot-starter-tomcat, qui est utilisé comme conteneur de servlets par défaut.
Génération du projet
En cliquant sur Generate Project, un fichier .zip sera téléchargé, contenant notre application prête à être importée.
Importation et configuration
Après avoir importé le projet dans ton IDE :
- Ouvre le fichier application.properties
- Modifie le port par défaut de l’application web afin d’éviter les conflits avec une autre application qui utiliserait le même port.
server.port line= 8181
l’URL suivante renvoie une erreur : [localhost](http://localhost: 8181/)

La vue n’est pas encore définie
C’est normal que l’URL affiche une erreur car aucune vue n’a encore été définie.
Ajouter un endpoint web
Nous avons créé notre application Spring Boot en spécifiant que nous voulions un packaging WAR.
Pour pouvoir déployer ce WAR plus tard et afficher le contenu web, vous devez créer un dossier webapp dans src/main
.
Spring MVC utilise le Tomcat intégré pour exécuter les applications.
Lors du déploiement, Tomcat recherche le fichier index.html
dans src/main/webapp
.
Étape 1 – Créer index.html
Créez un fichier index.html
dans src/main/webapp
avec un message simple :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<title>Accueil</title>
</head>
<body>
<h1>Bienvenue sur le site !</h1>
</body>
</html>
Après avoir redémarré l’application, l’URL suivante affichera le message :
http://localhost:8181/
Créer l’application Angular
Nous allons utiliser Angular CLI pour créer notre application Angular. Angular CLI est une interface en ligne de commande qui permet de générer un projet structuré et d’initialiser les dépendances ainsi que les interconnexions entre les différents modules.
Pré-requis
Pour utiliser Angular CLI, vous devez installer Node.js. npm est le gestionnaire de packages inclus dans Node.js.
Exemple de versions installées :
Node.js v11.8.0
npm 6.5.0
Angular CLI 7.3.1
Étape 2 – Créer le projet Angular
Pour éviter de créer un nouveau dossier, vous pouvez utiliser le répertoire webapp où se trouve déjà le fichier index.html.
Ouvrez un terminal, placez-vous dans le dossier src/main et exécutez la commande :
ng new webapp
Ne pas ajouter le routing ni le CSS pour l’instant. Vous pourrez le faire plus tard si vous souhaitez aller plus loin avec l’application.
Hiérarchie du projet

Réorganisation des dossiers et fichiers
Pour intégrer complètement Angular dans votre projet Spring Boot,
il est préférable de réorganiser les dossiers et fichiers afin de séparer configuration et vues.
Étapes à suivre
Supprimer le dossier node_modules.
Il sera régénéré plus tard à la racine du projet lorsque nous déplacerons package.json.Déplacer les fichiers de configuration au même niveau que pom.xml.
L’objectif est de conserver la configuration Angular et Maven côte à côte pour un accès plus simple.
webapp
:
Fichiers à déplacer depuis angular.json
package-lock.json
package.json
tsconfig.json
tslint.json
README.md
webapp/src
:
Fichiers à déplacer depuis karma.conf.js
tsconfig.app.json
tsconfig.spec.json
e2e/protractor.conf.js
e2e/tsconfig.e2e.json
⚠️ Vous remarquerez qu’il y a deux fichiers tslint.json.
Celui dans webapp/src
ajoute des règles au fichier principal déjà transféré.
👉 Ajoutez ces règles dans le fichier à la racine, puis supprimez celui de src
.
Le fichier README.md contient des commandes exemples pour utiliser Angular CLI.
Déplacer ensuite le contenu de
webapp/src
directement danswebapp
, puis supprimer le dossiersrc
devenu vide.
Cela permet d’éviter la confusion entre les multiples dossierssrc
du projet.Remplacer le fichier
index.html
créé précédemment par celui généré automatiquement par Angular.
Hiérarchie finale du projet
Après ces ajustements, la hiérarchie du projet devrait ressembler à ceci :

Mise à jour des fichiers de configuration
Maintenant, il faut modifier chaque fichier de configuration afin que les chemins pointent vers les bons répertoires.
👉 Vous pouvez trouver les fichiers corrigés sur GitHub.
Installation des dépendances
Depuis la racine du projet, exécutez la commande suivante pour régénérer le dossier node_modules :
npm install
Lancer l’application Angular
Pour tester l’application Angular, exécutez la commande :
ng serve
L’application sera alors accessible à l’adresse suivante http://localhost:4200/

Gérer Angular dans votre application Spring
Dans le fichier pom.xml, il est nécessaire de définir :
- les versions de Node et npm,
- ainsi que les commandes qui seront utilisées pour exécuter Angular.
Pour cela, nous allons utiliser le plugin frontend-maven-plugin.
Ce plugin permet d’installer Node, npm et de gérer des outils comme Grunt, Karma, Gulp, etc.
pom.xml
:
Ajouter la configuration suivante dans votre <plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.7.5</version>
<configuration>
<nodeVersion>v11.8.0</nodeVersion>
<npmVersion>6.5.0</npmVersion>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run build:prod</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Intégration du build Angular avec Maven
Avec ce plugin, nous indiquons à Maven que chaque fois que la commande :
mvn install
est exécutée :
Node et npm doivent être installés localement,
puis le projet Angular doit être construit.
👉 Cela génère automatiquement le dossier node_modules à la racine du projet.
Définir le script de build Angular
Dans le fichier package.json, ajoutez la ligne suivante dans la section scripts :
"build:prod": "ng build --prod --build-optimizer"
Ce script permet d’optimiser le build en production.
Si vous souhaitez exécuter d’autres commandes Angular avec Maven, vous pouvez simplement les ajouter dans ce même bloc.

Génération du WAR
Avec le build, un fichier WAR est généré contenant à la fois :
- la partie Java (Spring Boot),
- et le build Angular.
Votre application Spring Boot reste disponible à l’adresse :
Intégrer les composants Angular dans votre application Spring Boot
Lorsqu’un projet Angular est compilé, les composants sont générés dans des fichiers JavaScript (js) et mis en forme avec des fichiers CSS.
👉 Pour les utiliser dans votre application, il faudrait normalement intégrer un grand nombre de fichiers séparés.
Pour simplifier ce processus, nous avons besoin d’un outil capable de fusionner et minifier ces fichiers avant de les inclure dans l’application.
C’est exactement le rôle de Gulp !
Qu’est-ce que Gulp ?
Gulp est un outil d’automatisation simple à comprendre et à utiliser.
En plus de fusionner et minifier les fichiers, il peut également :
- compresser des images,
- compiler des fichiers LESS,
- et bien plus encore.
👉 Si vous souhaitez en savoir plus, vous pouvez visiter le site officiel de Gulp.
Utiliser Gulp avec Spring Tool Suite
Spring Tool Suite embarque déjà Gulp par défaut, ce qui permet de l’exécuter facilement.
Cependant, il est nécessaire d’installer Gulp ainsi que certains packages supplémentaires pour :
- concaténer les fichiers,
- renommer les fichiers.
Installation des packages Gulp
Exécutez les commandes suivantes depuis la racine du projet :
npm install --save-dev gulp
npm install --save-dev gulp-concat
npm install --save-dev gulp-rename
Création du fichier de configuration Gulp
Maintenant, créons un fichier de configuration nommé gulpfile.js
à la racine du projet.
const gulp = require('gulp')
const concat = require('gulp-concat')
const rename = require('gulp-rename')
gulp.task('prepare-js', function () {
return gulp
.src(['target/webapp/*.js'])
.pipe(concat('angular.js'))
.pipe(gulp.dest('src/main/webapp/dist'))
})
gulp.task('prepare-css', function () {
return gulp
.src(['target/webapp/styles.*.css'])
.pipe(rename('styles.css'))
.pipe(gulp.dest('src/main/webapp/dist'))
})
gulp.task('build', gulp.parallel('prepare-js', 'prepare-css'))
Intégrer Gulp dans Maven
Comme vous le voyez, un fichier Gulp est simple à lire et à comprendre.
En résumé, nous y déclarons les modules que nous voulons utiliser avec Gulp, nous définissons des tâches et nous les exécutons en mode parallèle.
Ensuite, ajoutez la commande gulp build dans Maven, afin que la prochaine fois que nous exécuterons l’application, les fichiers angular.js
et style.css
soient générés automatiquement.
Rappelez-vous du plugin frontend-maven-plugin que nous avons ajouté précédemment :
il gère également l’exécution de Gulp.
Ajoutez donc l’exécution suivante dans le fichier pom.xml
.
<execution>
<id>gulp build</id>
<goals>
<goal>gulp</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
Si vous exécutez la commande maven:clean install, vos fichiers doivent être générés danssrc/main/webapp/dist
.
Maintenant que la partie configuration est en place, nous pouvons nous concentrer sur Angular Elements.
Créer le custom element
Les Angular Elements sont des composants Angular empaquetés en tant que custom elements, natifs des navigateurs web tels que Chrome, Firefox, Opera, Safari, etc.
La liste complète des navigateurs supportés est disponible ici.
Ainsi, les Angular Elements peuvent être utilisés comme des éléments HTML dans n’importe quel framework ou application web.
Ce qui rend cette approche encore plus intéressante, c’est qu’Angular gère :
- les attributs,
- les bindings,
- les hooks du cycle de vie des Angular Elements.
Commençons par inclure le package @angular/elements pour pouvoir créer des custom elements.
npm install @angular/elements --save
Compatibilité des navigateurs
Les Custom Elements ne sont pas toujours supportés par les navigateurs anciens.
Pour éviter les erreurs, nous utilisons des polyfills afin d’assurer la compatibilité descendante.
ng add @angular/elements --name=webapp
Structure du projet
Le dossier webapp fait référence à src/main/webapp
.
C’est là que votre application Angular est stockée.
Création des Custom Elements
Nous sommes maintenant prêts à créer nos custom elements.
Commençons par créer un module widget qui contiendra tous les widgets que nous utiliserons dans notre application web.
Rendez-vous dans le dossier src/main/webapp/app
et tapez la commande suivante :
ng g module widget
Création d’un composant Rating
Maintenant, créons un composant rating à l’intérieur du module widget :
cd widget
ng g component rating
widget.module.ts
pour transformer le composant Rating en Custom Element
Modifier Éditez le fichier widget.module.ts
afin de rendre le composant Rating utilisable comme custom element :
import { NgModule, Injector } from '@angular/core'
import { CommonModule } from '@angular/common'
import { RatingComponent } from './rating/rating.component'
import { createCustomElement } from '@angular/elements'
@NgModule({
declarations: [RatingComponent],
imports: [CommonModule],
entryComponents: [RatingComponent],
})
export class WidgetModule {
constructor(private injector: Injector) {
const ratingElement = createCustomElement(RatingComponent, { injector: this.injector })
customElements.define('app-rating', ratingElement)
}
}
Ajouter le module Widget dans AppModule
Ajoutez le WidgetModule dans le tableau imports de AppModule.
Bootstrap des Angular Elements
Les Angular Elements se bootstrapent automatiquement, c’est-à-dire qu’ils démarrent lorsqu’ils sont ajoutés au DOM et se détruisent lorsqu’ils sont retirés.
Nous n’avons donc pas besoin de la méthode bootstrap par défaut.
- Supprimez le tableau bootstrap dans
app.module.ts
. - Nous allons bootstraper manuellement nos éléments.
L’interface DoBootstrap est exactement ce dont nous avons besoin, car elle permet d’ajouter la méthode ngDoBootstrap
.
Notre fichier final app.module.ts devrait ressembler à ceci :
import { BrowserModule } from '@angular/platform-browser'
import { NgModule, DoBootstrap } from '@angular/core'
import { WidgetModule } from './widget/widget.module'
@NgModule({
imports: [BrowserModule, WidgetModule],
})
export class AppModule implements DoBootstrap {
ngDoBootstrap() {}
}
Nettoyage de AppComponent
Comme nous n’utilisons plus AppComponent, nous pouvons :
- supprimer tous les fichiers
app.component.*
- et retirer le tableau declarations correspondant dans
app.module.ts
.
Composant Rating
Le composant Rating sera une boîte de notation basique dans notre application web.
- Il prendra en entrée un nombre entre 1 et 5
- et colorera autant d’étoiles correspondant à cette valeur.

- rating.component.ts
import { Component, Input } from '@angular/core'
@Component({
selector: 'app-rating',
templateUrl: './rating.component.html',
styleUrls: ['./rating.component.css'],
})
export class RatingComponent {
@Input() rate: number
}
- rating.component.html
<fieldset class="rating-rate">
<input type="radio" value="5" [checked]="rate==5" />
<label title="Rocks!">5 stars</label>
<input type="radio" value="4" [checked]="rate==4" />
<label title="Pretty good">4 stars</label>
<input type="radio" value="3" [checked]="rate==3" />
<label title="Not bad">3 stars</label>
<input type="radio" value="2" [checked]="rate==2" />
<label title="Kinda bad">2 stars</label>
<input type="radio" value="1" [checked]="rate==1" />
<label title="Sucks big time">1 star</label>
</fieldset>
- rating.component.css
/***************************
Pulls the stars container to the left
***************************/
.rating-rate {
float: left;
border: none;
}
/***************************
Hides the radio buttons
***************************/
.rating-rate:not(:checked) > input {
position: absolute;
top: -9999px;
clip: rect(0, 0, 0, 0);
}
/***************************
Default stars styles
***************************/
.rating-rate:not(:checked) > label {
float: right;
width: 1em;
padding: 0.1em;
overflow: hidden;
white-space: nowrap;
font-size: 100%;
line-height: 1.2;
color: #ddd;
}
/***************************
Adds the star symbol to the labels
***************************/
.rating-rate:not(:checked) > label:before {
content: '★ ';
}
/***************************
Colour for the applied rating stars
***************************/
.rating-rate > input:checked ~ label {
color: #f70;
}
Utiliser le custom element dans Spring Boot
Pour utiliser le custom element, créez un fichier index.html
et placez-le dans : src/main/resources/static
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Jangular</title>
<link rel="stylesheet" type="text/css" href="http://localhost:8181/dist/styles.css" />
</head>
<body>
<p>Welcome to jangular !</p>
<span style="float:left;padding-top:8px;">The application is rated </span>
<app-rating rate="5"></app-rating>
<script src="http://localhost:8181/dist/angular.js"></script>
</body>
</html>
Lancer l’application
Exécutez la commande suivante pour construire le projet et générer les fichiers Angular :
mvn clean install
Puis lancez votre application Spring Boot.
Si vous ouvrez l’URL suivante dans votre navigateur :http://localhost:8181/ vous obtiendrez l’erreur suivante dans l’inspecteur du navigateu

Utilisation de Zone.js
Zone.js est utilisé par Angular pour gérer l’exécution des tâches, les stack traces, etc.
Vous pouvez trouver plus d’informations sur zone.js ici.
- Dans une application Angular, zone.js est inclus automatiquement.
- Dans une application non-Angular, vous devez l’ajouter manuellement.
Importer Zone.js
Ajoutez la ligne suivante dans main.ts
pour importer zone.js :
import 'zone.js'
Relancer le build et démarrer l’application
Exécutez à nouveau la commande :
mvn clean install
Remarque
Vous pourriez rencontrer l’erreur suivante en vous connectant à : http://localhost:8181/
Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
Cela signifie que votre navigateur ne supporte pas ES5.
Éditez le fichier tsconfig.json et définissez la cible sur ES2015 au lieu de ES5.
Voilà ! ✅
Vous disposez maintenant d’une application Spring Boot utilisant un Angular Element.