Η ποιότητα του κώδικα αποτελεί κρίσιμο μέρος της διαδικασίας ανάπτυξης, ειδικά όταν θέλετε να εργαστείτε αποτελεσματικά και μακροπρόθεσμα. Υπάρχουν πολλές προσεγγίσεις και βέλτιστες πρακτικές, συμπεριλαμβανομένου όλου του υλικού των ευέλικτων μεθοδολογιών, αλλά οι περισσότερες από αυτές σχετίζονται με κάποιο μεγάλο, επιχειρησιακό έργο που διεξάγεται από τουλάχιστον 6 άτομα.
Τι πρέπει να κάνουμε, όταν η έργο είναι μικρή ή ο πελάτης δεν ξέρει ακόμα αν αξίζει να επενδύσει περισσότερα; Προφανώς, στο Στάδιο MVP του έργου, κωδικός το styling ή οι δοκιμές μονάδας δεν είναι η κορυφαία προτεραιότητα. Οι επενδυτές συνήθως θέλουν να έχουν ένα καλό προϊόν και έλα τώρα - αν λειτουργεί, δεν χρειάζεται δοκιμή, σωστά;
Στην πραγματικότητα, έχω κάποια εμπειρία σε δημιουργία εφαρμογών από το μηδέν, ακόμη και χωρίς να χρησιμοποιούνται εξαρχής οι βέλτιστες πρακτικές. Ορισμένες επιχειρηματικές περιστάσεις με ανάγκασαν να αναζητήσω τον συμβιβασμό μεταξύ των σχεδίων προϋπολογισμού ενός επενδυτή και της λίστας "nice-to-have" του κατασκευαστή. Ευτυχώς, αν χρησιμοποιείτε το GitHub, τα περισσότερα από τα συνήθη ζητήματα που σχετίζονται με την ποιότητα του κώδικα μπορούν να επιλυθούν μέσα σε λίγα λεπτά.
Σε αυτό το άρθρο, θα σας δείξω πώς να χρησιμοποιήσετε τις ροές εργασίας του GitHub στο περιβάλλον Node.js για να τυποποιήσετε την κωδική σας βάση.
Μερικές υποθέσεις πριν ξεκινήσουμε:
- Είστε εξοικειωμένοι με το NPM και την κονσόλα Linux.
- Έχετε κάποια εμπειρία με προεπεξεργαστές στυλ, φορτωτές ενοτήτων, bundlers, κ.λπ.
- Ξέρετε τι είναι τα λιντερ και θέλετε πραγματικά να τα χρησιμοποιήσετε στα έργα σας.
1. Τυπική δομή έργου JavaScript
Αν έχετε χρησιμοποιήσει ποτέ κάποια πλαίσια JS όπως το Vue ή React, μπορείτε εύκολα να εντοπίσετε κάποια κοινά στοιχεία μεταξύ τους, π.χ.:
- /src κατάλογο με όλη τη λογική και τα στοιχεία JS σας,
- /test κατάλογο για τις δοκιμές μονάδας και e2e,
- /ενεργητικό κατάλογο για στυλ, εικόνες κ.λπ.
Ακόμη και αν μιλάμε για JavaScript έργο, εργαζόμαστε σε Κόμβος περιβάλλον, οπότε προφανώς θα πρέπει να υπάρχουν και κάποια πράγματα του Node όπως package.json, package-lock.json και /node_modules κατάλογο στον ριζικό μας κατάλογο.
Όλα αυτά τα πράγματα είναι στη θέση τους - αυτό είναι που αποκαλούμε το σύμβαση. Τα πλαίσια εφευρίσκονται για να παρέχουν κάποιες λογικές συμβάσεις, οπότε συνήθως δεν χρειάζεται καν να μας ενδιαφέρει το αρχικό πρότυπο σχεδίασης. Καθώς σε αυτό το παράδειγμα, θέλω να εξηγήσω κάποιες προσεγγίσεις, δεν θα εφαρμόσω έτοιμες λύσεις όπως το Vue CLI.
Ώρα να καταλάβετε τι κρύβεται κάτω από όλα αυτά τα μαγικά σενάρια χνούδι!
2. Επέκταση του τυπικού έργου Node
Για την παροχή λύσεων υψηλής ποιότητας, οι λιντέρ είναι το πρώτο πράγμα με το οποίο πρέπει να ξεκινήσουμε κατά τη δημιουργία ενός νέου έργου. Ας επικεντρωθούμε σε δύο linters - Stylelint για στυλ (*.scss) και το ESLint για αρχεία πηγής (*.js). Και οι δύο αυτοί linters είναι διαθέσιμοι στο NPM και είναι αρκετά εύκολο να ρυθμιστούν. Η χρήση των linters απαιτεί να περάσετε από τη διαδικασία εγκατάστασης, να προσθέσετε αρχεία ρυθμίσεων και να ορίσετε σενάρια έργου. Ας το κάνουμε βήμα προς βήμα.
3. Προσθήκη Stylelint
Η εγκατάσταση του Stylelint στο περιβάλλον Node είναι πραγματικά απλή. Σύμφωνα με το επίσημα έγγραφα, απλά πρέπει να τρέξετε:
npm install --save-dev stylelint stylelint-config-standard
και περιμένετε μέχρι να τελειώσει.
stylelint-config-standard παρέχει ένα προεπιλεγμένο σύνολο κανόνων για το linting και μπορεί να αντικατασταθεί με οποιοδήποτε πακέτο που ταιριάζει καλύτερα στις ανάγκες σας (π.χ. Στυλ Airbnb). Στη συνέχεια, δημιουργήστε ένα νέο κρυφό αρχείο .stylelintrc.json, το οποίο είναι το αρχείο ρυθμίσεων του Stylelint, υπεύθυνο για τη φόρτωση των προκαθορισμένων κανόνων μας:
{
"extends": "stylelint-config-standard"
}
Αυτή τη στιγμή, το μόνο πράγμα που λείπει είναι κάποιο σενάριο (ή σενάρια) NPM που δηλώνεται στο αρχείο package.json για να ξεκινήσει το linting των αρχείων SCSS μας. Ακολουθεί η πρότασή μου:
"σενάρια": {
"lint:scss": --syntax scss -f verbose --color": "stylelint '**/*.scss' --syntax scss -f verbose --color",
"lint:scss:fix": "stylelint '**/*.scss' --syntax scss --fix -f verbose -color"
}
Όπως μπορείτε να δείτε, έχω δηλώσει το σενάριο που περιέχει -fix επιλογή - αυτή πρέπει να χρησιμοποιείται πριν από την προώθηση των αλλαγών στο αποθετήριο.
Θυμηθείτε - είναι κακή πρακτική να χρησιμοποιείτε -fix στη ροή του CI σας, διότι τότε ο κώδικας που περνάτε στην παραγωγή δεν θα είναι σωστά διαμορφωμένος στο αποθετήριο. Γι' αυτό χρειαζόμαστε και τα δύο σενάρια.
Ας δοκιμάσουμε τον linter μας δημιουργώντας ένα αρχείο /assets/scss/styles.scss με κάποιο περιεχόμενο, όπως:
body {
background-color: #fff,
}
npm run lint:scss
Θα πρέπει να δείτε στην κονσόλα σας κάτι σαν αυτό:
> stylelint '**/*.scss' --syntax scss -f verbose --color
assets/scss/styles.scss
2:21 ✖ Αναμενόμενη εσοχή 2 διαστημάτων εσοχή
1 πηγή που ελέγχθηκε
~/Codest/Projects/github-workflow-demo/assets/scss/styles.scss
Βρέθηκε 1 πρόβλημα
επίπεδο σοβαρότητας "σφάλμα": 1
εσοχή: 1
npm ERR! κωδικός ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] lint:scss: `stylelint '**/*.scss' --syntax scss -f verbose --color`
npm ERR! Κατάσταση εξόδου 2
Αυτό σημαίνει στην πραγματικότητα ότι ο παρεμβολέας μας λειτουργεί!
Η έξοδος δείχνει ακριβώς ποια γραμμή προκαλεί σφάλμα και περιγράφει το πρόβλημα που πρέπει να επιλυθεί. Ορισμένα ζητήματα δεν επιδιορθώνονται αυτόματα, καθώς χρειάζονται την απόφαση ενός προγραμματιστή, αλλά στην πλειονότητα των περιπτώσεων, αρκεί να εκτελέσετε την ίδια εντολή με -fix επιλογή, οπότε ας την εκτελέσουμε.
npm run lint:scss:fix
Τώρα θα πρέπει να βλέπετε πράσινη έξοδο χωρίς να υπάρχουν σφάλματα:
stylelint '**/*.scss' --syntax scss --fix -f verbose --color
1 πηγή που ελέγχθηκε
/Users/wojciechbak/Codest/Projects/github-workflow-demo/assets/scss/styles.scss
Βρέθηκαν 0 προβλήματα
4. Προσθήκη ESLint
Αυτό το βήμα είναι σχεδόν το ίδιο με το προηγούμενο. Θα εγκαταστήσουμε το ESLint, θα ορίσουμε κάποιο σύνολο προεπιλεγμένων κανόνων και θα δηλώσουμε δύο καλούμενα σενάρια NPM - ένα για το CI και ένα για το pre-push. Ας τα περάσουμε όλα αυτά!
Αν χρησιμοποιείτε το NPM στην καθημερινή σας εργασία, ίσως θα θέλατε να εγκαταστήσετε το ESLint σε παγκόσμιο επίπεδο. Αν όχι, παρακαλούμε ελέγξτε τις οδηγίες εγκατάστασης στο επίσημα έγγραφα.
npm install -g eslint
Όταν η εντολή eslint είναι διαθέσιμη στον υπολογιστή σας, απλά εκτελέστε την στο έργο σας:
eslint --init
Ακολουθώντας περαιτέρω οδηγίες που εμφανίζονται στο τερματικό σας, πάρτε απλώς μερικές αποφάσεις για το έργο όπως:
- Javascript ή TypeScript
- Στυλ Airbnb ή στυλ Google
- τύπος διαμόρφωσης (αρχείο JSON, αρχείο JS ή inline σε package.json)
- Ενότητες ES (εισαγωγή/εξαγωγή) ή απαιτούν σύνταξη
Σε αυτό το σημείο αξίζει να πούμε δυο λόγια για τον μορφοποιητή κώδικα που ονομάζεται Prettier. Είναι πλήρως τυποποιημένος και συμβατός με τους περισσότερους επεξεργαστές κώδικα (π.χ. VS Code). Το Prettier παρέχει πολλά σύνολα προκαθορισμένων κανόνων μορφοποίησης κώδικα, συνεργάζεται με linters και μπορεί να αποτελέσει μεγάλη υποστήριξη στο κυνήγι της κορυφαίας ποιότητας του κώδικα. Για να καταλάβετε τι ακριβώς είναι το Prettier, επισκεφθείτε αυτό το αρχείο σύγκριση από τα επίσημα έγγραφα.
Εάν έχει γίνει, το αρχείο ρυθμίσεων ESlint (π.χ. .eslintrc.json, ανάλογα με το τι έχετε επιλέξει προηγουμένως) θα πρέπει να εμφανιστεί στον ριζικό σας κατάλογο, κάπου δίπλα στο .stylelintrc.json δημιουργήθηκε πριν.
Τώρα πρέπει να ορίσουμε σενάρια στο package.json αρχείο, όπως και για τα αρχεία SCSS:
"σενάρια": {
"lint:js": "js' --ignore-pattern node_modules/",
"lint:js:fix": "eslint '**/*.js' --ignore-pattern node_modules/ --fix"
}
Συγχαρητήρια! Το ESLint είναι έτοιμο για χρήση αυτή τη στιγμή. Ας ελέγξουμε αν λειτουργεί σωστά. Δημιουργήστε το /src/index.js αρχείο με κάποιο περιεχόμενο:
console.log("κάτι"),
Τρέξτε τον παρεμβολέα:
npm run lint:js
Η έξοδος θα πρέπει να μοιάζει με αυτό:
> eslint '**/*.js' --ignore-pattern node_modules/
~/Codest/Projects/github-workflow-demo/src/index.js
1:1 προειδοποίηση Μη αναμενόμενη δήλωση κονσόλας no-console
✖ 1 πρόβλημα (0 σφάλματα, 1 προειδοποίηση)
Αυτή η προειδοποίηση δεν θα εξαφανιστεί μετά τη χρήση -fix επιλογή, επειδή linters δεν επηρεάζει τον δυνητικά σημαντικό κώδικα. Είναι μόνο για τη διαμόρφωση του κώδικα., συμπεριλαμβανομένων των λευκών διαστημάτων, των νέων γραμμών, των άνω και κάτω τελεία, των εισαγωγικών κ.λπ.
5. Ορισμός ροών εργασίας GitHub
Ροές εργασίας GitHub είναι ένα αρκετά καλά τεκμηριωμένο πράγμα. Μη διστάσετε να εμβαθύνετε σε αυτό, αλλά προς το παρόν, θα υλοποιήσω μια απλή ροή εργασίας για να αναβαθμίσω τον κώδικά μας μετά την ώθηση στο απομακρυσμένο αποθετήριο (προφανώς, που φιλοξενείται στο GitHub).
Δημιουργία /.github/workflows κατάλογο και νέο code-quality-workflow.yml αρχείο εκεί, καθώς οι ροές εργασίας του GitHub πρέπει να ορίζονται με αρχεία YAML.
Για να εκτελέσουμε μια σωστή ροή εργασιών, πρέπει να απαντήσουμε σε μερικές ερωτήσεις:
- Πότε θέλουμε να εκτελέσουμε τη ροή εργασίας μας (σε push, σε pull request, σε merge κ.λπ.);
- Θέλουμε να αποκλείσουμε κάποιες καταστάσεις (όπως η ώθηση στο master branch);
- Τι περιβάλλον πρέπει να ρυθμίσουμε για να εκτελέσουμε σωστά τις εντολές μας (σε αυτό το παράδειγμα - Node);
- Χρειάζεται να εγκαταστήσουμε εξαρτήσεις; Αν ναι, πώς θα πρέπει να το αποθηκεύσουμε στην κρυφή μνήμη;
- Ποια βήματα πρέπει να κάνουμε για να ολοκληρώσουμε τον έλεγχο;
Μετά από κάποιες σκέψεις και λίγες ώρες εργασίας με το παράδειγμα docs .yml αρχείο μπορεί να μοιάζει ως εξής:
όνομα: ποιότητα κώδικα
on: 'push'
jobs:
Ποιότητα κώδικα:
name: Lint source code
runs-on: ubuntu-latest
βήματα:
- χρησιμοποιεί: actions/checkout@v1
- όνομα: Εγκατάσταση κόμβου
χρησιμοποιεί: actions/setup-node@v1
with:
node-version: '12.1'
- name: Εξαρτήσεις cache
χρησιμοποιεί: actions/cache@v1
with:
/node_modules
key: $(( runner.OS ))-dependencies-$((( hashFiles('**/package-lock.json') ))
restore-keys: |
$(( runner.OS ))-dependencies-$(( env.cache-name ))-
$(( runner.OS ))-εξαρτήσεις-
$(( runner.OS ))-
- name: Εγκατάσταση εξαρτήσεων
run: |
npm install
- name: Αρχεία Lint
run: |
npm run lint
Το GitHub παρέχει όλα τα περιβαλλοντικά πράγματα που χρειαζόμαστε. Στην τελευταία γραμμή εκτελούμε την εντολή npm run lint η οποία δεν είχε οριστεί προηγουμένως:
"σενάρια": {
"lint": "npm run lint:js && npm run lint:scss"
}
Σημειώστε ότι στη ροή εργασίας μας δεν χρησιμοποιώ :fix εντολές.
Όταν ολοκληρωθούν όλα αυτά τα βήματα, μπορείτε να απολαύσετε αυτό το όμορφο αποτέλεσμα από το GitHub πριν συγχωνεύσετε το Pull Request σας:
