Tempo di lettura: 12 minuti
Prosegue la serie di tutorial dedicata alla libreria js di facebook. In questo vedremo come fare il Deployng di un App React in rete. Prenderemo in esame l’applicazione Heroes vista nella prima guida.
Il backend ,realizzato con nodeJs ed Express sarà quello visto nella seconda guida.
NOTA BENE: IN ENTRAMBE LE GUIDE VIENE DESCRITTO COME CLONARE I PROGETTI, FATELO PER POTER PROSEGUIRE.
Al momento questa riceve i dati in ingresso da json-server:
service/heroes.js
const baseurl = 'http://localhost:3003/heroes'
quindi cambiamo tale url e facciamo in modo che punti a:
import Axios from "axios"; const baseurl = 'http://localhost:3001/heroes/api/heroes' /**VISUALIZZA */ const getAll = () => { const request = Axios.get(baseurl) return request.then(response => response.data) } /**CREA */ const create = newObj => { const request = Axios.post(baseurl, newObj) return request.then(response => response.data) } /**MODIFICA */ const update = (id, newObj) => { const request = Axios.put(`${baseurl}/${id}`, newObj) return request.then(response => response.data) } /**ELIMINA */ const deleteHero = id => { const request = Axios.delete(`${baseurl}/${id}`) return request.then(response => response.data) } export default {getAll,create,update,deleteHero}
quindi aprite l’applicazione relativa al backend ed avviatela con il comando npm run dev, avviate anche il frontend Heroes con npm start. Se puntate l’indirizzo http://localhost:3000/ noterete subito un errore:
se provate con Postman funziona senza problemi:
Deploiyng di un App React: cors origin
Il problema risiede alla politica dei CORS o Cross-Origin Resource Sharing.
Secondo Wikipedia:
Cross-origin resource sharing (CORS) è un meccanismo che consente di richiedere risorse limitate (ad esempio caratteri) su una pagina web da un altro dominio esterno al dominio da cui è stata servita la prima risorsa. Una pagina web può incorporare liberamente immagini, fogli di stile, script, iframe e video cross-origin. Alcune richieste “interdominio”, in particolare richieste Ajax, sono vietate per impostazione predefinita dalla policy di sicurezza della stessa origine.
Nel nostro contesto il problema è che, per impostazione predefinita, il codice JavaScript di un’applicazione che viene eseguita in un browser può comunicare solo con un server nella stessa origine . Poiché il nostro server si trova nella porta localhost 3001 e il nostro frontend nella porta localhost 3000, non hanno la stessa origine.
Tieni presente che la stessa policy di origine e CORS non sono specifici per React o Node. Sono infatti principi universali del funzionamento delle applicazioni web.
Possiamo consentire richieste da altre origini utilizzando il middleware cors di Node .
Installa cors nel backend con il comando:
npm install cors
quindi usa il middleware da utilizzare e consentire le richieste da tutte le origini:
index.js
... const cors = require('cors') app.use(cors()) ...
ora come per magia se avviate l’applicazione:
funziona senza problemi.
Servire l’applicazione su internet con Heroku
Siamo finalmente pronti per spostare la nostra applicazione su Internet, per far ciò utilizzeremo Heroku. Se non lo conosci ti consiglio di leggere la documentazione ufficiale.
Aggiungi un file chiamato Procfile nella root principale del progetto e scrivi:
web: npm start
Questo fa capire ad Heroku come avviare l’applicazione.
Ora cambia la definizione della porta utilizzata nella nostra applicazione nel file index.js del backend:
... const PORT = process.env.PORT || 3001 app.listen(PORT) console.log(`Server running on port ${PORT}`)
in pratica gli abbiamo detto di utilizzare la porta definita nella variabile d’ambiente PORT oppure , se questa non fosse definita, la 3001. Heroku configura la porta dell’applicazione in base alla variabile d’ambiente.
Crea un repository git nella directory del progetto, aggiungi il file .gitignore con il seguente contenuto:
node_modules
in pratica diciamo a git di non importare la cartella node_modules ( se non conosci git puoi leggerti questo).
Crea un’applicazione Heroku con il comando :
heroku create
Nb: ti ricordo che per poter creare app su Heroku devi avere un account in git, leggi la documentazione.
se tutto va bene nel terminale ci troviamo:
fate click nel primo indirizzo, nel mio caso su https://ancient-ridge-82050.herokuapp.com/ vi si apre:
una volta creato il repository e l’applicazione Heroku aggiungiamo l’applicazione in esso quindi da terminale digitiamo in ordine:
git add . git commit -m"First commit" git push heroku --set-upstream origin master
Se tutto è andato bene , l’applicazione funziona:
In caso contrario, il problema può essere trovato leggendo i registri di heroku con il comando heroku logs .
NB Almeno all’inizio è bene tenere sempre d’occhio i log di heroku. Il modo migliore per farlo è con il comando heroku logs -t che stampa i log sulla console ogni volta che succede qualcosa sul server.
NB Se stai distribuendo da un repository git dove il tuo codice non è sul ramo principale (cioè se stai alterando il repository degli eroi dall’ultima lezione) dovrai eseguire git push heroku HEAD: tuo branch. Se hai già eseguito un push su heroku, potresti dover eseguire git push heroku HEAD: main –force .
Bene ora aprite il frontend ed aggiornate l’indirizzo che punta a localhost/3001 con quello relativo all’applicazione Heroku appena creata:
service/heroes.js
... const baseurl = 'http://localhost:3001/api/heroes' ...
a così, nel mio caso:
... const baseurl = 'https://intense-taiga-53023.herokuapp.com/api/heroes' ...
quindi avviatela con npm start.
La Build di produzione sul frontend
Fino ad ora abbiamo eseguito il codice React in modalità di sviluppo. Questa è configurata in maniera tale da fornire messaggi di errori chiari, eseguire immediatamente il rendering delle modifiche e così via.
Per la distribuzione dell’applicazione in rete dobbiamo crearne una versione ottimizzata con i soli file necessari al funzionamento della stessa in modo tale da renderla più leggera possibile. In poche parole dobbiamo effettuare la build di produzione.
Aprite il frontend e da terminale digitate:
npm run build
attendete qualche istante e noterete che questi crea una directory nella radice del progetto chiamata appunto build
con una serie di file all’interno, tanto quanto bastano affinchè il progetto funzioni correttamente.
Come potete notare, dall’immagine, contiene un unico file index.html. Tutto il codice js, compreso le dipendenze, vengono minimizzati in esso.
Aggiungi la build al backend
Un’opzione per la distribuzione del frontend è quella di copiare la build all’interno del progetto del backend. Se utilizzi mac o linux puoi eseguire semplicemente tale comando (chiaramente in base ai tuoi percorsi):
cp -r build ../../../osa3/notes-backend
se invece utilizzi windows utilizza il seguente comando(utilizza i tuoi percorsi):
xcopy build "F:\APP\REACT\forBlog\backend\build"/s
in pratica, dalla radice del progetto del frontend, inserisco il comando Ms-dos xcopy con il nome della directory da copiare build, quindi tra doppi apici inserisco il percorso di destinazione (da notare che mi ero anche creato nel backend una directory di nome build). Nota bene potresti anche non crearti la directory, una volta digitato il comando questa ti chiede se vuoi copiarli all’interno della stessa, dai conferma:
il ‘/s’ alla fine della stringa fa si che vengano copiate directory e sottodirectory, se lo avessi omesso non mi avrebbe copiato la cartella static fondamentale per il corretto funzionamento dell’applicazione(contiene tutti i file js). Leggi la documentazione ufficiale se vuoi saperne di più.
Per fare in modo che express mostri del contenuto statico come ad esempio la pagina index.html, Javascript, ecc…occorre un middleware integrato in express chiamato static.
Aprite il file index.js del backend ed aggiungete:
app.use(express.static('build'))
in questo modo ogni volta che express riceve una richiesta HTTP GET, verificherà prima se la directory di build contiene un file corrispondente all’indirizzo della richiesta. Se trova quello corretto essa lo restituirà.
Visto che ora , sia il frontend che il backend si trovano al solito indirizzo, possiamo dichiarare la costante baseUrl del service(frontend) come un URL relativo, quindi:
service/heroes.js
... const baseurl = 'https://intense-taiga-53023.herokuapp.com/api/heroes' ...
a così:
const baseurl = '/api/heroes'
dopo aver fatto la modifica dobbiamo rifare la build del progetto e copiarla nel server.
Se tutto è andato per il verso giusto avremo:
proviamo ora a ‘pusciare’ tutto su heroku:
git push heroku HEAD:main
vi ricordo che io mi trovo su un branch diverso da quello principale di heroku per cui devo inserire la stringa HEAD, in caso contrario avrei potuto utilizzare direttamente:
git push heroku main
quindi al link del mio heroku https://intense-taiga-53023.herokuapp.com/ ottengo:
ottimo direi 🙂 🙂 la nostra applicazione funziona perfettamente anche in remoto anche se dobbiamo ancora implementare la scelta dell’importanza dell’eroe.
Razionalizzare la distribuzione del frontend
Come avrete di certo notato ogni volta che facciamo una modifica nel frontend, dobbiamo rifare la build e quindi ricopiarla nel backend. Per evitare tutti questi passaggi possiamo aggiungere alcuni script nel file package.json del nostro backend:
... "build:ui": "rm -rf build && cd F:/APP/REACT/forBlog/heroes && npm run build --prod && cp -r build F:/APP/REACT/forBlog/backend/", "deploy": "git push heroku HEAD:main", "deploy:full": "npm run build:ui && git add . && git commit -m uibuild && npm run deploy", "logs:prod": "heroku logs --tail" ...
Nota bene: io inserisco nella riga “deploy” git push heroku HEAD:main in quanto in locale mi trovo in un ramo diverso dal principale, in caso contrario basta inserire git push heroku main o master 😉
Lo script npm run build: ui compila il frontend e copia la versione di produzione nel repository di backend. npm run deploy rilascia il backend corrente a heroku.
npm run deploy: full combina questi due e contiene i comandi git necessari per aggiornare il repository di backend.
C’è anche uno script npm run logs: prod per mostrare i log di heroku.
Notare che i percorsi delle directory nello script build: ui dipendono dalla posizione dei repository nel file system.
Deployng di un App React:Proxy
Se avviate il server dal frontend, quindi in modalità di sviluppo, noterete che l’applicazione non funziona in quanto abbiamo riportato dei cambiamenti a livello di connessione API, infatti il backend non risponde.
Naturalmente ciò è dovuto alla modifica dell’indirizzo backend in un URL relativo:
const baseurl = '/api/heroes'
Poiché in modalità di sviluppo il frontend è all’indirizzo localhost: 3000 , le richieste al backend vanno all’indirizzo errato localhost: 3000 / api / heroes . Il backend è in localhost: 3001 .
Se il progetto è stato creato con create-react-app, questo problema è facile da risolvere. È sufficiente aggiungere la seguente dichiarazione al file package.json del repository di frontend.
{ "dependencies": { // ... }, "scripts": { // ... }, "proxy": "http://127.0.0.1:3001"
Dopo un riavvio, l’ambiente di sviluppo React funzionerà come proxy . Se il codice React esegue una richiesta HTTP a un indirizzo del server in http: // localhost: 3000 non gestito dall’applicazione React stessa (cioè quando le richieste non riguardano il recupero del CSS o JavaScript dell’applicazione), la richiesta verrà reindirizzata a il server all’indirizzo http: // 127.0.0.1: 3001 .
Ora anche il frontend va bene, lavorando con il server sia in modalità di sviluppo che di produzione.
Un aspetto negativo del nostro approccio è quanto sia complicato distribuire il frontend. La distribuzione di una nuova versione richiede la generazione di una nuova build di produzione del frontend e la copia nel repository di backend. Ciò rende più difficile la creazione di una pipeline di distribuzione automatizzata . Pipeline di distribuzione indica un modo automatizzato e controllato per spostare il codice dal computer dello sviluppatore attraverso diversi test e controlli di qualità all’ambiente di produzione.
Esistono diversi modi per ottenere ciò (ad esempio, posizionare sia il codice di backend che di frontend nello stesso repository ) ma non li approfondiremo ora.
In alcune situazioni potrebbe essere opportuno distribuire il codice frontend come propria applicazione. Con le app create con create-react-app è semplice .
Il codice corrente del backend può essere trovato su Github , nel ramo deploiyng-app_part_2 . I cambiamenti nel codice del frontend sono nel ramo proxy del repository del frontend .
Vi ricordo che per clonare uno specifico branch di un repository remoto a locale dovete eseguire il seguente comando:
git clone -b <nome branch da clonare> https://github.com/freewebsolution/React2.0.git <cartella da creare in locale>
Se volete Approfondire le conoscenze su Git e GIT hub potete seguire il corso completo su Udemy sempre scontato a 9.99/12.99 € , inoltre, nel momento in cui non foste soddisfatti, avete la possibilità di ottenere il rimborso completo dello stesso entro 30 giorni dalla data di acquisto!