Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hey everybody, my name is Melisha and I'm a developer advocate
at iterative AI. So there I work
on an open source tool called DVC, and it helps
make machine learning projects a lot easier for machine
learning engineers. So check that out if you're interested
in it. But today I'm going to talk to you about
using storybook to maintain your components in
Redwood. So we're going to talk about storybook,
redwood and component driven development today.
If you have any questions about this talk, feel free to
reach out to me on Twitter at flipped coding and I'll
do my best to answer your questions.
So let's just jump right on into it and talk
about component driven development. This is
something that we've all probably been doing in
some way without giving it an official name.
So if you work on the front end in react,
angular view, svelte, whatever your
framework is, you've probably touched some components driven
development. And what this does,
it helps you model your systems better.
So instead of building each page in isolation where
you have all of the components self contained,
there, you're actually building these modular components
that are very loosely coupled that
can handle pretty much any state you throw
at them. So instead of having all of these components
scattered throughout all of these pages that do really
similar stuff, and maybe just passing some props
along would give that component the functionality
that it needs, the styles that it needs, you can
do that with component driven development. And what
that helps you do is since you're building
these really modular pieces of code,
whenever you're working with your data, you don't
have to worry as much about one
particular page. So you have these components
that accept different kinds of props. They already handle
the different states that you need when your data comes
in. So you can reuse all of those components
with whatever data that you need.
You're not locked into just, well,
this is on the user dashboard reporting page,
so I can only use this component because it's the only thing
that handles this data. Instead,
you have a components you can use on that reporting
page and on the settings page and maybe somewhere
else within your app. So one example that we're
going to stick with pretty much the whole time during this talk
is a button, because how many times have
you had crazy things happen with buttons?
So that is where storybook comes in.
This lets you develop your components in isolation,
which is actually pretty awesome,
because what that means is when you come up with
these new states that, let's say our button needs to
have a primary state for when
a user is just looking at a form or they're in a modal
or whatever, and we have a secondary state for,
I don't know, the buttons just in a different state.
And then of course, we have some kind of dark mode button.
You don't necessarily want to have to run your whole
app, change data, call APIs,
or even just go in and manually tweak the
code. So when you're doing your local development,
you put in those weird conditions to get the components to
show how you want them to do. Well, with storybook,
you don't have to do all of the spaghetti code locally.
You can actually just look at your components with
different props applied to them without
having to touch your app at all. So if we have this button
components file, we can develop and see how
that works in absolute isolation from the app.
And something else that storybook helps us do that really
gets overlooked in, well,
almost every part of software, unfortunately,
documentation. You know, when you bring on somebody
new to the team or you're working with components
you haven't seen in a while, it might be hard to remember
the names of the props, what values you can
pass to the props, what that's actually supposed to do to
the component itself, how that might interact with other
things on the page. With storybook, you can
document all of that. You can leave examples of,
let's say, our button components. You can leave examples of it
in different states, show the different props that
you need to set for the different scenarios and data that you'll
be getting. Storybook bundles,
all of this together, you can look at the components
in isolation, and you can document those
components, I guess, in isolation too.
So everything is really neatly put together.
And this is one of the fun parts. When you're
doing components driven development in the first place,
it makes writing tests a lot easier.
But when you're doing it with storybook, you're really
focused on how your component should react with
changes on the page. So again, if we
have our button and we've just loaded in some data,
maybe we need to change the state of that button to
some kind of loading symbol that's a different color.
And then after we have all of the data,
we change it to something else. This is definitely
some kind of functionality you would want to write tests for,
right? So when you already have your
component developed and set up in the way that storybook
needs to run with it, writing your test gets a lot easier
because you can actually test the components
in isolation. You don't need to render the whole page,
make up the fake data call the fake
APIs, unless you know that's part of your test suite.
But if you're just wanting to make sure your buttons are looking right,
it makes it a whole lot easier. Or if you want to make sure that
when data is loading into a certain component that
it updates correctly. This is a great
way to take advantage of storybook for testing.
Now we're going to talk about how you actually use storybook.
So we're going to look at it inside of the redwood framework,
which is honestly just one of my personal favorite frameworks.
And it's a full stack JavaScript framework,
but you could also call it a full stack Jamstack
framework. So I've heard some
comparisons to next, but I think
it's a little better. Maybe that might just
be because I like how much it handles for you out
of the box. So with Redwook,
you have your react front end, you have a graphQl
server for the backend, and you have Prisma
supporting all of your database operations.
So when you create a new Redwood app,
you have a fully functional full stack
app from front end to database. As soon
as you run the app, like you
just create a new project, you run it and
you have this react front end, you have this graphql server,
you have storybook. If you want to add some authentication,
you can do that too. But Redwood just handles a
bunch of stuff for you out of the box, but it doesn't
keep it hidden from you. So you can go in and edit any of the
files. If you go through their docs, you can see how they
structure things and why they do file conventions the way that they
do. But Redwood has all of
this for you, and there are a lot of commands that you
can use to generate code that really
makes development oddly fast. It almost
feels like you're cheating, but at the same time you still have to go
in and change things to fit your business
needs, but it does a
lot. So let's just look at what it's like
to work with a new project in Redwood, and we're going to
focus on making this button component that I've been
talking about this whole time. So I'm
going to switch over to vs code,
and here you see what a fresh Redwood
app looks like. And I've learned from
doing this a few times not to install
the framework live because it
takes a while. So I don't want to have to sit here and ramble for
five minutes while this loads everything in the background.
But if you do want to follow along, you can
type in yarn, create Redwood
app, and if you like typescript,
you can just add this typescript option.
If you don't, it's okay to work with just JavaScript
files. Then the last thing we need to do
is say the name of our app.
So in my case it'll be storybook demo and then
you would hit enter and it'll start making all
of these files for you. So I'm going to delete that out
of the terminal. But once that command finishes
running, you'll see all of these files that I
have over here. But our main focus is going
to be typically on this API folder and
this web folder. So the API folder,
it handles where we connect to our database and make our
schema. It handles how we define
our graphql types and the resolvers that we'll be using.
So everything for our database and graphQl
server happened right here in the API folder.
But where we're going to be focusing today is
the web folder. This handles all of the
front end for us. So this is where all of our
react is. This is where all of our components will be,
but we'll start. I just want to show you that this is
really as cool as I say it is. So I'm going to run the
app before we make any changes.
That way you can see it in the browser when it
finishes doing its stuff
here.
All right, so I'll switch over to my
browser.
It's always so much fun trying to switch between screens.
Let me make sure I got the right button.
Yay. So this is what it looks like when
you run your Redwood app without making any changes at all.
We're using to follow this little recommendation here. And we're
going to make a home page. So I'm going to come back
over to vs code and
show you a Redwood command. So going to keep
the app running in the background and open a new terminal.
And here we're going to run yarn Redwood
generate page.
And we're so creative. So we're just going to call it home and
we're going to assign it to our root URL.
Might need to use the right version of node that always
trips me up, but just going to run
that command now. And what this is going
to do, Redwood, is going to generate these three files
here for us. So if I come over in the web directory
and look under source pages, you'll see this new
home directory. And it's pretty cool because Redwood
makes this test file for you. It makes a
storybook story for you, and it makes the
component for you. It also updates the
routes for you. So anytime you need to add
a new page, you can just run that command and get all of this functionality
for free. But now that you've seen
how we make a new page, I want to show you how this storybook
components looks. Just to give you an idea before we make
our button. So I'm going to run yarn Redwood
storybook.
And yeah, this is using to
start up our storybook server.
So just using to let it finish web
packing.
Perfect. And I'm using to switch
to the browser.
Yes. Okay. This is what storybook
looks like with that home page component.
So let's say you had some particular page.
Maybe it's a report page and you're
only supposed to show certain columns and
tables if a user has a certain set
of permissions. You could use this
storybook page to toggle between
those different states without actually touching
your app here. So all of the changes
that you want to make or the different scenarios
you want to see, you can do that right here in your
story. And now that you've seen
that, let's make our button finally.
And then you'll see how all of this ties together.
So back here in vs code, I'm going to risk it
and open another terminal and hope that I don't forget the other ones are
open. And we're going to run yarn
redwood generate components
and we're finally going to make that button once
I change my node version again. So now we're
going to make that button.
All right. It did something super similar to
our page. Of course, we don't have a new route for the button.
Thankfully, the button doesn't need a route. That would be weird.
But we have those same files. We have this sample
test, we have our story, and then we have the
component itself. Now we're going to get
into where storybook and component driven
development actually matters.
So we've already installed the styled
components library. That's just how I
like to do my styles. You can use Css if you like.
And yeah, I'm going to make
it like this. But I'm going to come down here and
make this styled button.
It's going to be styled button.
I love how creative programming is with the terminology.
And then I'm actually going to cheat a little
and just copy and paste some code in here.
So what we're doing is
taking a prop inside of this
styled button and based on the type
of button we're working with, it'll update the background color
and the text color. For our button,
let me add some components.
I'm not sure why I did the thing with the weird
quotes, but I'm using to fix that because it'll bug me if I
don't. So we are going to just use
double quotes everywhere. But that's pretty much
what's happening here. We have this styled button,
and based on the type of button,
we'll change some colors. So up here in
the actual components, I'm going to
cheat a little bit again and just copy and paste some code
in here. And this is our actual
button. This is it. Maybe I'll
drop it like this just so it looks like we
have a little bit more. But this is it.
This is the button. You see, we're taking in two props here.
We're taking in the type and the label.
So the use case for this would be,
let's say you have a form that a user is filling out when
they're typing in their data.
Maybe you want it to be grayed out or
a different color. You give it a different message telling them they can't save
till they finish the form. You'll pass that type and
that label in. It'll display the text here, and it'll
change the style of the button based
on what type you passed in. Usually, if you
were checking the different states for this button
in the app itself, you would probably have
to manually update the type every time
you want to check the styles. You would probably have
to do some kind of weird local janky
code just so that you could see the
different possibilities for the state of this button.
But with storybook, we have this story
here, and I'm actually just going to go ahead
and delete that out because we really don't need it.
So we're going to import our button like this.
Since we did export it as the default.
Never mind, let me save that and
undo that. So we got a clean component
here. Speaking of which, we're going
to make this components the button.
This is just some storybook
stuff that helps with organizing things and letting
you know what you're working with. If you want to learn more about the particulars,
you should definitely go look at their docs because it will explain
it a little bit better than I will right now.
So with this empty story,
let's make our template.
To make the complete, we'll just make
this template variable where we take in the arguments that we
pass to the button. So with this template,
we're going to be able to pass in all kinds of combinations
of types and labels to see what
this components would look like with these different states.
That is what our template and our args let us do.
So with the template in place,
let's take a look at what it would be like to make
a primary button. Basically,
we are exporting this primary button
that's bound to our template. So primary
is going to take in these arcs to tell the
button what to render. And what that means
is primary is just this button
with these args applied to it. So if I
save this and come back
to storybook,
because I can definitely switch between screens.
All right, so now you see here in our storybook,
we have our button finally, and it's our primary
button. It's not that impressive right
now, but let's add a few more buttons
just so you can see how storybook handles these different states.
I'm going to copy and paste this a couple of times
and I'm going to call this secondary and
update all of this stuff.
And then I'm going to make this the dark button because
almost a lot of apps have dark mode now,
right? So we've updated this
storybook story to have two more buttons
with these different states and now we're going to look at
what happened in our browser,
which you should see these other components down here.
So now you have a quick view at what the secondary button
looks like, what the dark button looks like. It's all
there and you don't have to go in your code and change anything.
You can just come back here to this story and update
whatever you need. So anytime you change this component,
you can come into your story, add the props that documents
the new component and it also shows off how the new component
works. So you get a bunch of benefit just packed
in here. But this is how
storybook is so useful with component driven
development. Just imagine how useful this is with the table.
I can tell you it's pretty useful because those
usually have all kinds of crazy data floating around.
Sometimes you don't have complete data, so there's columns missing.
Maybe you need to render a weird empty
state because of reasons.
And it's hard to test that when you're just doing that
in a running app locally. There's so many things
that you have to tweak in the code to force those changes
onto components that aren't built in isolation,
that it
makes you be extra careful before you push your
code up for a pr review. But that
is what I wanted to teach you all about storybook today.
So I'm going to switch back over to my
slides and tell you how to
add storybook to an existing project. Because maybe
you aren't working with Redwood, maybe you aren't ready to make that
jump and you have some kind of just a regular react
app or whatever you're working with. It's pretty
easy to add storybook. You just run
this command in the root of your project and it'll set up
the storybook configs for you. You can go
through the docs and look at some of the add ons that are there,
but it's pretty easy to just throw
this into any existing project.
That is all you have to do, do those configs
and then debug it, because it's never that easy.
But in theory, you just do this command and
I guess my doggo wanted to join me for the very end.
Well, that's fine, because we are at
the very end, so I just want to wrap up with a
few key takeaways. Components driven development
really does make long term maintenance easier, if for
no other reason. You have your props
in different states documented. So when business
needs change, you can actually see the evolution
of how the components changed. And when you bring on
new people, when you're jumping around projects that are in
your company, or if you're a freelancer and you're just
hopping in all over the place,
having that kind of documentation and that ability
to work on components in isolation makes
projects way more pleasant to work with.
And then Redwood just bootstraps a
bunch of stuff for you. So if you did want to use the GraphQl
server, there's one command that
takes your schema and it literally makes
the whole app for you. Like it makes the
graphQl server, it makes the types, the resolvers on the front
end, it makes the pages and these components, and it fetches the data.
Redwood does a lot, so you should probably just check
it out and then, my favorite,
keep trying new things. There are so
many new tools out here that it's
kind of crazy. Sometimes you don't have to stick
with everything you try. Just take a
look at what's going on and maybe it'll give you some
ideas for things that you're already working on,
or you might get a fresh perspective on some problem
you've been stuck on. And one other thing I
know, sometimes as developers, we're like, oh, I need to build
this from scratch to prove that I'm so good at code.
You really don't. That's the secret.
You really don't have to prove that, because there's so many tools out
here. If you know how to use them and you know what's going on under
the hood, you're fine. Just use the tools.
Don't spend a week trying to make.
Well, if you could make your own framework in a week, that would
be pretty crazy. But just don't waste your time
trying to make a framework when there's a bunch of framework works out here that
you can try, and maybe later, after you've tested everything
out, then you can make your own thing because you see the gaps.
But I digress. Keep trying new stuff.
That's all I have for you. I hope that you learned something.
And again, if you have any questions, feel free to reach
out to me on Twitter at flipped coding.