|
|
|
[TOC](./../../..)
|
|
|
|
# WP React
|
|
|
|
|
|
|
|
_Solució per injectar components de React al DOM generat per WordPress sense necessitat d'incrustació via `<iframe />`_.
|
|
|
|
|
|
|
|
Amb aquesta funcionalitat es vol aconseguir un mètode per reutilitzar parts de la lògica de la aplicació frontend fora del seu context. En concret, **ha de permetre reutilitzar els components de React encarregats dels fluxes de contractació i d'alta de sòcia sense necessitat de carregar tota l'aplicació a través d'un iframe**. Amb aquesta metodologia aconseguim una optimització dels temps de càrrega de la pàgina web de Som Connexió alhora que simplifiquem la gestió de maquetació de les pàgines d'alta i de contractació, que deixaran d'estar segmentades en dos contextos independents (dom i iframe) amb totes les dificultats de sincronització que això comporta, a més de reduir la complexitat dels sistemes d'analítiques per fer seguiment dels _leads_ ja que tot el procés es donarà sota el domini píublic de la pàgina web [somconnexio.coop](https://somconnexio.coop).
|
|
|
|
|
|
|
|
## React
|
|
|
|
|
|
|
|
**React es una llibreria de JavaScript per construir interfícies d'usuari**. React no és un _framework_ –ni tan sols és una llibreria acotada a la web. S'utilitza de la ma d'altres llibreries encarregades de renderitzar els seus components en funció de l'entorn. Per exemple, [React Native](https://reactnative.dev/) pot ser utilitzat per desenvolupar aplicacions mòbils.
|
|
|
|
|
|
|
|
**Quan desenvolupem aplicacions amb React per a l'entorn web fem ús de [ReactDOM](https://react.dev/reference/react#react-dom)**. Sobint, ens referim a React i ReactDOM com a _frameworks_, ja que resolen els mateixos problemes que altres _frameworks_, però el fet que React per si sol no sigui una solució completa per al desenvolupament web i necessiti treballar orquestrat amb altres llibreries és el que ens impedeix considerar-lo com a tal.
|
|
|
|
|
|
|
|
L'objectiu principal de React és el de minimitzar els errors que succeeixen durant el desenvolupament de UIs. Això ho acompleix gràcies a l'ús de components —blocs lògics de codi autoncontinguts que descriuen procions de la interfície d'usuari. Aquests components poden ser conjugats per crear una UI completa abstraient-se del treball de renderització, permetent a la persona desenvolupadora contentrar-se en el disseny de la UI.
|
|
|
|
|
|
|
|
## React DOM
|
|
|
|
|
|
|
|
**El paquet ReactDOM és una llibreria encarregada de gestionar la renderització de components de React en entorns web** representant-los com a elements d'un [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) o com a HTML.
|
|
|
|
|
|
|
|
La llibrerira ens exposa dos punts d'entrada:
|
|
|
|
|
|
|
|
1. [react-dom/client](https://react.dev/reference/react-dom/client): Aquestes APIs et permet renderitzar components de React a la banda del client (el navegador). Aquestes APIs son utilitzades tipicament a l'arrel del teu arbre de components per iniciar el teu arbre de components i injectar-lo al DOM del navegador.
|
|
|
|
2. [react-dom/server](https://react.dev/reference/react-dom/server): Aquestes APIs et permeten renderitzar components de React com a text HTML a la banda del servidor. Aquestes APIs només s'utilitzen a l'arrel de les aplicacions per transformar l'arbre de components en la seva representacio HTML.
|
|
|
|
|
|
|
|
WP React farà ús de les APIs `react-dom/client` per tal de renderitzar els components de la nostra oficina virtual dins el DOM generat per WordPress.
|
|
|
|
|
|
|
|
### createRoot
|
|
|
|
|
|
|
|
La funció `createRoot` del mòdil `react-dom/client` ens permet crear un node arrel d'on fer penjar els teus components de React dins d'un node DOM. React prendrà el control del DOM descendent del node arrel. Sovint, quan treballem amb React, treballem fent aplicacions gestionades totalment per la llibreria vinculades a un arxiu HTML amb un sol node que ens servira com a arrel per al nostre arbre de components de React, però també és possible delegar en React parts parcials del nostre DOM i fer ús de la funció `createRoot` múltiples cops en una mateixa pàgina per mostrar components de react.
|
|
|
|
|
|
|
|
A continuació es mostra un exemple de com podem utilitzar React per gestionar dos parts diferents del DOM, la nevagació i els comentaris, sense que React prengui el control de tot el DOM de la pàgina.
|
|
|
|
|
|
|
|
**index.html**
|
|
|
|
```html
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head><title>My app</title></head>
|
|
|
|
<body>
|
|
|
|
<nav id="navigation"></nav>
|
|
|
|
<main>
|
|
|
|
<p>This paragraph is not rendered by React (open index.html to verify).</p>
|
|
|
|
<section id="comments"></section>
|
|
|
|
</main>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
```
|
|
|
|
|
|
|
|
**index.js**
|
|
|
|
|
|
|
|
```jsx
|
|
|
|
import './styles.css';
|
|
|
|
import { createRoot } from 'react-dom/client';
|
|
|
|
import { Comments, Navigation } from './Components.js';
|
|
|
|
|
|
|
|
const navDomNode = document.getElementById('navigation');
|
|
|
|
const navRoot = createRoot(navDomNode);
|
|
|
|
navRoot.render(<Navigation />);
|
|
|
|
|
|
|
|
const commentDomNode = document.getElementById('comments');
|
|
|
|
const commentRoot = createRoot(commentDomNode);
|
|
|
|
commentRoot.render(<Comments />);
|
|
|
|
```
|
|
|
|
|
|
|
|
**Components.js**
|
|
|
|
```jsx
|
|
|
|
export function Navigation() {
|
|
|
|
return (
|
|
|
|
<ul>
|
|
|
|
<NavLink href="/">Home</NavLink>
|
|
|
|
<NavLink href="/about">About</NavLink>
|
|
|
|
</ul>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function NavLink({ href, children }) {
|
|
|
|
return (
|
|
|
|
<li>
|
|
|
|
<a href={href}>{children}</a>
|
|
|
|
</li>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Comments() {
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<h2>Comments</h2>
|
|
|
|
<Comment text="Hello!" author="Sophie" />
|
|
|
|
<Comment text="How are you?" author="Sunil" />
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function Comment({ text, author }) {
|
|
|
|
return (
|
|
|
|
<p>{text} — <i>{author}</i></p>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Implementació
|
|
|
|
|
|
|
|
Fent ús de les APIs de ReactDOM podem crear nodes arrel per a una aplicació de React i injectar-los dins un DOM preexistent perquè prenguin el control d'una de les seves branques. Com hem vist, això és una solució estandard que utilitza les APIs nadives de React i ReactDOM. El repte és el següent: **Configurar múltiples rutines de transpilació del codi de frontend per tal d'aconseguir encapsular en mòduls distribuibles diferents versions del nostre arbre de components de React amb l'objectiu de reutilitzar la lògica de l'aplicació fora del seu context**. Un cop disposem d'aquests mòduls, haurem de fer que aquests estiguin disponbiles a l'entorn de WordPress perquè aquest pugui carregar-los amb el seu sistema de càrrega de _scripts_ i instanciar-los a les seves pàgines.
|
|
|
|
|
|
|
|
### Transpilació i empaquetament
|
|
|
|
|
|
|
|
El frontend de l'oficina virtual de Som Connexió està creat amb l'utilitat [`create-react-app`](https://create-react-app.dev). Aquesta utilitat ens permet crear entorns de desenvolupament autoconfigurats per a aplicacions de React de tipus _single page applications_. Els entorns de desenvolupament generats per aquesta útilitat gestionen la configuració com un paquet extern actualitzable amb el sistema de dependències de npm. D'aquesta forma, els equips de desenvolupament externalitzen la necessitat de gestió i manteniment de la configuració i s'adequen als estandards definits per la utilitat. El resultat és la possibilitat de disposar d'un entorn de desenvolupament llest per ser productiu en questió de segons que implementa els millors estandards a nivell de solucions tecnològiques i sense necessitat de dedicacions destinades al seu manteniment. Com a contrapartida, disposarem d'un entorn de treball que amaga els arxius de configuració i que gestiona de forma externalitzada i no personalitzable les eines de desenvolupament disponibles. Això pot ser problemàtic si no esperes que la teva aplicació de React funcioni com una _single page application_. Aquestes limitacions són les que han portat a la exposició a la web pública dels fluxes de contractació i alta a través de la incrustació via iframe de tota l'aplicació de la oficina virtual sota el subdomini [oficinavirtual.somconnexio.coop](https://oficinavirtual.somconnexio.coop)
|
|
|
|
|
|
|
|
Al abordar la necessitat de diferents rutines de transpilació i empaquetament del nostre codi per tal de generar diferents distribuibles de complexitat variable ens topem amb la impossibilitat de solucionar el problema amb configuracions personalitzades de les eines de compilació, pel que hem d'optar per solucions que es donguin a nivell de codi (que sí que està sota el nostre domini).
|
|
|
|
|
|
|
|
L'estrategia seguida és la de configurar, a nivell de codi, importacions de mòduls condicionals en base al valor de variables d'entorn. Exemple:
|
|
|
|
|
|
|
|
```jsx
|
|
|
|
import React from "react";
|
|
|
|
import ReactDOM from "react-dom/client";
|
|
|
|
|
|
|
|
if (process.env.FOO === "bar") {
|
|
|
|
const App = require("./App.js");
|
|
|
|
} else {
|
|
|
|
const App = require("./Forms.js");
|
|
|
|
}
|
|
|
|
|
|
|
|
const root = ReactDOM.createRoot(document.querySelector("#root"));
|
|
|
|
root.render(<App />);
|
|
|
|
```
|
|
|
|
|
|
|
|
#### CJS vs ESM
|
|
|
|
|
|
|
|
### React Router
|
|
|
|
|
|
|
|
### Configuració HTTP CORS de la API
|
|
|
|
|
|
|
|
### Desplegament
|
|
|
|
|
|
|
|
Per al desplegament dels mòduls generats amb aquesta metodologia farem ús del sistema d'integració continuna de Gitlab. |
|
|
\ No newline at end of file |