Hi there, welcome to the first video in a series of videos
where I'll be building an app using the Phoenix framework. Now
I'll be taking an idea from wireframe to production. And
along the way, I'll be implementing things like CI/CD,
and Phoenix-y features like Live View, I'll get authentication in
there. And really, if there's something interesting, I'll try
and build it and try to fit it into the application as well.
This video series is for those that are new to Phoenix and are
looking at getting something built with Phoenix itself. And I
know I'll be learning a bunch of things along the way, we'll
definitely be making a bunch of mistakes. So I will share any
corrections and any lessons I've learned in upcoming videos. And
if there's anything that I missed, please leave it down in
the comments below. And in this video, we are just going to get
everything set up. So I'll go through the app that I want to
build share the idea. And then we'll get our Phoenix
application all up and running. we'll implement tailwind CSS,
and style our homepage. So let's dive into it. So the app that we
are going to build today is a social media for puppies slash
dogs, so the idea is you can find your favourite dog create
an account for your own dog, post like puppy updates, and
have people subscribe to those updates in other words like
follow your dog. Eventually, I wanted to create like a way for
shelters to be able to easily add their dogs and have a
message system where people could also inquire about their
adoptable dogs. Now the idea that we want to build that
haven't really fully fleshed out. So this is all definitely
going to change in the future. But there's like comments and
updates, we want to be able to have a feed of dogs, so maybe
your personalised feed, a way to autocomplete search. So we want
to be able to search on all the attributes, and add filters to
help you search for the dogs you want to see. So this could be
maybe like tags or something like that, then you have the
ideas of like following a pup. So again, notifications, updates
on the pup, and then also chatting to the right people. So
you can message people and then also be able to start like
adopting a dog. So let's have a look at the wireframes. Now I've
built four wireframes, we have desktop homepage not logged in.
Then, we also have a desktop homepage where we have logged
in, we have the ability to add a pup and then to show all the
pups. So having a look at the not logged in page, notice that
we can submit a pup, we also have named our app sniff social.
And that, you know could definitely change in the future.
I'm not entirely sure if that's the name we want to go with. We
have search and we have the ability to see a list of
puppies. And then when we do login. So say you've logged in
as a user, you have your little profile and it will drop down
menu that shows some contextual actions. And then maybe we would
be able to personalise this page. So if you're logged in,
maybe you would see a search that's kind of like already
completed with things that you've already searched for,
like search history or have puppies that are related to what
you follow. Yeah, so lots of things that we could do with
this page. And then if we come down to adding your pup, this is
a pretty generic form. So you can add in pictures with your
pup, you can, this will open up the file picker on your desktop,
you can kind of see we get our name, breed, color, personality,
which is really just a bunch of tags, and then a big description
box where you can fill out the description of your pup. And
then finally, this page with my pups is a little bit I'm not
entirely sure what do I do with this, but right now it's like a
list of all the pups that you own. So maybe this is really
good for a shelter scenario where they have to manage a lot
of pups. There'll be some description of the puppy name,
and then you can go and edit that dog. Now just want to point
out that these are wireframes, so definitely prone to change
and will probably evolve over time. But now that we've looked
at this, let's switch over to a terminal. And let's start
building our app. So we're going to create a new Phoenix
application called sniff social, which is the name of our app,
and we are going to install some dependencies. Now, this is going
to take a little while. So I'm going to cut and we'll come back
when they're all done. Cool. So now that the installation is
finished, Phoenix offers some steps to get us the rest of the
way there. So we're gonna follow those, we're gonna change
directory into our application run mix ecto create, and that
will create our database for us. And once that's done, we will
run mix Phoenix server, which will start up our localhost
server. And this server is going to be running on localhost 4000.
If we switch over to the browser, actually have that site
open, and we can see that we have a generic Phoenix
boilerplate up and running. So switching back over to our
terminal, let's close down our server and run some Git commands
just to get everything initialised so we have
everything in source control.
After we do that, we are going to get tailwind installed. So to
do that, we first need to change directory into assets. And if we
have a look at the assets folder, we can see that it
contains our CSS, JavaScript, our package JSON, which is what
we kind of want to edit. And then also Webpack config. So
Phoenix ships with Webpack four, as its default for now. We're
going to run this NPM install, which I pulled from the Tailwind
docs, and this is going to install a bunch of stuff. And
I'm going to ignore the security vulnerabilities for now,
definitely want to address that sooner rather than later. But
let's just address that in a future video. So let's go back
to our top level folder, where our elixir code lives. And let's
open up our code editor. So in VS code, our package JSON shows
the packages that we just installed using NPM install, you
can see there's some changes to the package lock and package
JSON, and we're going to create a new file. And we're going to
name that the post CSS config. And we'll paste in some
configuration that again is pulled from the Tailwind Doc's.
And once that is done, we are also going to create a new
tailwind config dot js file as well. Now we can create this
through npx tailwind init. But I like just doing this by hand.
And then in this we are also going to paste in some
configuration code that's going to be copied from the tailwind
docs. Now if we have a look at this purge array, we want to
bring in the files that we want Tailwind to purge. Now that's
going to be under lib, sniff social web. And then it will be
all the files in our templates folder. And if there's any other
folders, we can also add them to this purge array. But right now
we are going to add a glob where anything that ends in eex will
be purged and purging in Tailwind when really means
removing any unnecessary CSS from our stylesheet that isn't
being defined in our application. So if you're only
using a small subset of styles, we don't want to bring in the
entire tailwind CSS, we want to purge the unused classes. Now we
also want to load our post CSS through Webpack. So let's switch
back to our assets directory and run out post CSS loader, we need
to install the post css loader. So if we try installing this
right now, it will actually fail, because the latest version
of post css expects a newer version of Webpack five, which
isn't in this Phoenix, but will probably be updated in future
Phoenix versions. So let's install an older version of post
css, we're going to specify post css four. And then we're also
going to install post CSS import, which will allow us to
use the add import statements in our CSS file. And if we open up
our code, again, we can see our package JSON, we've installed
post CSS import, post CSS loader, with the right version
number, and we can remove anything that's sass related
because we aren't using sass anymore. So removing node sass
and sass loader. And that is really all we need to do for the
install. And in our web pack config, we can replace sass
loader with the post CSS loader. And we should be good to go.
From there, we're going to go to our CSS folder, rename app dot
SCSS to App dot CSS, because we aren't using sass anymore. And
then in our JavaScript folder, we'll also fix that import path
in our app.js file to link to the right app dot CSS file. And
then in our CSS file, we are going to remove all this code.
And we are going to import our tailwind directives here or add
these tailwind directives, which will import our tailwind styles.
Now, from there, we're going to remove this Phoenix dot CSS file
because we aren't using that anymore. And we are getting
really close to getting Tailwind in working. So had to jump
through a lot of hoops. But let's start our Phoenix server
and see what is happening. So let's start our Phoenix server
again, we're going to run mix Phoenix dot server, I don't see
any errors in the output. So that's a great start. And if we
go back to our page, we can see that some of the tailwind style
have now been brought in. And we can go ahead and test that
Tailwind actually works. So going back to our code editor,
we can open up our template file, and that is found under
lib, sniff social web templates, layout, and app dot html eex.
Now if you're coming from something like Ruby on Rails,
then this is pretty similar to the application.html.rb. And in
our app dot html file, we're just going to add a tailwind
class bg-red-100 reloading to this page, we can see that hey,
this actually made our background red, and we can kind
of confirm that the Tailwind classes are actually being
imported.
Now we can also open up our dev tools and look at app CSS source
to actually check that the Tailwind styles exist. And hey,
it's there. And this file is huge. And it's also importing in
some classes we don't even use. So Tailwind 2.1 has actually
released a JIT compiler preview made, which actually brings down
this CSS file size to something much more manageable. So we can
go to our tailwind config dot js and enable here using mode JIT.
This will automatically reload our server. And then heading
over to our page again, we can see that this CSS file is much,
much smaller. And the tailwind JIT compiler will actually add
your CSS during runtime, which is awesome. And you can tell
from this file that we aren't bringing in every single style,
we actually are only bringing in the classes that we will be
using in our app. So now that we have tailwind installed, let's
get rid of this homepage text. And we'll copy and paste in some
HTML that I wrote earlier. And this HTML just defines a home
page, and it has a bunch of tailwind classes attached to it.
It doesn't do anything too crazy right now, I'm actually just
gonna replace who's the goodest pup with our app name sniff
social. And I'll move that line, who's the goodest pup to the
subtitle. And this page will have a form that isn't attached
to anything, and also has some placeholder puppy pictures from
a website called place puppy, which has some adorable pictures
on there. So go check that out. And yeah, so really nothing too
crazy on this page. So if we save this page and reload, we
can see that all our HTML elements show up on this, which
is great, we see the form populated. And then if we go
ahead and try to change this form, there's actually an issue
here. So reloading this page. There's no blue class. So that's
super strange, because I thought we had tailwind JIT installed.
So what's going on here, if we go to Webpack config dot js,
this dot concat line is actually causing one of the issues. To
fix this, we are going to paste in this exclude module plugin,
and add in a post CSS loader as the module to exclude. This
means that every time we save our CSS files are actually
rebuilt, and they're not cached by that library. Now, let's stop
the server and restart it. But before we just pass the mix
Phoenix server, we also want to pass in NODE_ENV equals
development. Because without this flag tailwind JIT, will
just compile everything once. But we want to compile after
every file rebuild. So let's reload everything. And we can
see that hey, the blue background is there. If we
change this to green, this has reloaded, which is great. We can
change it to purple as well. And hey, cool. All the styles are
being updated using JIT. But there is one issue here, Phoenix
and Webpack can get into a race condition. So let's comment out
this code. Because we want to avoid any caching race condition
that might happen, especially with Tailwind JIT. So restarting
everything, then we can see that everything loads, fine. And if
we change our class from purple, maybe we do 300 still loads
fine. And if we change this back to grey, everything is hunky
dory. Cool. So the next thing that we want to deal with is
this kind of ugly header, we don't really need the Phoenix
framework logo anymore. So hopping over to our app dot html
dot eex file, let's just remove the header. While we're here, we
might as well remove the background as well. And once I
remove that, I'm going to add some extra classes to a
container to make the centering look good. And that's it. We are
all done. So let's do a recap on what we just did today. So we
built a phoenix application using some generators like
Phoenix dot new. We also got everything up and running. And
then we added tailwind CSS to our project. This meant that we
can just call all the tailwind styles, and they'll just appear
magically. We also turned on the preview JIT mode for tailwind
which meant that how local style sheet is much, much smaller,
instead of this huge thing that pulls in every single class.
It's now only pulling in the classes that we use in our
application. So all very fun stuff. Oh, and then we added
some puppy pictures and styled our homepage. So in the next
episode, I really want to get into deployment because I think
that's the fastest, or at least the best loop that I can think
of is you make a change locally, you push it to GitHub, and then
you see that change to appear in production environment. So
that's what we're working on next video. And if you liked
this video, please give it a thumbs up. And if you have any
thoughts about the name, or any thoughts about future topics,
please leave it down the comments below. Until next time,
see you later.