paint-brush
How To Use Gulp And Prettier on Code Snippets and API Outputsby@timbushell
716 reads
716 reads

How To Use Gulp And Prettier on Code Snippets and API Outputs

by Tim BushellDecember 16th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Code editors come with "beautifiers" which programmers can use to make code uniformly and conventionally laid out, aka: "pretty".

Company Mentioned

Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - How To Use Gulp And Prettier on Code Snippets and API Outputs
Tim Bushell HackerNoon profile picture

Code editors come with "beautifiers" which programmers can use to make code uniformly and conventionally laid out, aka: "pretty".

But sometimes you have a snippet of code, maybe copied from the web, or maybe a packet of JSON curled on the command line, and you want to quickly format it.

Here is a way of using gulp and prettier to build a cute project to automate this common task. This will be a fun utility you can run in the background; and for those looking to learn gulp, it makes for a neat primer for a less common use case.

Prerequisites

  • You'll need Node and npm installed
  • You'll need gulp installed as a global package:
    npm i gulp -g 
  • You'll need to know how to run
    curl
    or
    http
    on a command line.

What is gulp?

gulp is a NodeJS-based task runner. grunt is another well known library built for the same purpose, but in this article we'll use gulp because I like it better. In my opinion, gulp is more like code; grunt is more like configuration. Either are good. I like gulping better than I like grunting. If you want to grunt, find a grunter. I'm a gulper. Unless it's beer. Then I'm a sipper.

gulp uses a concept called a "pipe". A pipe is nothing more than a chain of functions where each transforms the input in some way before passing on the output of each stage to the next function. Metaphorically, this would be a valid gulp task:

function gulpPotatoesTask() {
  return src(potatoes)
    .pipe(wash())
    .pipe(peel())
    .pipe(slice())
    .pipe(season())
    .pipe(fry())
    .pipe(drain())
    .pipe(cool())
    .pipe(bag())
    .pipe(dest(shop))
}

Obviously gulp can't make potato chips (or "crisps" as we say in the UK); but it can perform many useful computer tasks. gulp itself doesn't have any task functions, all it does is pipe content from one function to another. The actual functions are imported from gulp based libraries; some of them gulp friendly versions of well known npm libraries. There are lots of them! You can even write your own.

  • Tasks can be simple, like copying files from one place to another; or compiling code, or compressing files; or deploying applications...
  • Usually the tasks gulp completes are trivial. They could be easily achieved with a few command line statements. What gulp brings to the party is convenience.
  • A gulp task only saves you a few seconds each time... but if you use gulp to handle the quick tasks you do frequently, the time saved adds up...

We're going to look at a simple use case.

Working pretty

When I'm developing a REST API, I'm often curling the endpoint to verify the output. On the command line, the output is not pretty, so it makes it hard to verify whether a large JSON packet... especially a list of records... is error free. I'd usually to copy and paste the result into my code editor and run a "beautify" command. That's a simple task, which takes a few seconds, which I have to do a lot! It's a perfect candidate for a gulp task.

Let me show you what I mean with help from cat-facts.

On a command line, using curl or http or something else you like, run this:

curl -X GET https://cat-fact.herokuapp.com/facts

You'll see some output like this:

[{"status":{"verified":true,"sentCount":1,"feedback":""},"type":"cat","deleted":false,"_id":"5887e1d85c873e0011036889","user":"5a9ac18c7478810ea6c06381","text":"Cats make about 100 different sounds. Dogs make only about 10.","__v":0,"source":"user","updatedAt":"2020-09-03T16:39:39.578Z","createdAt":"2018-01-15T21:20:00.003Z","used":true},{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"588e746706ac2b00110e59ff","user":"588e6e8806ac2b00110e59c3","text":"Domestic cats spend about 70 percent of the day sleeping and 15 percent of the day grooming.","__v":0,"source":"user","updatedAt":"2020-08-26T20:20:02.359Z","createdAt":"2018-01-14T21:20:02.750Z","used":true},{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"58923f2fc3878c0011784c79","user":"5887e9f65c873e001103688d","text":"I don't know anything about cats.","__v":0,"source":"user","updatedAt":"2020-08-23T20:20:01.611Z","createdAt":"2018-02-25T21:20:03.060Z","used":false},{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"5894af975cdc7400113ef7f9","user":"5a9ac18c7478810ea6c06381","text":"The technical term for a cat’s hairball is a bezoar.","__v":0,"source":"user","updatedAt":"2020-11-25T21:20:03.895Z","createdAt":"2018-02-27T21:20:02.854Z","used":true},{"status":{"verified":true,"sentCount":1},"type":"cat","deleted":false,"_id":"58e007cc0aac31001185ecf5","user":"58e007480aac31001185ecef","text":"Cats are the most popular pet in the United States: There are 88 million pet cats and 74 million dogs.","__v":0,"source":"user","updatedAt":"2020-08-23T20:20:01.611Z","createdAt":"2018-03-01T21:20:02.713Z","used":false}]

...which ain't pretty!

We're going to write a gulp task which can be used to immediately view a prettier version of this (and other types of) output.

What is prettier?

Prettier formats types of code, like Markdown, HTML, Javascript, JSON, php, SASS, JSX, and a few others. By format or "prettier" we mean making Yuck

[{x:0.8237408992028434,y:0.13037233515888857},{x:0.6963719435837943,y:0.4649206270118649},{x:0.7648934156460141,y:0.5717398107678364},{x:0.9959169251265363,y:0.2694142052523685},{x:0.6960740127788656,y:0.4607191696858737},{x:0.7997975402971844,y:0.7237427911168932},{x:0.2787610912100449,y:0.9407814810049839},{x:0.3814844890207585,y:0.5966765925995574},{x:0.8582462233630488,y:0.40239228496424784},{x:0.7787669281973615,y:0.08106311625800644},{x:0.2141057128647048,y:0.9657071629620191},{x:0.8275684202905218,y:0.5451389175963794},{x:0.165628605615336,y:0.14122051271223968},{x:0.20818796522948935,y:0.7404504627391517},{x:0.9674488899456264,y:0.20797270494407227},{x:0.4749080813580391,y:0.5771024073819466},{x:0.8843075075690756,y:0.6923906507976978},{x:0.3726781663836376,y:0.09623360192541552},{x:0.9597557422088943,y:0.7070691995654992},{x:0.6074224539058268,y:0.9773926533307942}]

look Yummy

[
  { x: 0.8237408992028434, y: 0.13037233515888857 },
  { x: 0.6963719435837943, y: 0.4649206270118649 },
  { x: 0.7648934156460141, y: 0.5717398107678364 },
  { x: 0.9959169251265363, y: 0.2694142052523685 },
  { x: 0.6960740127788656, y: 0.4607191696858737 },
  { x: 0.7997975402971844, y: 0.7237427911168932 },
  { x: 0.2787610912100449, y: 0.9407814810049839 },
  { x: 0.3814844890207585, y: 0.5966765925995574 },
  { x: 0.8582462233630488, y: 0.40239228496424784 },
  { x: 0.7787669281973615, y: 0.08106311625800644 },
  { x: 0.2141057128647048, y: 0.9657071629620191 },
  { x: 0.8275684202905218, y: 0.5451389175963794 },
  { x: 0.165628605615336, y: 0.14122051271223968 },
  { x: 0.20818796522948935, y: 0.7404504627391517 },
  { x: 0.9674488899456264, y: 0.20797270494407227 },
  { x: 0.4749080813580391, y: 0.5771024073819466 },
  { x: 0.8843075075690756, y: 0.6923906507976978 },
  { x: 0.3726781663836376, y: 0.09623360192541552 },
  { x: 0.9597557422088943, y: 0.7070691995654992 },
  { x: 0.6074224539058268, y: 0.9773926533307942 }
]

So let's start making pretty from ugly; yummy from yuck; unreadable to ... well... you get the point.

Scaffolding

Start by creating a new folder for the project and initialize a npm package:

mkdir pretty-ugly
cd pretty-ugly
npm init -y

At this stage you'll have a folder with a

package.json
file - and that's it. Next we'll install some npm packages.

npm i del gulp gulp-prettier prettier vinyl-paths

When the install is finished, run

gulp

gulp
[17:40:34] No gulpfile found

No gulpfile found!? Good point! So create

gulpfile.js
with your favourite text editor and put it in the root of your new project. Copy the following into the file and save it.

/pretty-ugly/gulpfile.js 

const { src, dest, watch } = require("gulp")
const prettier = require("gulp-prettier"),
  del = require("del"),
  vinylPaths = require("vinyl-paths")

let prettyUglyFiles = ["./pretty/ugly/*.*"]

let prettyUglyTask = () => {
  return src(prettyUglyFiles)
    .pipe(vinylPaths(del))
    .pipe(prettier())
    .pipe(dest("./pretty/"))
}

let prettyUgly = () => {
  return watch(prettyUglyFiles, prettyUglyTask)
}

exports.default = prettyUgly

For those of you who know gulp, this will be familiar. For those who don't know gulp, I will break it down. If you are a grunt user it will be useful for you to compare the approach.

First we import all the libraries we need from gulp:

src
,
dest
, and
watch
are part of gulp's core API; functions which form the backbone of gulp tasks.

  • src
    gets gulp to retrieve one or more source files/folders.
  • dest
    gets gulp to "pipe" the result of some transformation of those files into a destination folder.
  • watch
    gets gulp to (duh!) watch for changes in the src which can be used to trigger a new transformation of them which is piped into the destination folder.

Next we import some of the gulp based transforming functions from other npm libraries.

const prettier = require("gulp-prettier"),
  del = require("del"),
  vinylPaths = require("vinyl-paths")

Task 1: prettyUglyTask

The "pipe" in

prettyUglyTask
is simple.

let prettyUglyFiles = ["./pretty/ugly/*.*"]

let prettyUglyTask = () => {
  return src(prettyUglyFiles)
    .pipe(vinylPaths(del))
    .pipe(prettier())
    .pipe(dest("./pretty/"))
}
  1. We ask gulp to fetch all files in the source directory referenced by
    prettyUglyFiles
  2. We ask gulp to delete the source files. Don't worry too much about what
    vinyl-paths
    does - think of it as a marshal which deletes the files while keeping them in the pipe.
  3. We ask gulp to ask prettier to run its magic on them and make them (duh!) prettier.
  4. We get gulp to save the prettier files into a different folder. The reason for using a different folder is that we're going to watch the source directory for changes and we don't want gulp to get into an infinite loop!

Task 2: prettyUgly

let prettyUgly = () => {
  return watch(prettyUglyFiles, prettyUglyTask)
}

The

prettyUgly
task is simple. We ask gulp to watch the source folder and if anything changes, we ask it to perform Task 1: prettyUglyTask. Watch handles the piping of the changed files into the
prettyUglyTask
function.

exports.default = prettyUgly

It is Task 2,

prettyUgly,
which we export. When we run
gulp
, it will run Task 2, which does nothing until the files in the source directory change.

The folder structure we're using is purely to humour me. We put the "ugly" files into the ugly folder and gulp puts the prettier versions into the pretty folder. You'll need these folders so make them:

mkdir -p pretty/ugly

You could use a different folder structure, i.e. making pretty and ugly siblings, but I like the nomenclature which implies the action, e.g. "[make] pretty [of that which is] ugly". I like that the files I want to see are in the parent folder, and the files I never want to see (the ugly ones) are buried. Small things please little minds.

At this point your project will look like this:

pretty-ugly 
    |- node_modules
    |- pretty 
        | - ugly 
    |- gulpfile.js 
    |- package-lock.json
    |- package.json

Now open up a different terminal and type the

gulp
command:

gulp
[20:54:25] Using gulpfile ~/Dev/timitee/pretty-ugly/gulpfile.js
[20:54:25] Starting 'default'...

In your original terminal (and with an eye on your second terminal), type this:

curl -X GET "https://cat-fact.herokuapp.com/facts" --output ~/Dev/timitee/pretty-ugly/pretty/ugly/catfacts.json

You'll notice that gulp wakes up and prints:

[20:56:04] Starting 'prettyUglyTask'...
[20:56:04] Finished 'prettyUglyTask' after 164 ms
[20:56:05] Starting 'prettyUglyTask'...
[20:56:05] Finished 'prettyUglyTask' after 9.68 ms

Even though we

--output
our "cat facts" into the
pretty/ugly
folder, you'll open the
catfacts.json
from the
pretty
folder.

With this gulp task running, you can put (or output) any file prettier recognizes (see https://prettier.io/) into the

ugly
folder, and it will format the file and move the pretty version into the (duh!)
pretty
folder.

And that's pretty-ugly!

I hope this leaves you with:

  1. A taste of gulp.
  2. A handy utility you can use in your daily workflow.
  3. Some pretty files.
  4. A couple of cat facts.

Core, Thanks!