Przewodnik programisty dotyczący ulepszania struktury projektu w aplikacjach Meteor
Opublikowany: 2022-03-11W ciągu ostatnich kilku lat nastąpił dramatyczny wzrost liczby dostępnych frameworków JavaScript. Począwszy od wypróbowanego i prawdziwego AngularJS do wielu frameworków, które pojawiają się co miesiąc, istnieje imponująca różnorodność do wyboru. Jeden, który przykuł moją uwagę kilka lat temu, to framework o nazwie Meteor. W przeciwieństwie do większości frameworków, Meteor ma być kompletną platformą do tworzenia aplikacji JavaScript. Dla tych, którzy są nowicjuszami w Meteorze, zachęcam do sprawdzenia tego na ich stronie internetowej. Ten artykuł nie będzie wprowadzeniem do Meteoru. Zamiast tego zbadamy kilka prostych sposobów na wprowadzenie struktury w projektach Meteor.
Jedną z wielkich zalet Meteora jest to, że bardzo łatwo jest szybko prototypować złożone aplikacje JavaScript za jego pomocą. Ponieważ Meteor jest hybrydą szablonów i renderowania front-end w połączeniu z serwerem opartym na węzłach współpracującym z MongoDB (ujednolicone rozwiązanie), większość wstępnej konfiguracji niezbędnej do stworzenia aplikacji internetowej z pełnym stosem jest już wykonana za Ciebie. Jednak łatwość rozwoju, jaką to zapewnia, może być pułapką. Podczas tworzenia aplikacji Meteor łatwo jest popaść w złe praktyki i skończyć z mieszaniną nieustrukturyzowanego kodu. Mam kilka sugestii, jak można tego uniknąć.
Rusztowanie: zarządzalna hierarchia katalogów w Meteor
Po pierwsze, podczas tworzenia aplikacji należy zachować zalecaną strukturę folderów. Meteor domyślnie umożliwia umieszczanie plików w dowolnym miejscu w folderze projektu - jeśli chcesz, możesz nawet umieścić cały swój kod w jednym pliku. Chociaż może to działać w przypadku projektu hackathonu, trudno jest zarządzać złożonością związaną ze zwykłymi, skalowalnymi aplikacjami na poziomie produkcyjnym bez solidnej struktury.
Aby rozwiązać ten problem, polecam sprawdzić pakiet npm Chrisa Mathera. Pakiet ma wiele opcji konfiguracyjnych, więc ciężko będzie go tu opisać, ale generalnie buduje strukturę projektu, która będzie wyglądać mniej więcej tak:
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
Jednak w przypadku niektórych projektów taka struktura folderów i plików może być przesadą. Nie każdy projekt będzie musiał mieć tak szczegółowy poziom organizacji, z podziałami na kolekcje, metody i kod publikowania na serwerze. Dla tych, którzy nie mają zbyt dużego projektu lub po prostu nie chcą instalować i uczyć się kolejnego pakietu npm, polecam taką podstawową strukturę folderów:
Kluczowymi elementami są folder publiczny zawierający pliki, takie jak favicon i inne zasoby statyczne, oraz foldery klienta, wspólnego i serwera. Foldery klienta i serwera powinny (oczywiście) zawierać kod, który jest wykonywany odpowiednio na kliencie i serwerze. Wspólny folder zawiera kod, który musi być dostępny zarówno dla klienta, jak i serwera. Przykładem tego jest kod schematu, który omówimy za chwilę.
Istnieją dwa sposoby przeprowadzenia najniższego poziomu organizacji: jeden według typu pliku, a drugi według funkcji. Organizacja według typu pliku oznacza, że na przykład w folderze client/templates znajdują się trzy foldery — jeden dla plików JavaScript, jeden dla CSS i jeden dla HTML. Folder HTML będzie zawierał wszystkie pliki HTML szablonów, na przykład Login.html, Main.html i tak dalej. Foldery JavaScript i CSS będą zawierać odpowiednio pliki szablonów ich typu. Z drugiej strony organizacja według funkcji oznacza organizowanie według koncepcji, którą ucieleśniają pliki. Na przykład w kliencie/szablonach miałbym folder „Login” ze wszystkimi plikami JavaScript, CSS i HTML powiązanymi z procesem logowania do aplikacji. Preferuję organizację według funkcji, ponieważ pozwala to wyraźniej określić, gdzie można znaleźć określone pliki lub fragmenty kodu. Jednak nie jest to czysto czarno-białe, a większość osób i zespołów stosuje mieszankę tych metod, aby uporządkować swoje pliki i foldery.
Schemat: Twoja aplikacja tego potrzebuje, nawet jeśli Twoja baza danych nie
Drugi rodzaj struktury, który chciałbym omówić, jest związany z bazą danych. W tym artykule założono, że używasz MongoDB. Jeśli nie, koncepcje prawdopodobnie będą nadal obowiązywać, ale szczegóły nie. Osoby korzystające z MongoDB wiedzą, że dzięki temu sposób, w jaki przechowujemy nasze dane, jest pozbawiony struktury. Ponieważ MongoDB jest bazą danych magazynu dokumentów NoSQL, nie ma ustalonego schematu dla żadnego „typu” danych. Ta swoboda oznacza, że nie musisz się martwić o upewnienie się, że wszystkie obiekty są ustandaryzowane do jakiejś sztywnej formy, w rzeczywistości wszystkie dane aplikacji mogą zostać wrzucone do jednej kolekcji, jeśli chcesz. Jednak jeśli chodzi o tworzenie aplikacji o jakości produkcyjnej, nie jest to tak pożądane. Aby sobie z tym poradzić i dodać przydatne funkcje, takie jak sprawdzanie poprawności żądań zapisu, możemy skorzystać z dwóch wspaniałych pakietów Meteor: Aldeed's SimpleSchema i Collection2.

Pakiet SimpleSchema, jak sama nazwa wskazuje, umożliwia reaktywną walidację obiektów w Twojej aplikacji. Zapoznaj się z dokumentacją na GitHub. Pakiet Collection2 uruchamia się z SimpleSchema i pozwala na wprowadzenie odpowiednich schematów do kolekcji Meteor. Umożliwia to automatyczną walidację żądań zapisu po stronie klienta i serwera do dowolnej kolekcji z dołączonym do niej schematem. Oba te pakiety są bardzo rozbudowane i można je dostosowywać, więc w kilku akapitach trudno o ich pełne zrozumienie. Raczej polecam zapoznać się ze szczegółowymi plikami readmes, które Aldeed skompilował dla konkretów. Po prostu opowiem o tym, jak zyskałem wartość z tych pakietów. Jedną z najlepszych rzeczy, które umożliwiły, była walidacja danych wejściowych użytkownika. Przydaje się to do sprawdzania poprawności dokumentów użytkownika Meteor (z pakietu Konta). Domyślnie użytkownicy Meteorów mają zaskakująco złożony niejawny schemat. Oto zdjęcie fragmentu kodu, który Aldeed tak uprzejmie udostępnił:
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 } });
To po prostu schemat obiektu profilu użytkownika. Próba sprawdzenia poprawności wszystkich obiektów użytkownika byłaby bałaganem bez specjalnie zbudowanego pakietu, takiego jak SimpleSchema . Chociaż wszystkie te pola pojawiają się na obrazku jako opcjonalne, jeśli chciałbyś mieć prawidłowo zweryfikowany schemat użytkownika, prawdopodobnie nie byłoby to możliwe, a rzeczy takie jak „Schema.UserCountry” w rzeczywistości przekierowują do innych schematów w celu sprawdzenia poprawności. Dołączając ten schemat do obiektu User i integrując go reaktywnie z naszymi formularzami, być może z pakietem takim jak AutoForm Aldeed, możemy uzyskać wysoki stopień kontroli nad tym, co robi, a co nie trafia do naszych baz danych, oszczędzając czas i wysiłek dzięki koncepcyjny model obsługi danych w naszej aplikacji, który można wskazać i omówić na konkretnych warunkach.
Role: dla 401 i 403
Ostatnią sugestią dotyczącą strukturyzowania i ulepszania projektu Meteor jest pakiet Alanning Roles. Jest to system autoryzacji dla Meteor, który pozwala sprawdzić poziomy dostępu użytkowników do dowolnej części aplikacji internetowej. Uprawnienia są dołączone do profilu użytkownika w postaci ciągów, które są później sprawdzane lub unieważniane, gdy użytkownik próbuje uzyskać dostęp do jakichkolwiek metod Meteor lub danych opublikowanych dla klienta. Na przykład:
if (Roles.userIsInRole(Meteor.userId(), "admin")) { tabsArr.push({ name: "Users", slug: "users" }); }
Chociaż rdzeń systemu jest stosunkowo prosty, pozwala na złożone i szczegółowe uprawnienia do dowolnej części aplikacji. Ponieważ wszystkie role są przechowywane jako ciągi, możesz skonfigurować dowolny system — „admin”, „admin.division1.manage”, „admin.division1.manage.group2” i tak dalej.
Problem ze swobodą, jaką zapewnia ten pakiet, polega na tym, że śledzenie bardzo szczegółowego systemu ról może być trudne. Pakiet udostępnia funkcje, takie jak „getAllRoles”, które, jak sama nazwa wskazuje, pobierają wszystkie utworzone role, ale to od Ciebie zależy, jakie są ich znaczenia i kiedy dana rola powinna być użytym. A dla tych, którzy są ciekawi, jaka jest różnica między „rolami” a „uprawnieniami”, na potrzeby tego pakietu zasadniczo nie różnią się one od siebie.
Zawijanie
Niestety, ze względu na obszerność artykułu (każdy z wymienionych tutaj pakietów zasługuje na własny samouczek) nie było możliwe szczegółowe omówienie żadnego konkretnego pakietu, ale mam nadzieję, że rzuciłem trochę światła na to, jak można pracować nad „ustandaryzowanym „Aplikacja Meteor, której możesz mieć pewność, sprawdzi się w produkcji i na dużą skalę. Jeśli szukasz więcej informacji, sprawdź zamieszczone przeze mnie linki i spójrz na jeszcze jedną rzecz, która nie znalazła się w tym artykule, ale jest przydatna w aplikacji Meteor: pakiet Restivus, który pozwala w celu łatwego udostępnienia interfejsu API REST dla Twojej aplikacji.
Zrzeczenie się, że nie jestem autorem żadnego z tych pakietów i przepraszam, jeśli błędnie przedstawiłem jakiekolwiek cechy lub cele jakiegokolwiek pakietu. Dziękuję za przeczytanie i mam nadzieję, że ten artykuł był dla Ciebie korzystny. Jeśli masz jakiekolwiek pytania, skontaktuj się ze mną lub zostaw komentarz poniżej.