Κάντε την ανάπτυξη HTML πολλών σελίδων να απορροφά λιγότερο με το Pug

Εμπνευσμένο από μια αληθινή ιστορία

Ας κάνουμε ένα ταξίδι…

Φανταστείτε ότι βρίσκεστε στη λίστα κλήσεων για έναν ανεξάρτητο οργανισμό σε μια πόλη της επιλογής σας. Τώρα ας υποθέσουμε ότι λαμβάνετε ένα ωραίο μήνυμα στα εισερχόμενά σας. Ανοίγετε το μήνυμα και φαίνεται αρκετά φυσιολογικό.

Έχουμε άμεση ανάγκη για έναν προγραμματιστή να ξεκινήσει σήμερα.

το μήνυμα και φαίνεται αρκετά φυσιολογικό.

Έχουμε άμεση ανάγκη για έναν προγραμματιστή να ξεκινήσει σήμερα.

Όντας ένα άτομο που απολαμβάνει να τρώει φαγητό για να επιβιώσει, πληκτρολογείτε μερικές πληροφορίες και υποβάλλετε αίτηση.

Μέσα σε πέντε λεπτά από το πάτημα αυτού του κουμπιού αποστολής, λαμβάνετε μια κλήση. 10 λεπτά μετά από αυτό, αποκτάτε πρόσβαση στον διακομιστή.

Περιττό να πούμε ότι βρίσκεστε σε προθεσμία. Αυτή η προθεσμία λήγει στο τέλος της ημέρας.

Ανοίγετε τα αρχεία HTML και τα κοιτάζετε… με τρόμο.

Ο κώδικας είναι παντού, ακατάστατος και αποδιοργανωμένος. Για να μην αναφέρουμε, πρέπει να κάνετε προσαρμογές στην κεφαλίδα και το υποσέλιδο… σε πέντε διαφορετικές σελίδες.

Το πρώτο πράγμα που κάνετε είναι να το εκτελέσετε μέσω Prettify (Δόξα τω Θεώ για Prettify). Αυτό το καθάρισε, αλλά υπάρχουν μερικά ακόμη προβλήματα. Αυτός είναι ένας στατικός ιστότοπος HTML, που σημαίνει ότι κάθε αλλαγή που κάνετε στο παγκόσμιο περιεχόμενο (κεφαλίδα, υποσέλιδο και ούτω καθεξής), θα πρέπει να αντιγράψετε σε ΚΑΘΕ αρχείο. Ω θεε μου.

Τι θα κάνεις???

Απλό, θα δημιουργήσετε ένα αρχείο Webpack για να χειριστείτε το δυσάρεστο μέρος της σύνταξης HTML και θα το κάνετε γρήγορα.

Να τι πρέπει να γνωρίζετε:

  • Javascript! (λόγω του Webpack)
  • HTML! (γιατί είναι από αυτό το Διαδίκτυο είναι φτιαγμένο)
  • CSS! (γιατί ποιος αρέσει άσχημα πράγματα;)
  • πατημασιά! (γιατί αυτό είναι το σημείο αυτού του άρθρου!)
  • npm (επειδή είναι Θεός)
  • Βασικές γνώσεις της γραμμής εντολών (επειδή το να κάνετε πράγματα μέσω λήψεων είναι ανόητο…)
  • Μάθετε ποιος είναι ο Jim Carrey (επειδή gifs)

Εάν δεν είστε εξοικειωμένοι με το πατημασιά, μπορείτε ακόμα να διαχειριστείτε το δρόμο σας μέσω αυτού. Αλλά αν έχετε χρόνο, διαβάστε το. Συνιστώ να μαθαίνετε πατημασιά με πατημασιά. Ή τα έγγραφά τους. Και αυτά είναι καλά, υποθέτω.

Εδώ είναι οι εκδόσεις που χρησιμοποίησα για αυτό:

  • html-loader: 0,5,5,
  • html-webpack-plugin: 3.2.0,
  • pug-html-loader: 1.1.5,
  • Webpack: 4.12.0
  • webpack-cli: 3.0.8
  • npm: 6.1.0
  • κόμβος: 10.4.0

Ενημέρωση: Έκανα ένα βίντεο! Ρίξτε μια ματιά αν δεν θέλετε να διαβάσετε, αλλά προτιμάτε να ακούσετε τη φωνή μου για 30 λεπτά.

Βήμα 1. Οργανώστε τη δομή του έργου σας

Έτσι θέλω να οργανώσω τον φάκελό μου για αυτούς τους τύπους έργων.

src/ oldHTML/ dist/ images/ css/ webpack.config

Θέλω να βάλω όλο το αρχικό HTML σε έναν ξεχωριστό φάκελο που δεν μπορώ να διαγράψω κατά λάθος. Το Webpack είναι λίγο πιο ευγενικό από το να πω, Gulp, το οποίο είχα διαγράψει έναν ολόκληρο φάκελο πριν; Αυτή η δομή είναι αρκετά καλή για να ξεκινήσουμε.

Βήμα 2. Ανασηκώστε τον κινητήρα npm

Aside: Πρόσφατα επέστρεψα npmαπό yarnγια μερικούς λόγους. Ένα από αυτά ήταν ότι σταμάτησε να λειτουργεί και είχα λίγη υπομονή για να το κάνω να λειτουργεί ξανά. Ενδιαφέρον άρθρο εδώ, αν θέλετε να διαβάσετε περισσότερα.

Τέλος πάντων, αρχίστε εκείνο το npm.

npm init -y

Σημείωση: (το -y είναι εάν δεν θέλετε να απαντήσετε σε καμία από τις ερωτήσεις του)

Εγκαταστήστε εξαρτήσεις ανάπτυξης.

Μην ανησυχείτε, θα εξηγήσω κάθε ένα καθώς πηγαίνουμε

npm install -D webpack webpack-cli pug-html-loader html-webpack-plugin html-loader

Προσθέστε μερικά σενάρια στο package.json

Από προεπιλογή, το package.json έχει ένα σενάριο, αλλά πρέπει να προσθέσουμε μερικά.

"dev": "webpack --watch --mode development", "prod": "webpack --mode production"

Αυτά είναι τα δύο που θέλω να συμπεριλάβω. Το πρώτο θα τρέξει το Webpack σε λειτουργία ανάπτυξης (σημείωση: η σημαία --mode είναι νέα στο Webpack 4) και θα παρακολουθεί τις αλλαγές αρχείων. Το δεύτερο είναι όταν θέλουμε να τρέξουμε το Webpack στην παραγωγή, αυτό συνήθως ελαχιστοποιεί τα πράγματα.

Θα πρέπει να μοιάζει με αυτό:

"name": "pugTut", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "dev": "webpack --watch --mode development", "prod": "webpack --mode production" }, .....more code

Δημιουργήστε μερικά αρχικά αρχεία για να ελέγξετε τη διαμόρφωση του Webpack

Το Webpack χρειάζεται ένα σημείο εισόδου, οπότε ας το κάνουμε. Δημιουργήστε ένα app.js στο φάκελο src / . Μπορεί να είναι κενό. Δεν πειράζει. Χρειάζεται επίσης ένα αρχικό αρχείο pug για μεταγλώττιση. Δημιουργήστε επίσης ένα αρχείο index.pug στον φάκελο src / .

Δημιουργήστε και ρυθμίστε το webpack.config.js στον ριζικό κατάλογο

Alright, if you haven’t used Webpack before, I’m going to walk through each part individually to give you (and hopefully me) an idea of wtf is going on in this config file.

First, let’s declare our dependencies.

// webpack.config.js const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin');

path is a native Node dependency, so you shouldn’t have to worry about that being required in your package.json.

Webpack is, well Webpack…

HtmlWebpackPlugin is how we extract HTML. I’m not an expert on how Webpack works. From what I understand, since it is designed to consume JavaScript, we have to have loaders in our config file to pull out things like HTML and CSS. HtmlWebpackPlugin is how we do something useful with the HTML that gets extracted from the loaders.

Cool? Next step…

const pug = { test: /\.pug$/, use: ['html-loader?attrs=false', 'pug-html-loader'] };

This method is used by Wes Bos and I really like it, so I use it. We have to define rules on how to handle certain file types, for example .pug or .css. Putting it into a variable makes it more legible, in my opinion. Anyways, we setup a test case with a regexp, then define the loaders we want to use. For whatever reason, the loaders are listed in reverse order of what you’d think. I’m sure there is an explanation but I couldn’t find it.

Confused? What that means is, if we want to use pug to compile to HTML, we write it in the order above: our html loader ->pug loader. However, in reality when the code runs, it runs the pug loader first…then the HTML loader. Yep.

Note: Don’t worry about ?attrs=false for right now, I’ll explain it a bit later.

Cool? Next step…

const config = { entry: './src/app.js', output: { path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js' }, module: { rules: [pug] }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: 'src/index.pug', inject: false }) ] }; module.exports = config;

Holy Crap. That’s a lot of stuff. Let’s break it down.

entry is simply the entry point for our JS file.

output defines where we want our JS file to go. This is not where our HTML files will go. As mentioned above, path is a node module. __dirname is a variable we can get from Node. The filename is what we want to call our JS file. The [name] is a substitution. In this case, it uses the file name of the entry file. You can also use [hash] if you want a unique identifier.

module defines the different modules. For the purpose of this tutorial, there is only one module with one set of rules. rules defines the rules we will use for that module. We throw the pug variable we made earlier into there. So nice, so clean.

Finally, plugins is where we get to add any third party stuff. In our case, we are using HtmlWebpackPlugin to do something with our pug files.

filename is what we want our HTML file to be called. template is the pug file that are compiling. inject is: “inject all assets into the given template.” I have it set to false because…well, honestly I don’t remember.

One of the crappiest things about HtmlWebpackPlugin is that you have to create an entry for EVERY HTML file. I tried to figure a way around it, but found no simple solutions.

// webpack.config.js const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const pug = { test: /\.pug$/, use: ['html-loader?attrs=false', 'pug-html-loader'] }; const config = { entry: './src/app.js', output: { path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js' }, module: { rules: [pug] }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: 'src/index.pug', inject: false }) ] }; module.exports = config;

Before we move on, let’s make sure our code works! Run the script.

npm run dev

If all went well, you should see something like this:

We’ve come a long way. Here’s a present:

Step 3. Break up the pages into partials

This is where magic starts happening. I know it seems like we’ve been working for a while with very little gain, but trust me…it was worth it.

One of the most important features for pug is the partials. The idea is to have one file that holds most of your global code (head, header, footer, nav, and so on) and have individual files for all your content.

Let’s make a couple files. You should have created the index.pug file already, but let’s make one more, layout.pug.

src/ - index.pug - layout.pug

Step 4. Setup layout file

The layout file is basically the main template for your whole site. It will have hold all the global stuff, for example head, header and footer.

//- layout.pug doctype html html head title I'm a title body block header block content block footer script(src="somescript.js")

I guess something to explain is that pug is all based on indentation, similar to YAML. It is glorious, because that means no more closing tags! However, this can throw some, especially those with crappy indentation to begin with. So just make sure to start slow and make sure everything is indented correctly and you’ll be fine.

Looking at our layout.pug file, you’ll see some familiar HTML tags mixed with unfamiliar ones. I highly suggest downloading syntax highlighting for pug in your editor of choice. If you’re using VSCode, it should come with it by default. Thanks Microsoft.

I think it’s pretty easy to figure out, but let’s take a look at the meat of the document to make sure we know what’s going on.

head title I'm a title body block header block content block footer script(src="somescript.js")

head, body, title and script are normal tags, but what the hell is block? block is how we define dynamic content. Basically, this is telling pug that some content is going to go in here. Hopefully it’ll make more sense when we create our individual page files.

Step 5. Create more partials

Let’s make use of that index.pug file.

//- index.pug extends layout block content p Woah.

Looking at our index file, it seems awfully small for a whole HTML page. That’s because of that little extends fella. extends tells pug that you want to use another pug file as the template, in our case layout. Then below that block content is in reference to what we put in our layout.pug file.

If you have your Webpack still running in the background, it should recompile and you’ll get a fresh new index.html in your dist/ folder. If not, run Webpack again.

Step 6. Grab all the old HTML

Those starter files are fine and dandy, but we need to make some real progress. We need to start grabbing that HTML and using it! Luckily, pug will recognize regular old HTML tags, so you can literally copy all the HTML content you want and just paste it in there.

It might look something like this:

extends layout block content 

blerb

Woah.

Alright, it’s not really that simple.

Like I mentioned, pug is based on indentation. To make life easier on yourself, I suggest removing all indentation from the HTML file before pasting into the pug file. It will mostly work, but you’ll probably have to finagle it a bit. Lucky for us, pug-html-loader will tell us what’s wrong with it when it tries to compile. There are some examples of common problems in the next Step.

Step 7. Start optimizing

Δεν πρόκειται να ψέψω, όταν ρίχνετε για πρώτη φορά σε HTML, το Webpack δεν θα του αρέσει. Εδώ είναι μερικά πράγματα που πρέπει να προσέξετε:

Εικόνες

  1. Βεβαιωθείτε ότι οι σύνδεσμοι προς τις εικόνες είναι καλοί. Για οποιονδήποτε λόγο, συχνά αποτυγχάνει εάν το src = "images /" αντί του src = "/ images /"

2. Υποσχέθηκα νωρίτερα να επιστρέψω σε αυτό ?attrs=false, λοιπόν, εδώ είμαστε!

Αυτό είναι το πρόβλημα από τον ιστότοπο html-loader που εξηγεί τι κάνει.

Για να απενεργοποιήσετε πλήρως την επεξεργασία χαρακτηριστικών ετικετών (για παράδειγμα, εάν χειρίζεστε τη φόρτωση εικόνων από την πλευρά του πελάτη) μπορείτε να περάσετε attrs=false.
html-loader?attrs=false 

Javascript

Το pug δεν παίζει ωραία με το JS σε ετικέτες σεναρίου. Εάν επικολλάτε τακτικά σε άνοιγμα και κλείσιμο ετικετών σεναρίου JS, μπορεί να λειτουργεί εντάξει Ωστόσο, εάν θέλετε να κάνετε χρήση της ετικέτας σεναρίου pug, απλώς φροντίστε να προσθέσετε μια τελεία στο τέλος, όπως αυτή:

Step 8. Make more pages and start converting to pug tags

Clearly it’s useless if you are only doing the index page. For whatever you’re doing, just create a new file for each page you want. Also, make sure to make new HtmlWebpackPlugin entries in the plugins section in Webpack.

It’ll end up looking like this:

//webpack.config.js ...previous code... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: 'src/index.pug', inject: false }), new HtmlWebpackPlugin({ filename: 'contact.html', template: 'src/contact.pug', inject: false }) ] ...more code...

You don’t have to convert everything to pug format immediately. In fact, if you have a huge site with a crap ton of HTML, then you can do it as you go, but it does make it easier.

Includes

Αυτό δεν θα ήταν ένα πολύ καλό σεμινάριο εάν δεν μιλήσαμε για τα περιλαμβάνει. Θυμάστε αυτά τα μπλοκ στο αρχείο διάταξης; Λοιπόν, εάν δεν θέλετε το αρχείο διάταξης να είναι γιγαντιαίο, μπορείτε να δημιουργήσετε ξεχωριστά αρχεία που θα τραβηχτούν κατά τη στιγμή της μεταγλώττισης. Για παράδειγμα, εάν θέλετε να δημιουργήσετε ένα μόνο αρχείο που περιέχει όλες τις πληροφορίες κεφαλίδας. Η διάσπασή του με αυτόν τον τρόπο βοηθά επίσης ουσιαστικά στην εσοχή.

Δημιουργήστε ένα νέο αρχείο "κεφαλίδα" σε ένα νέο φάκελο "περιλαμβάνει":

src/ -- includes/ header.pug

Σε αυτό το αρχείο, τοποθετήστε ό, τι θέλετε να είστε στην κεφαλίδα.

//- header.pug header h1 I'm a header

Τώρα επιστρέψτε στο layout.pug και συμπεριλάβετε το.

//- layout.pug doctype html html head title I'm a title body block header include includes/header block content block footer script(src="somescript.js")

Βήμα 7. Θέλετε να πάρετε Fancy;

Υπάρχουν πολλά περισσότερα πράγματα που μπορείτε να κάνετε με pug και webpack. Ωστόσο, νομίζω ότι φτάσαμε στο τέλος των βασικών. Ωστόσο, ρίξτε μια ματιά στα mixins. Αυτά τα πράγματα είναι καταπληκτικά.

Τυλίγοντας

Συνιστώ ανεπιφύλακτα να εισαγάγετε HTML αργά, διαφορετικά θα καταλήξετε να εντοπίσετε 1.000 σφάλματα ταυτόχρονα.