Ruby on Rails modularization με Packwerk Episode II
Nicolas Nisoria
Στο δεύτερο επεισόδιο της σπονδυλωτής οργάνωσης Ruby on Rails με την Packwerk θα εξετάσουμε προσεκτικά την έννοια της εφαρμογής ως πακέτο.
Εφαρμογή ως πακέτο
Η προσέγγιση για την αρθρωτή διαμόρφωση της εφαρμογής μας συνίσταται στη μετατροπή ολόκληρης της εφαρμογής σε ένα πακέτο.
Δημιουργήστε τη δομή
Πρώτα, πρέπει να δημιουργήσουμε app/packages όπου θα τοποθετήσουμε όλα τα πακέτα μας. Για να απομονώσουμε τα πακέτα μας πρέπει να διαχωρίσουμε κάθε Έννοια MVC σε έναν φάκελο. Λαμβάνοντας το CodeTriage έργο ως παράδειγμα θα έχουμε κάτι σαν την ακόλουθη εικόνα.
Αν προσπαθήσουμε να τρέξουμε τον διακομιστή, θα αποτύχει να βρει τις σταθερές. Γι' αυτό πρέπει να προσθέσουμε μια γραμμή ρυθμίσεων στο application.rb
Τώρα η εφαρμογή λειτουργεί, αλλά δεν μπορεί να βρει τις προβολές, οπότε πρέπει να προσθέσουμε άλλη μια γραμμή ρυθμίσεων στο αρχείο μας application_controller.rb
Η δομή μας είναι έτοιμη, οπότε τώρα μπορούμε να αρχίσουμε να δημιουργούμε τα πακέτα. Για να το κάνουμε αυτό, πρέπει μόνο να προσθέσουμε έναpackage.yml σε κάθε φάκελο με την ακόλουθη διαμόρφωση:
enforce_privacy: false
enforce_dependencies: true
enforce_privacyμας δίνει τη δυνατότητα να απομονώσουμε όλες τις σταθερές του πακέτου και να εργαστούμε με ένα δημόσιο API. Για να εκθέσουμε τις δημόσιες σταθερές, πρέπει να προσθέσουμε τις σταθερές, για παράδειγμα, στο packages/users/app/public.Προς το παρόν θα ορίσουμε αυτή τη διαμόρφωση σε false.
enforce_dependencies θα επιβάλει την εξάρτηση ενός πακέτου και θα ελέγξει όλες τις αναφορές σταθερών. Εάν μια εξάρτηση δεν ορίζεται ρητά, θα αποτελεί παραβίαση του ορίου.
Επικύρωση του συστήματος πακέτων
Packwerk καθιέρωσε ένα κριτήριο που πρέπει να ακολουθήσουμε για να έχουμε ένα έγκυρο σύστημα πακέτων. Μπορούμε να αρχίσουμε να εκτελούμε packwerk validate στην κονσόλα μας.
Αυτό θα ελέγξει τη δομή των φακέλων μας, διαμόρφωση του πακέτου, και κρυφή μνήμη μονοπατιών αυτόματης φόρτωσης.
Αυτή τη στιγμή, η εφαρμογή μας δεν είναι έγκυρη και πρέπει να διορθώσουμε τις διαδρομές φόρτωσης στοpackwerk.yml. Για να το κάνουμε αυτό, πρέπει μόνο να προσθέσουμε τα μονοπάτια που λείπουν.
Σε αυτό το σημείο, είμαστε έτοιμοι να ελέγξουμε τις παραβιάσεις ορίων στην εφαρμογή μας. Για να ελέγξουμε τις παραβιάσεις μπορούμε να εκτελέσουμεpackwerk update-deprecations , αυτή η εντολή θα δημιουργήσει deprecated_references.yml αρχείο για κάθε πακέτο. Σε κάθε αρχείο, θα βρούμε το όνομα του πακέτου, τον τύπο της παραβίασης και τη διαδρομή του αρχείου. Με όλες αυτές τις πληροφορίες γνωρίζουμε πού συμβαίνει η παραβίαση και μπορούμε να πάρουμε μια απόφαση για την επίλυσή της.
Παίρνοντας το παράδειγμα θα περιγράψουμε κάθε μέρος της παραγόμενης πληροφορίας από Packwerk.
– app/packages/repos - πακέτο όπου η σταθερή παραβίαση είναι βρέθηκε.
– ::Repo - διαδρομή προς το αρχείο που περιέχει την παραβιασμένη σταθερά.
– εξάρτηση - ένα είδος παραβίασης, είτε της εξάρτησης είτε της ιδιωτικής ζωής.
– app/packages/users/models/user.rb - διαδρομή προς το αρχείο που περιέχει την παραβιασμένη σταθερά.
Ως τελευταίο βήμα σε αυτή την ενότητα, μην ξεχάσετε να προσθέσετε τις νέες διαδρομές των αρχείων που δημιουργήθηκαν στο packwerk.yml και εκτελέστε ξανά τις επικυρώσεις.
Οπτικοποίηση της εξάρτησης
Με όλες τις πληροφορίες στο package.yml και το deprecated_references.ymlτότε μπορούμε να οπτικοποίηση ενός γραφήματος εξαρτήσεων. Για να το κάνουμε αυτό πρέπει να προσθέσουμε ένα άλλο πολύτιμο λίθο, σε αυτή την περίπτωση θα χρησιμοποιήσουμε το Pocky.
Τρέχοντας τσουγκράνα pocky:generate θα δημιουργήσουμε ένα αρχείο με όνομα packwerk.png όπου μπορούμε να απεικονίσουμε το πρώτο γράφημα των εξαρτήσεων.
Με όλα τα πακέτα καθορισμένα, το γράφημά μας θα μοιάζει ως εξής.
εξαρτήσεις υπάρχουν ήδη, αλλά αυτό δεν σημαίνει ότι γίνονται αποδεκτές από το Packwerk. Στο αποδεχτούμε μια εξάρτηση πρέπει να προσθέσουμε τη ρύθμιση εξαρτήσεων στο package.yml σε κάθε συσκευασία. Θα επικεντρωθούμε σε mail_builders αφού είναι ένα πακέτο χωρίς κυκλική εξάρτηση. Αξίζει να αναφέρουμε ότι Packwerk δεν θα μας αφήσει να δεχτούμε κυκλικές εξαρτήσεις.
Μετά την προσθήκη αυτής της διαμόρφωσης, Pocky θα χρωματίσει τις αποδεκτές εξαρτήσεις με πράσινο χρώμα.
Μπορούμε να διαγράψουμε deprecated_references.yml από το app/packages/mail_builders και τρέξτε packwerk update-deprecations ξανά. Το αρχείο δεν θα δημιουργηθεί ξανά αφού όλες οι οι παραβιάσεις διορθώθηκαν για αυτό το πακέτο. Είναι σημαντικό να αναφέρουμε ότι ακόμα και αν δεν κάνουμε Graph με αποδεκτές εξαρτήσεις
Ruby on Rails σπονδυλοποίηση με Packwerk αποδεχτούμε εξαρτήσεις, η εφαρμογή μας θα εξακολουθεί να λειτουργεί όπως πριν, αλλά τώρα έχουμε περισσότερες πληροφορίες για τη λήψη αποφάσεων και την αναδιαμόρφωση.
Κατάργηση κυκλικών εξαρτήσεων
Στο προηγούμενο γράφημά μας, είχαμε πολλές κυκλικές εξαρτήσεις που έπρεπε να επιλυθούν με κάποιο τρόπο. Έχουμε διαφορετικές στρατηγικές για να το κάνουμε αυτό:
- Εκτελέστε έγχυση εξάρτησης ή έγχυση εξάρτησης με τυποποίηση.
Ένα ζήτημα εδώ είναι ότι για να κάνουμε μια σωστή αναδιαμόρφωση, πρέπει να γνωρίζουμε την βάση κώδικα. Δεν είμαι τόσο εξοικειωμένος με την κωδικοβάση αυτού του έργου, δεδομένου ότι το πήρα ως παράδειγμα, οπότε για πρακτικούς λόγους θα ακολουθήσουμε την πρώτη στρατηγική, να μην κάνουμε τίποτα. Ακόμα και αν θα αποφύγουμε το μεγαλύτερο μέρος του refactoring, θέλουμε να δουλέψουμε πάνω στις εξαρτήσεις στο ρίζα πακέτο.
Το root πακέτο περιέχει όλη την κόλλα από το Πλαίσιο Rails, όλες οι κλάσεις από τις οποίες κληρονομούμε και τις κάνουμε να δουλεύουν όλες μαζί. Έτσι, για να λύσουμε τις κυκλικές εξαρτήσεις, θα δημιουργήσουμε ένα νέο πακέτο με το όνομα rails μέσα από τα παρακάτω βήματα:
Μετακινήστε όλα τα αρχεία και τους φακέλους της εφαρμογής_ από την εφαρμογή στο app/packages/rails.
Δημιουργήστε έναpackage.yml για το πακέτο με την ίδια διαμόρφωση με τα προηγούμενα πακέτα.
Προσθέστε όλες τις νέες διαδρομές αρχείων στο packwerk.yml.
Προσθέστε app/packages/rails ως εξάρτηση από τα υπόλοιπα πακέτα.
Μόλις δημιουργήσουμε το πακέτο θα αρχίσουμε να παρατηρούμε πολλά αρχεία που μπορούν να αναδιαρθρωθούν. Αφού μετακινήσουμε τα πάντα στο αντίστοιχο πακέτο και αποδεχτούμε εξαρτήσεις θα έχουμε μια νέα δομή και έναν καθαρότερο γράφο.
Αφαίρεση εξαρτήσεων από το ριζικό πακέτο
Τώρα το γράφημά μας φαίνεται πολύ καλύτερο θα ήταν υπέροχο αν μπορούσαμε να αφαιρέσουμε όλες τις εξαρτήσεις από το πακέτο root. Αν ελέγξουμε το deprecated_references.yml στο root package, θα παρατηρήσουμε ότι οι περισσότερες από αυτές είναι από το δοκιμή , lib/tasks , db και config φάκελος. Για να επιλύσουμε αυτές τις εξαρτήσεις, θα δημιουργήσουμε έναν φάκελο δοκιμής μέσα σε κάθε πακέτο. Έχοντας κάτι σαν app/packages/users/test. Στη συνέχεια, θα αποκλείσουμε lib/tasks , db και configμεταξύ άλλων φακέλων από Packwerk ανάλυση, καθώς αυτές οι εξαρτήσεις δεν είναι πραγματικά σημαντικές για την ανάλυσή μας και δεν έχουμε έναν εύκολο τρόπο να τις επιλύσουμε. Θα προσθέσουμε τα ακόλουθα στο packwerk.yml.
Αφού μετακινήσουμε όλες τις δοκιμές από το πακέτο root και αποκλείσουμε τους φακέλους από την ανάλυση, θα έχουμε ένα νέο γράφημα χωρίς εξαρτήσεις root.
Όπως βλέπουμε, εξακολουθούμε να έχουμε κυκλικές εξαρτήσεις στοχρήστες , repos , και έγγραφα . Παρόλο που δεν τα λύσαμε, έχουμε σημαντικές πληροφορίες να μεταβιβάσουμε τώρα. Γνωρίζουμε ότι κάθε ομάδα που εκτελεί αλλαγές σε ένα από αυτά τα πακέτα, θα πρέπει πιθανώς να εκτελέσει αλλαγές στα πακέτα με την κυκλική εξάρτηση. Από την άλλη πλευρά, γνωρίζουμε ότι μια ομάδα μπορεί να εργαστεί σε github_fetchers αποκλειστικά, γνωρίζοντας ποια πακέτα είναι να επηρεάζεται από τις αλλαγές κάθε στιγμή.
Μπορείτε να βρείτε το τελικό αποτέλεσμα του έργου εδώ.
Επόμενο βήμα
Ως επόμενο βήμα, θα μπορούσατε να επιβάλλετε σταθερό απόρρητο σε κάθε πακέτο και να εκθέτετε μόνο το δημόσιο API που θα είναι προσβάσιμο από άλλα πακέτα. Μπορείτε εύκολα να ρυθμίσετε πού θα τοποθετηθεί το API σας στο package.yml.
Packwerk μας δίνει πολλές πληροφορίες σχετικά με την εφαρμογή μας και με αυτές τις πληροφορίες μπορούμε να λάβουμε αποφάσεις για τη βελτίωση της ροής εργασίας των ομάδων μας. Αν και η διαδικασία φάνηκε να είναι μακρά και με πολλές ρυθμίσεις, δεν χρειάζεται να είναι πάντα έτσι. Μπορούμε να ξεκινήσουμε να δημιουργούμε πακέτα μόνο για τον νέο κώδικα που προστίθεται στην εφαρμογή μας και στη συνέχεια να αρθρωθούμε σταδιακά. Έτσι τώρα μπορούμε να αρχίσουμε να μιλάμε για τη σταδιακή διαμόρφωση (Gradual Modularization) αυτή είναι η έννοια που εισήγαγε ο Stephan Hagemann "Μπορούμε, για πρώτη φορά, να αποφασίσουμε να ξεκινήσουμε την αρθρωματοποίηση ενός τμήματος του κώδικα με έναν φιλόδοξο τρόπο... Αυτό μας επιτρέπει να δημιουργήσουμε ένα σύστημα υποστήριξης που επεκτείνεται σταδιακά προς μια καλύτερη δομή της εφαρμογής".