Guida per gli sviluppatori al miglioramento della struttura del progetto nelle applicazioni Meteor
Pubblicato: 2022-03-11Negli ultimi anni, c'è stato un drammatico aumento del numero di framework JavaScript disponibili. A partire dal collaudato AngularJS al numero di framework che escono ogni mese, c'è un'impressionante diversità tra cui scegliere. Uno che ha attirato la mia attenzione alcuni anni fa è un framework chiamato Meteor. A differenza della maggior parte dei framework, Meteor mira a essere una piattaforma completa per lo sviluppo di app JavaScript. Per coloro che non conoscono Meteor, ti incoraggio a dare un'occhiata sul loro sito web. Questo articolo non sarà un'introduzione a Meteor. Invece, esploreremo alcuni semplici modi per introdurre la struttura nei progetti Meteor.
Uno dei grandi vantaggi di Meteor è che è molto facile prototipare rapidamente applicazioni JavaScript complesse con esso. Poiché Meteor è un ibrido di modellazione e rendering front-end accoppiato con un server basato su Node che interagisce con MongoDB (una soluzione unificata), la maggior parte della configurazione iniziale necessaria per la creazione di un'app Web full-stack è già stata eseguita per te. Tuttavia, la facilità di sviluppo che questo fornisce può essere una trappola. È facile cadere in cattive pratiche e ritrovarsi con un guazzabuglio di codice non strutturato durante la creazione di un'app Meteor. Ho alcuni suggerimenti su come questo può essere evitato.
Scaffolding: gerarchia di directory gestibile in Meteor
Innanzitutto, è importante mantenere la struttura delle cartelle consigliata durante la creazione dell'applicazione. Meteor ti consente di posizionare i file ovunque all'interno della cartella del progetto per impostazione predefinita: puoi persino avere tutto il tuo codice in un unico file, se lo desideri. Anche se questo potrebbe funzionare per un progetto di hackathon, la complessità sostenuta dalle solite app scalabili a livello di produzione è difficile da gestire senza una solida struttura.
Per risolvere questo problema, ti consiglio di dare un'occhiata al package iron npm di Chris Mather. Il pacchetto ha una varietà di opzioni di configurazione, quindi sarà difficile da descrivere qui, ma in generale costruisce una struttura di progetto che assomiglierà a questa:
my-app/ |- .iron/ |- config.json |- bin/ |- build/ |- config/ |- development/ |- env.sh |- settings.json |- app/ |- client/ |- collections/ |- lib/ |- stylesheets/ |- templates/ |- head.html |- lib/ |- collections/ |- controllers/ |- methods.js |- routes.js |- packages/ |- private/ |- public/ |- server/ |- collections/ |- lib |- methods.js |- publish.js |- bootstrap.js
Tuttavia, per alcuni progetti una struttura di cartelle e file come questa può essere eccessiva. Non tutti i progetti dovranno avere un livello di organizzazione così dettagliato, con separazioni per raccolte, metodi e codice di pubblicazione sul server. Per coloro che non hanno un progetto troppo grande o semplicemente non vogliono installare e imparare un altro pacchetto npm, consiglio questa struttura di cartelle di base:
Gli elementi chiave sono una cartella pubblica che contiene file come la tua favicon e altre risorse statiche e le cartelle client, comuni e server. Le cartelle client e server dovrebbero (ovviamente) contenere codice che viene eseguito rispettivamente sul client e sul server. La cartella comune contiene il codice che deve essere accessibile sia al client che al server. Un esempio di questo è il codice Schema, di cui parleremo tra poco.
Esistono due modi per eseguire il livello di organizzazione più basso: uno è per tipo di file e il secondo è per funzione. L'organizzazione per tipo di file significa che nella cartella client/modelli, ad esempio, avrai tre cartelle: una per i file JavaScript, una per i CSS e una per l'HTML. La cartella HTML conterrà tutti i file HTML del modello, ad esempio Login.html, Main.html e così via. Le cartelle JavaScript e CSS conterranno rispettivamente file modello del loro tipo. Organizzare per funzione, invece, significa organizzare in base al concetto che i file incarnano. Ad esempio, in client/modelli, avrei una cartella "Login", con tutti i file JavaScript, CSS e HTML associati al processo di accesso dell'app. Preferisco l'organizzazione per funzione in quanto ti consente di essere più chiaro su dove puoi trovare determinati file o parti di codice. Tuttavia, non è puramente in bianco e nero e la maggior parte degli individui e dei team ha trovato una combinazione di questi metodi per strutturare i propri file e cartelle.
Schema: la tua app ne ha bisogno anche se il tuo database non lo fa
Il secondo tipo di struttura di cui vorrei parlare è associato al database. Questo articolo presuppone che tu stia utilizzando MongoDB. In caso contrario, i concetti probabilmente si applicheranno ancora, ma non le specifiche. Coloro che utilizzano MongoDB sanno che consente di non strutturare il modo in cui memorizziamo i nostri dati. Poiché MongoDB è un database di archivio documenti NoSQL, non esiste uno schema fisso per alcun "tipo" di dati. Questa libertà significa che non devi preoccuparti di assicurarti che tutti gli oggetti siano standardizzati in una forma rigida, infatti, tutti i dati della tua app potrebbero essere inseriti in un'unica raccolta se lo desideri. Tuttavia, quando si tratta di creare app di qualità di produzione, questo non è proprio desiderabile. Per gestire questo e aggiungere funzionalità utili come la convalida delle richieste di scrittura, possiamo rivolgerci a due meravigliosi pacchetti Meteor: SimpleSchema e Collection2 di Aldeed.

Il pacchetto SimpleSchema, come suggerisce il nome, ti consente di convalidare reattivamente gli oggetti nella tua app. Dai un'occhiata ai documenti su GitHub. Il pacchetto Collection2 esegue il bootstrap di SimpleSchema e consente di portare gli schemi appropriati alle raccolte di Meteor. Ciò che ciò consente è la convalida automatica delle richieste di scrittura lato client e server in qualsiasi raccolta con uno schema collegato. Entrambi questi pacchetti sono molto profondi e personalizzabili, quindi è difficile darne una comprensione completa in pochi paragrafi. Piuttosto, ti consiglio di guardare i readme dettagliati che Aldeed ha compilato per i dettagli. Parlerò semplicemente di come ho ottenuto valore da questi pacchetti. Una delle cose migliori che hanno abilitato è stata la convalida dell'input del modulo dell'utente. Questo è utile per convalidare i documenti Meteor User (dal pacchetto Accounts). Per impostazione predefinita, gli utenti di Meteor hanno uno schema implicito sorprendentemente complesso. Ecco un'immagine di una parte del codice che Aldeed è stato così gentile da rendere disponibile:
Schema.UserProfile = new SimpleSchema({ firstName: { type: String, optional: true }, lastName: { type: String, optional: true }, birthday: { type: Date, optional: true }, gender: { type: String, allowedValues: ['Male', 'Female'], optional: true }, organization : { type: String, optional: true }, website: { type: String, regEx: SimpleSchema.RegEx.Url, optional: true }, bio: { type: String, optional: true }, country: { type: Schema.UserCountry, optional: true } });
Questo è semplicemente lo schema per l'oggetto profilo dell'utente. Tentare di convalidare tutto l'oggetto User sarebbe un pasticcio senza un pacchetto appositamente creato come SimpleSchema . Sebbene tutti questi campi appaiano facoltativi nell'immagine, se si desidera uno schema utente correttamente convalidato probabilmente non lo sarebbero e cose come "Schema.UserCountry" reindirizzano effettivamente ad altri schemi per la convalida. Allegando questo schema all'oggetto User e integrandolo in modo reattivo ai nostri moduli, magari con un pacchetto come AutoForm di Aldeed, possiamo ottenere un buon grado di controllo su ciò che fa e non lo fa nei nostri database, risparmiando tempo e fatica con un modello concettuale di come i dati vengono gestiti nella nostra applicazione che può essere indicato e discusso in termini concreti.
Ruoli: Per i 401 e 403
L'ultimo suggerimento che ho per strutturare e migliorare un progetto Meteor è il pacchetto Ruoli di Alanning. Questo è un sistema di autorizzazione per Meteor e ti consente di controllare i livelli di accesso degli utenti per qualsiasi parte della tua app web. Le autorizzazioni sono allegate al profilo Utente sotto forma di stringhe che vengono successivamente convalidate o invalidate quando l'utente tenta di accedere a qualsiasi metodo Meteor o dato pubblicato sul client. Per esempio:
if (Roles.userIsInRole(Meteor.userId(), "admin")) { tabsArr.push({ name: "Users", slug: "users" }); }
Sebbene il nucleo del sistema sia relativamente semplice, consente autorizzazioni complesse e dettagliate per qualsiasi parte dell'applicazione. Poiché tutti i ruoli sono archiviati come stringhe, puoi configurare un sistema profondo quanto vuoi: "admin", "admin.division1.manage", "admin.division1.manage.group2" e così via.
Il problema con la libertà che questo pacchetto consente è che può essere difficile tenere traccia di un sistema di ruoli altamente granulare. Il pacchetto fornisce funzioni come "getAllRoles" che, come suggerisce il nome, recupera tutti i ruoli che hai creato, ma spetta a te tenere traccia di quali sono tutti i loro significati e quando un determinato ruolo dovrebbe essere utilizzato. E per coloro che sono curiosi di sapere quale sia la differenza tra "ruoli" e "permessi", ai fini di questo pacchetto non sono sostanzialmente diversi.
Avvolgendo
Purtroppo, vista l'ampiezza dell'articolo (ciascuno dei pacchetti qui menzionati merita un proprio tutorial) non è stato possibile entrare nel dettaglio di nessun pacchetto in particolare, ma spero di aver fatto luce su come si può lavorare verso un "standardizzato ” L'applicazione Meteor di cui puoi essere certo funzionerà bene in produzione e su larga scala. Se stai cercando maggiori informazioni, dai un'occhiata ai link che ho postato e dai un'occhiata a un'altra cosa che non è arrivata a questo articolo, ma è utile avere in un'app Meteor: il pacchetto Restivus, che ti consente per esporre facilmente un'API REST per la tua app.
Come disclaimer, non sono l'autore di nessuno di questi pacchetti e mi scuso se ho travisato una qualsiasi delle caratteristiche o degli obiettivi di qualsiasi pacchetto. Grazie per aver letto e spero che questo articolo ti sia stato di beneficio. Sentiti libero di contattarmi per qualsiasi domanda tu possa avere o lascia un commento qui sotto.