# Atelier SingleSpa (FR)
## Découverte de SingleSpa
- Le but de cet atelier est de découvrir les bases de SingleSpa et de l'architecture micro-frontends
- Pour des raisons de simplicité, le terme micro-frontend sera abrégé en MFe
- Pour ce tutoriel, nous allons nous inspirer du [Getting Started officiel](https://single-spa.js.org/docs/getting-started-overview)
- Le terme MFe est inspiré de micro services. On développe des briques isolées et réutilisables
- Une plateforme qui suit cette architecture sera composée d'un MFe de type `root-config` et de plusieurs MFe de type `app-parcel`
- La grande particularité de ce paradigme est que chaque MFe est hébergé sur un serveur et possède sa propre url. On ne lancera jamais le "projet" entier sur sa machine, mais uniquement le MFE sur lequel on travaille
- Dans le cadre de ce tutoriel, tout sera lancé en local
- Etant donné qu'il n'y a pas de hiérarchie entre les MFe, nous allons créer un dossier `test_single_spa` qui contiendra tout notre code
## Etape 1 : root-config
- La racine de l'application se nomme `root-config` en SingleSpa
- Dans un langage plus fonctionnel, il s'agit de la plateforme (Astrée, MAS...)
- Ouvrir un 1er terminal
- Depuis le dossier `test_single_spa`, lancer la commande `npx create-single-spa --moduleType root-config` puis suivre le wizard
- ? Directory for new project (.) `root-config`
- ? Which package manager do you want to use? `yarn` (ou autre)
- ? Will this project use Typescript? `y`
- ? Would you like to use single-spa Layout `enter`
- ? Organization name `cls`
- `cd root-config`, `yarn start`
- Le plateforme est lancée sur http://localhost:9000/
- Notez qu'elle intègre une application d'exemple
- Deux notions importantes
- Le fichier `src/index.ejs` intègre le mapping entre les noms d'applications et librairies, et leur url
- Le fichier `src/microfrontend-layout.html` permet de composer les MFe (on y retrouve le MFe d'exemple)
## Etape 2 : librairies partagées
- Si une lib est utilisée dans plusieurs MFe (ex: react), il est possible de la définir en tant que dépendance commune
- Dans la section import-map de `root-config/src/index.ejs`, rajouter les lignes suivantes
```
"imports": {
// Rajouter ces deux imports
"react": "https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js",
// ...import des MFe
}
```
## Etape 3 : app1
- A présent, nous allons créer un premier MFe application (de type `app-parcel`)
- Ouvrir un 2ème terminal
- Depuis le dossier `test_single_spa`, lancer la commande `npx create-single-spa --moduleType app-parcel` puis suivre le wizard
- ? Directory for new project (.) `app1`
- ? Which framework do you want to use? `react`
- ? Which package manager do you want to use? `npm`
- ? Will this project use Typescript? `y`
- ? Organization name `cls`
- ? Project name `app1`
- Dans le `package.json` de ce nouveau projet, changer le `webpack serve` en `webpack serve --port 9001`
- `cd app1`, `yarn start`
- Le plateforme est lancée sur http://localhost:9001/
- Remarquez que l'application n'est pas utilisable telle quelle, pas par défaut en tout cas. Elle doit être utilisée depuis le `root-config`
- Répérez l'adresse du fichier javascript, en l'occurrence `http://localhost:9001/cls-app1.js`
- Puis dans `root-config/src/index.ejs`, rajouter la ligne suivant dans l'import-map `"@cls/app1": "//localhost:9001/cls-app1.js"`
- Et dans `root-config/src/microfrontend-layout.html`, remplacez `<application name="@single-spa/welcome"></application>` par `<application name="@cls/app1"></application>`
- Sur http://localhost:9000/ vous devriez voir "@cls/app1 is mounted!"
## Etape 4 : app2
- Nous allons créer un second MFe application (de type `app-parcel`)
- Ouvrir un 3ème terminal
- Depuis le dossier `test_single_spa`, lancer la commande `npx create-single-spa --moduleType app-parcel` puis suivre le wizard
- ? Directory for new project (.) `app2`
- ? Which framework do you want to use? `react`
- ? Which package manager do you want to use? `npm`
- ? Will this project use Typescript? `y`
- ? Organization name `cls`
- ? Project name `app2`
- A partir de cette étape, il va falloir faire preuve d'imagination
- Dans ce tutoriel, `root-config` et `app1` sont lancés en local, mais en pratique ils seront hébergés sur un serveur et auront chacun leur url
- Imaginons que `app1` et `app2` représentent le même MFe / la même fonctionnalité, et que `app2` est la version locale sur laquelle nous allons travailler
- L'idée est "d'override" `app1` par `app2`
- Dans le `package.json` de ce nouveau projet, changer le `webpack serve` en `webpack serve --port 9002`
- `cd app2`, `yarn start`
- Sur http://localhost:9000/, dans la console, exécuter `localStorage.setItem('devtools', true);` pour activer les devtools, puis faire F5 (opération à réaliser une seule fois)
- Cliquer le symbole devtools en bas à droite de la page, localiser la ligne `@cls/app1`, et coller `//localhost:9002/cls-app2.js` dans le champs `Override URL`
- `app2` est maintenant branchée à la plateforme. Modifiez le fichier `app2/src/root.component.tsx` et constatez les changement
## Pour aller plus loin
- Explorer les MFe de type `Utility`
- Créer plusieurs pages grâce au système de routing intégré par défaut dans le `root-config`
- Brancher le composant d'un framework dans le code d'un autre framework grace au concept de `Parcel`
- Créer un MFe de gestion des données
# SingleSpa tutorial (EN)
## Discovering SingleSpa
- The goal of this tutorial is to discover SingleSPA and the micro-frontend architecture
- For simplicity sake, "micro-frontend" will be called "MFe"
- This tutorial is largely inspired by the [Official Getting Started](https://single-spa.js.org/docs/getting-started-overview)
- The term MFe is inspired by "micro services". We develop isolated and reusable bricks
- A platform built using SingleSPA will be composed by `root-config` MFe and multiple `app-parcel` MFes
- One of the main characteristic of this paradigm (in SingleSPA at least), is that each MFe is hosted on a server and has its own url. We will never launch the entire “project” on our machine, but only the MFe on which we are working
- But for this tutorial, everything will be locally hosted
- Since there is no hierarchy between MFe, we will create a `test_single_spa` folder which will contain all our code
## Step 1 : root-config
- The root of the application is called `root-config` (in SingleSpa)
- In more functional terms, it would be call a platform (Astrée, MAS...)
- Open a 1st terminal
- From the `test_single_spa` folder, run the command `npx create-single-spa --moduleType root-config` then follow the wizard
- ? Directory for new project (.) `root-config`
- ? Which package manager do you want to use? `yarn` (ou autre)
- ? Will this project use Typescript? `y`
- ? Would you like to use single-spa Layout `enter`
- ? Organization name `cls`
- `cd root-config`, `yarn start`
- The platform is launched on http://localhost:9000/
- Note that it includes an example application
- Two important notions
- The `src/index.ejs` file includes the mapping between the names of applications and libraries, and their url
- The `src/microfrontend-layout.html` file allows to compose the MFe (we find the example MFe there)
## Step 2 : Shared libraries
- If a lib is used in several MFe (ex: react), it is possible to define it as a shared dependency
- In the import-map section of `root-config/src/index.ejs`, add the following lines
```
"imports": {
// Rajouter ces deux imports
"react": "https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js",
// ...import des MFe
}
```
## Step 3 : app1
- Now, we are going to create a first MFe application (`app-parcel` type)
- Open a 2nd terminal
- From the `test_single_spa` folder, run the command `npx create-single-spa --moduleType app-parcel` then follow the wizard
- ? Directory for new project (.) `app1`
- ? Which framework do you want to use? `react`
- ? Which package manager do you want to use? `npm`
- ? Will this project use Typescript? `y`
- ? Organization name `cls`
- ? Project name `app1`
- In the `package.json` of this new project, change `webpack serve` into `webpack serve --port 9001`
- `cd app1`, `yarn start`
- The platform is launched on http://localhost:9001/
- Note that the application is not usable as is, not by default anyway. It must be used from the `root-config`
- Locate the address of the javascript file, in this case `http://localhost:9001/cls-app1.js`
- Then in `root-config/src/index.ejs`, add the following line to the import-map `"@cls/app1": "//localhost:9001/cls-app1.js"`
- In `root-config/src/microfrontend-layout.html`, replace `<application name="@single-spa/welcome"></application>` with `<application name="@cls/app1"> </app>`
- On http://localhost:9000/ you should see "@cls/app1 is mounted!"
## Etape 4 : app2
- We will create a second MFe application (of type `app-parcel`)
- Open a 3rd terminal
- From the `test_single_spa` folder, run the command `npx create-single-spa --moduleType app-parcel` then follow the wizard
- ? Directory for new project (.) `app2`
- ? Which framework do you want to use? `react`
- ? Which package manager do you want to use? `npm`
- ? Will this project use Typescript? `y`
- ? Organization name `cls`
- ? Project name `app2`
- From this stage, it will be necessary to show imagination
- In this tutorial, `root-config` and `app1` are launched locally, but in practice they will be hosted on a server and will each have their own url
- Let's imagine that `app1` and `app2` represent the same MFe/feature, and `app2` is the local version we are going to work on
- The idea is to "override" `app1` by `app2`
- In the `package.json` of this new project, replace `webpack serve` with `webpack serve --port 9002`
- `cd app2`, `yarn start`
- On http://localhost:9000/, in the console, run `localStorage.setItem('devtools', true);` to activate the devtools, then press F5 (one-time operation)
- Click the devtools symbol at the bottom right of the page, locate the `@cls/app1` line, and paste `//localhost:9002/cls-app2.js` in the `Override URL` field
- `app2` is now connected to the platform. Edit the `app2/src/root.component.tsx` file and see the changes
## To go further
- Explore `Utility` type MFe
- Create several pages with to the routing system integrated by default in the `root-config`
- Plug the component of a framework into the code of another framework using the concept of `Parcel`
- Create a data management MFe