Discover3 Minutes with Kent
Claim Ownership
3 Minutes with Kent
Author: Kent C. Dodds
Subscribed: 407Played: 3,615Subscribe
Share
ยฉ Kent C. Dodds
Description
๐ Hi there! I'm Kent C. Dodds (https://twitter.com/kentcdodds). This is a (week)daily podcast where I give 3 minute thoughts about web development.
You can subscribe on iTunes here: http://kcd.im/3-mins-itunes and on RSS here: http://kcd.im/3-mins-rss
You can subscribe on iTunes here: http://kcd.im/3-mins-itunes and on RSS here: http://kcd.im/3-mins-rss
235ย Episodes
Reverse
Hey there friends. So yesterday I was just a fanboying I guess about
Prisma. If you haven't heard of Prisma, it is a Oh what does that? It's
ORN, I can't remember what what the word for that is but it interfaces
between you and a backend database. So it supports post-grass and SQLite my
sequel and a MongoDB support is coming.
So yeah, just so you have a database and you tell it what database what
kind of,Database you're hitting and how to connect to it or what the
connection URL is. And then it manages connecting to it and you have the
rest of your code doesn't have to worry about what type of database it is.
You just work with Prisma. And what makes Prisma especially special is that
it has a really great way for defining your schema for the types or the
models that your database supports. It has a really nice way of making the
database match that so it'll create the tables for you and everything.
It has a great way for my great.Hitting so if you need to change the column
name or something then it will automate that process and and that can be
part of your deployment pipeline is to alter tables to add columns and
stuff like that. It doesn't quite help you with like breaking changes.
It they have some articles to help, you know, how to go about doing that
and I have successfully done that with Prisma. But yeah, and and it's it's
not like a terribly difficult thing to do necessarily but I mean if it's a
really great big breaking change then having zero downtime is tricky.
But yeah, I've had a couple like the situations where I needed to remove an
enum value and stuff and I was able to do that without too much trouble.
Thanks to a lot to prism as migrate feature, but then the thing that you
experience on a regular basis working with Prisma that just I love is its
type script support.
So you define this schema and then it generates TypeScript types. So that
as you're using Prisma you say Prisma dot and then the,The table that you
want to get and info from and then find many and then you have a select and
aware and an order by and if there's relations so like a user has many
posts or something then you can get all that users posts or if you're
looking for posts, you can get the the author and data from that and it's
all just so nice with TypeScript.
It's it's brilliant. So if you are using one of those databases and you
haven't tried Prisma yet give it a look it is fantastic. I'm really really
happy with it. Hope you're having an awesome day andWe'll talk to you later.
https://github.com/johnlindquist/kit/discussions/310
https://www.scriptkit.com/
Hello friends. So this morning, I finished something that I was working on
a little bit yesterday. It's a script kit script to call Cloud Nary upload
which allows me to very easily upload images to my cloud nary account. It
uses the cloud nary API and yeah, I just need a couple of environment
variables and and you can use this too.
You get script kit, you can copy the same script. And yeah, you just need a
couple environment variables and then it uses the script kit. UI which is
basically kind of like,Spotlight or Alfred where you say I want to run the
culinary upload and then it asks you which folder you want to upload it to
and it gives you this way to navigate around those so you can say on the
current folder.
I want one folder one directory yep or I want to go into this directory and
so you can kind of navigate the folder structure of cloud nary which is
really useful for me because I know that I could just like throw all of my
blog post images and all of my epic react article images and all of my
other images throughout my site into one giant bucket andReference those
URLs and whatever but I don't know about you I just really like to have
things organized and directory makes the most sense.
And so, you can navigate around the directory as you would expect. You can
create a new directory and I also cash the other folders that are within a
directory so I don't have to hit the API every time you go you're as your
navigating around. And so I give you an option to refresh the cash for a
particular directory.
And and yeah, and so once you've selected your directory, then it gives you
a drag and drop little UI where you can drop as many images.As you like and
then it goes through each one of those images and asks you what you want
the name of the image to be it gives the default for whatever the file name
is And then yeah and then it'll upload it.
And when you're all done, it will open up your browser to show you to the
directory that you chose so that you can see all the images. It also copies
the URL for each image that you uploaded and so if you have if you're just
uploading one then that's the one that's in your code board.
If you upload multiples and they're gonna overwrite each other, which is
why I think it's really good idea to have a clipboard history with Alfred
is is how I do that. And so yeah, I just updated.My 2010 decade and review
posts in their like 20 images in that post and I uploaded those all of
those and updated the blog post in like just five minutes.
It was really nice. So eventually, I'm gonna automate the whole process of
putting all of my images on cautionary for all my blog posts, but this was
a really good first take it what it's gonna be like for writing new blog
posts and uploading new images. So anyway, this is another example of where
script kit is awesome.
I'll put a link to the script in the description and I hope that's
interesting and helpful. Have a nice day.
Hello friends, so I wanted to talk today about whether or not you should
make a custom hook for everything. So a few days ago, maybe last week there
was this thing going around where people were recommending that you never
ever use the react built-in hooks inside of a component, you always extract
it to a custom hook.
This is terrible advice. Don't do that at all. So the way that I think
about hooks in React is the they're basically functions that have the,Only
special distinction of being functions that actually call other hooks.
That's the only thing special about them. So everything else about this
function is the same as regular functions.
And you don't make a function for every line of code that you write right?
Like that would be ridiculous. The reason that we make functions is to
encapsulate certain logic. And most of the time it's useful mostly for
reuse. Sometimes it could be nice to take a bunch of chunks of code.
And logically put it together so that it can be separate from the rest of
our our code, but you've got to keep in mind that every single time you
abstract something into another function you're adding complexity. And now
you have to pass parameters and and maybe you didn't pass enough and so now
you need to update those in the except the additional parameters and and
and then if you're doing TypeScript, you have to make sure that you're
typing for those parameters is correct and and potentially worry about the
return value and then oh what if now weDecide that there's some logic in
this function that says never mind let's return early or let's throw an
error or something like that.
Now, you have to start worrying about the consumer and say, oh well, they
wanted to return early from here. So, I'll return early. It just gets to be
more complex. There are more things to think about. So you can't avoid
adding complexity when you start abstracting things into functions.
It's just the way that it is it always adds complexity. Now whether or not
it makes your code simple or more simple.Is a different matter or sorry let
me say that differently whether or not it makes it easier for you as the
the writer of the coder and the maintainer of the code to understand what's
going on.
That's a different matter. But the fact is that it will always increase
complexity to extract things into separate functions and that is no
different with hooks. This is especially relevant if you wanted to abstract
just the use effect part, but you want to pass in some sort of function
that's going to get called within that effect.
That means that you'll either need to.Call back that your passing in or you
have to use the latest ref pattern to always use the latest function. So
anyway, hope that helps.
https://stackoverflow.com/a/46780568/971592
Hello there friends. Sorry, it's been a little bit of a break but I was
working on something and I wanted to measure how fast it was but yeah and
so I'm gonna use the Chrome DevTools profiling performance tab to profile
it. And it's always so frustrating to like try and find the part of the
code that you're trying to profile in that flame graph.
It's really kind of a confusing area. And I remembered that there's the
performance mark API and so you have the ability to add your own custom
timings and so,You can say okay here's the start of what I'm trying to
measure and here's the end. And how long did all of that take?
And you can do like performance down now console log in and then like
compare and stuff. But I wanted to look at the flame graph. And so I it
didn't work right away and I looked up and found a stack overflow post that
showed exactly how to do this and so I'll link to that in the notes of this
episode.
But basically, it's a combination of the mark and measure APIs on the
performance object. So you say performance dot mark and you give it a
string to label that mark.And then another performance you do whatever it
is you want to do So in my case I wanted to measure the reading time of a
blog post and I'm using this module called reading hyphen time, which I
think is what like all the gaps people logs and everything used for this.
And so I call that function and I'm on a really big blog post and to test
this out. I call that function and then on the next line you say
performance.mark and you give it another label and then you say right after
that performance dot measure and you give three arguments the first is the
label for.
The measurement the second is for the start marker So whatever you put for
the first performance dot mark, that's what the second argument here. And
then the last argument is whatever you put for the end. So you give it a
name and then the start in the end and then that will show up in your dev
tools in the performance profiling tab and it just makes it so much easier
to make sure that you're honing in on the area of the code that you
actually care about.
Unfortunately, I don't know whether this works very well for asynchronous
code. So, I cure it's we're gonna do an await here and then afterThat away
I don't think that's gonna work very well But for synchronous code it works
great And actually if we're talking about async code and there is some
performance profiling metrics that you can do with React app specifically
and they do have the ability to do some sort of timings for that with
asynchrony.
It's actually very cool and I teach you about it on epic react. So if
you're if you're not done the performance workshop yet, or the actually the
performance section of the bookshelf app, then you may not have run up
against that. But it's really cool. All right, hopefully that's helpful.
I'll chat with you later.
Hello there friends. Welcome to June I am thinking about Postgres and
Prisma and that sort of thing a lot lately because I'm working on my
website and doing that sort of thing and one tip that I have for you if you
ever do database sort of things is try to make sorry to make your data as.
As restrictive as possible. Early on as as you're trying to make things. So
like make things if you're like, I don't know if there should be a required
field or not make it required. If you're this is an enum but we could have
this we could have a lot of different values for this potentially have the
fewest number of values possible to get you to the next phase.
The reason is because it's a lot easier to later do a migration.That
expands the permissive venous of that schema than going the other direction
because when you go the other direction, you have to find all of the data
rows that don't go into the new schema and update those so that they they
fit.
So, for example, if you have a first name field and you decide to make it
optional first and then after you have a bunch of users you come in later
and you decide no no this first name field needs to.Be required. Well, now
you have to first go and update all of the usernames to be like unknown or
something before you can do that schema update.
And so yeah, just try to when you're starting a new project or when you're
yeah, I guess not even a new project but when you're adding a new model or
something like that try to be as restrictive as possible early and then you
can loosen things up later when you have more context and you know, what
makes more sense.
So yeah, hopefully that's helpful and interesting. IIt's this is just
personally affected me because I I was really loose at the start of this
project and then I had to tighten things up and it's kind of annoying. So
anyway, I hope that's interesting helpful. Ah, but a nice day.
https://kentcdodds.com/blog/fix-the-slow-render-before-you-fix-the-re-render
https://kentcdodds.com/blog/colocation
https://epicreact.dev/improve-the-performance-of-your-react-forms
Hello there friends. So today somebody shared a lightbri with me and I
assumed that it was just a library to help you track rerenders. But it
turns out it's like a state management library and that helps you avoid
rerenders but my initial reaction and thought about tracking re-renders is
the tools like that.
I think lead people to jump directly to the natural and obvious solution,
which is often not the best solution and I'm talking about memoization. So
when,If you're tracking rerenders and that's how you measure whether
something's faster or not you're gonna say, oh well this component didn't
need to rerender so therefore.
I will apply the re-render hammer to solve this problem and that is react
memo. And then you have to use memo or use callback all the things that you
pass to it. And that spiders in into the rest of your code base really
easily. And so what I recommend is I have a blog post called fix the slow
render before you fix the rerender and so you have to put a little bit more
thought into it, but you find out what part of you.
Here rendering is slow because even if you fix the rerender at some point
you've got to render like there are necessary renders. And if those are
slow then that's not a great user experience either. And so if you can fix
that then maybe you'll be able to avoid needing to worry about rerenders.
But sometimes you just there's nothing that's slow in particular. It's just
a lot of things that add up to make the experience slower and so fixing
renders is kind of the the best approach for that. And when you're in that
situation, then I actually wrote.Another blog post called state look
colocation can make your react apps faster and just recently wrote a blog
post that takes an angle on the like forms and how you can use state
collocation with forms and I'll link all of those at the top of this the
description this episode.
But basically, I think that we can get a lot by using state co-location
also composability and composing our components, especially like layout
components, so you don't have to pass.Props through all these other you
know app components And as with a combination of the way that you structure
things you often don't have to worry about unnecessary renders because they
just can't happen.
So anyway, the library itself was a state management tool and and some
people get a kick out of that and that's great. That's awesome. I haven't
found myself needing to reach for many state management tools outside of
react query and went with Remix. I don't really need a state management
tool.
It's pretty awesome. But yeah, those are just some of the thoughts that I
had when I first saw the name of this librarian. So hope that,Is
interesting and helpful have a nice day.
Hello there friends, so I was thinking this morning about utilities and you
know these little utility functions that we write and we put it in like a
utils modular or something and sometimes when we're running these we want
to split things out to make it just.Easier to manage or something and and
it's just kind of a natural thing at least for me to want to split things
out into individual files, so each utility is in its own file, you know, if
it's just a single line or something.
I typically just keep it on one but if it's kind of complicated or maybe
there are group of utilities that make a lot of sense together. I just feel
naturally inclined to move those into a separate file. But what I've found
is in my experience is that you're often better off just leaving utilities
all in the same file and thenMaybe using code comments or something to
separate different parts of that file because what what I found happens
over and over again is one utility depends on another and that utility
depends on this other utility which depends on the first one and so you
have like a cyclic dependency or cyclical dependency sort of thing and so
when you try to start pulling things out into different utility or into
different files, now you have to extract the other files.
Or other utilities into separate files as well ultimately leading to
basically a lot of files that have just a couple lines of utilities. And I
definitely don't see that as being any simpler. And in fact, it can be even
more complex when you start adding type script and now you have types that
you need to extract it to different files so you can use them together.
So, but there is a reason that we like to keep our files shorter and that's
because when when you have a really big utility that can be really
complicated. I,Worked on a a backbone view that was like 3,000 lines long
once and it was not fun and I did not like having such a big file, but I've
been thinking about this and I think that the problem isn't necessarily the
size of the file the problem is the size of the the individual component.
And so and just the number of concerns it was mixing. That was what made it
really difficult. And so yeah, the the length of the file that doesn't
really matter all that much. It's the number of mixed concerns that makes
things really difficult. So, I would encourage you to.
Think twice before extracting utility files or your utility functions into
individual files and maybe first try to organize that file a little bit to
make it easier to manage. I hope that's helpful and interesting have a nice
day.
Good morning or afternoon or evening friends, I wanted to talk today about
a saying that my wife has I think when my kids grow up they're gonna
remember my mom always used to say this and and so what she says is we'll
cross that bridge when we come to it now, of course this isn't like an
original saying but she just says it a lot and what she's saying is that
she doesn't want to make these decisions right now or use up the mental
energy to decide whether or not.
She wants to let the kids do a certain thing or whatever and I've taken to
saying it myself, um and what I'll often say is if you want me to answer
now, I'll just say no so why don't you wait until I'm able to think about
this but it was I was thinking about this in the context of programming and
that's kind of what doing calculations within an if statement or the right
side of a ternary operator something that's kind of what that's like, so
sometimes I will have a block.
Of code where I'm doing some calculations and then I have an if statement
that says if such and such then use the value of those calculations
otherwise do nothing or otherwise do something else and so if you do your
calculations first, then you're kind of crossing the bridge before you came
to it you're making a calculation for a value for which you may not
actually need at all if you don't end up going into the consequent and
actually using that value and and so I get instead you put the calculation
within the if block or what we call the consequent then.
Then you're crossing the bridge when you come to it you don't actually need
to make that calculation until you actually need to get that value now
there are I explain this to my wife last night and I thought oh that would
be a good thing for three minutes with Kenton and she said well now what
are the situations in which you would ever want to do the calculation
before, you know, you actually need it and I said well, sometimes it can be
useful just for the way the code is structured you do all the calculations
up here, sometimes it's easy to calculate one thing while you're
calculating another thing even ifYou may not need both of those things and
so there are reasons where you might want to cross the bridge before you
come to it, but I I think in those situations you want to make sure that
you're not ending up with a performance problem of some kind so mentoring
can help out a lot so at the end of the day it comes down to readability
and what's the most readable and then the exception is for those times
where it's a performance problem then then you do things anyway just
thought it was kind of interesting analogy or metaphor.
Hope you're having a nice day, we'll talk to you later.
Hello there friends So this morning I was just thinking about this little
tip that I share with you. It's pretty quick. In my global git ignore,
which is located in my home directory dot get ignore underscore global. I
have a couple of things in here that I wanted to shout out and specifically
this morning.
I was thinking about my ignored global good ignore. So I am I have a two
rules that will ignore any files that or any directories that end in dot
ignored in any files that include dot ignored dot in the file name and so
what this allows me to do is very easy.
Within the context of my project create a temporary file like temp dot
ignored.js where I can script up a little things. I can require
dependencies and require files in my application and whatever all within
the context of the app and I can mess around kind of like a playground sort
of thing to work on something until I have it solid and then I can take
that code over to where it actually is.
This can be really helpful when the feature that I'm working on is
difficult to like navigate to or whatever the case may be. And so yeah,Or
like it takes a series of steps even if it's not a UI thing if it takes a
series of steps to get it to this particular state.
Having a little file that I can use as a playground that doesn't have
anything to do with get or whatever is really helpful. So yeah, the way
that I do that is a star dot ignored slash and so that's for directories
that end in dot ignored and star dot ignored dot star which will ignore any
of the files that I included dot ignored.
A couple other things that I have in here that sometimes people don't have.
So this isGoogle ignore this applies to all of the get projects in my on my
computer a dot ds underscore store and so when you open up a directory in
in the Finder app on a Mac and creates this really annoying file and I
still get pull requests from people all the time that included dot ds store
and so I think I actually add that to my get ignore for each project as
well when it's like an open source thing just to not deal with that.
Also dot VS code. I know sometimes you can set like,Little local settings
in there and so sometimes I'll force add those but by default. I don't want
that in there dot idea for web storm and then you've got some like NPM and
yarn debug stuff some VIM stuff in here with a star dots SWP and yeah
anyway just kind of some helpful tips.
I think the biggest one is the diagnord. I also have dot local sometimes.
I'll put that in projects for like here's the dot EMV dot local, so it's
just the stuff that's local on my machine. I don't want to commit that.
Hope that.Helps. Have a wonderful day.
Hello friends so I mostly recording this one so that I can hopefully not
forget it because I was working with doctor yesterday and I don't work with
Docker a lot but I'm kind of thinking about in the next version of Epic
React. I want to take the application that we build and make it even more
real world.
We're going to jump off of Create. React app and use Remix. Don't worry,
they're probably going to have some sort of free tier or a trial version or
something. So, I'm not going to force people to have a license to remix to
take epic react. But I do want to teach you the the best way to build React
applications andI think that that's remix and so it'd be a responsible for
me to do it any other way.
So anyway, we're going to be probably using remix and we're probably going
to use a real database and this presents a lot of challenges because I'm
here to teach you how to build React applications and I need to limit the
scope otherwise it the course will be just enormous.
And so I don't want to teach you how to set up a database and the easiest
way to do that is to have you use Docker but then doctors and entirely
different subject as well, that is also not easy. If you've never used it
before I I'm struggling with it myself.
But anyway in the process of I'm gonna try and like give you a bunch of
scripts that you just run these scripts and and everything will work and
that's the hope provided that you get docker installed properly. So we'll
see hopefully that works out nicely. But my the thing that I learned
yesterday or kind of today is that there I set up a postgres database
inside a Docker container and I have a Docker composed file and I was
following a tutorial and one of the things that had in there was.
I guess I probably should have had this pulled up and ready for you it's
Docker compose.Yeah, and it had oh I actually lost it had some like volume
thing in here. And the and setting up the particular volume is basically
where Docker is going to persist all of the data that is in the Postgres
database so that when you close down the Docker container you can open it
back up and all the data is still there.
And I had a lot of trouble because I would try and delete the image delete
the container and create it all brand new but it would reuse the same
volume and so,I wasn't able to just delete all the tables and whatnot. So
finally, I figured out how to do that and and it was from help from people
on the YouTube comments of the Line Street I needed yesterday and it's a
simple as using Docker volume LS to list out all of the volumes that you
have and then Docker volume RM and then providing the the name of the
volume you want to remove and that deletes all the data.
And you can also do ducker volume prune and that will remove them all. So,
that's what I learned.
Hello there friends, so I've just been thinking about incentives and
companies and and the yeah, like what what motivates people to have
different opinions and stuff like that. And I want to use myself as an
example here because I think it's a there's a lot of nuance with the way
that we kind of automatically think that people are have ulterior motives.
So, I created epic react to teach people how to learn react. And so my
question is did did I create epic react?And then say hey everybody it's
React is amazing and like is my ulterior motive in telling people that
react as awesome and they should use it so that I can sell courses or did I
discover react and I got really excited about it and I and I just think
that it's a fantastic way to build it web applications and so as a result
of this I create epic reacts as well as all of my other material and stuff.
To convince people to use it just because I think that it's a really great
framework. And then I finance my my free work by selling.Epic React I can
tell you that it's the latter but how do you know. You can't really trust
my word for it because my I could have an ulterior motive.
And I think this is the sort of thing that's really new on. So just to give
you another example, let's say that there's somebody who's really bullish
on a particular stock. They maybe it's Apple or something. And so, they
they create a YouTube channel that just goes all on on and on and on about
how great Apple is.
Now our did they create like what order did this happen in did they create
the channel and then they say,Wow this is a great way for me to get people
to buy the stock. I'm gonna pump the stock up and then I'll my purchase of
the stock will be worth a lot.
Or is it a kind of more of a combination where they are really bullish
about Apple so they buy a lot of stock and they're like man. I just this is
such an awesome company. I'm also going to start this YouTube channel to
talk about why I think it's such a you know, a great investment or
whatever.
So anytime you see somebody who seems to have a conflict of interest.It's a
very very possible that that conflict of interest is the entire reason that
their motivated to behave in the way that they're behaving or speak and say
the things that they're saying. It's entirely possible that there's that
bias and that's controlling everything.
But keep in mind like kind of walk history back a little bit and and think
okay, maybe they really have this solid conviction and that's what made it
motivated them to go and buy the stock or what motivated them to create
this thing and pump it up because they already had that conviction and they
don't maybe have an ulterior motive.
Hey there friends. Have you heard of progressive enhancement or progressive
web apps? Well, I thought of a real world thing that kind of resembles what
this actually means and what it doesn't. So, you know how like there's all
these memes of like I got a smart thermostat and now it's broken because my
internet went down or something like that and so now I'm like steaming hot
like why did I do this and and we have the same sort of thing with my watch
and so I have a smartwatch.
It's a,Nice one. It's a fossil I guess. And then I also have an aura ring
and both of them are useful in their own different ways. But when my watch
breaks or if it runs out of battery, which is more often, it doesn't break
very like ever. But when it runs out of battery, I'm no longer able to even
tell the time.
So, it's like totally a break. It's useless as just like a break on my
wrist. That is not great. But when my ring runs out of battery,That's also
not great but it's still functions as a ring. And so in this context
progressive enhancement would be like my ring will always function as a
ring but it progressively enhances in that when it has battery it also
functions as a way of taking my my pulse and different things like that.
Whereas with the watch if it doesn't have power, it doesn't do anything.
It's it's not serving its purpose at all unless I suppose if you just like
appearing like you have a watch but it's basically.Other than that. And so
when we're talking about progressive enhancement or progressive web apps,
we're talking about taking advantage of the tools and capabilities of the
web and all the modern and cool stuff but not exclusively not at the
exclude exclusion of functionality for browsers that don't support those
modern features.
And so we progressively become a even more capable web app when those
features are available. And so in my contacts with the,Watch in the ring
that the extra feature that's available is power. And with the watch it
doesn't progressively enhance, it just doesn't work at all without that
extra feature of power.
Whereas with my ring it functions as a ring just fine whether or not it has
power and then if it does then improgressively enhances to do a lot of
other cool things. But anyway, that's kind of what I think about
progressive enhancement progressive web apps. It's kind of an interesting
thought.
And yeah, shout out to remix particular for taking this.So seriously. I
hope that's helpful to you have a wonderful day.
https://kcd.im/trophy
https://kentcdodds.com/blog/eliminate-an-entire-category-of-bugs-with-a-few-simple-tools
TypeScript is tests. Tests are type script. So type script is just a way to
give yourself more confidence. Sure, it helps you in your workflow, it
makes you a faster as you're developing because you have autocomplete and
stuff like that. And testing does the same thing as well as you
refactoring, you know that you didn't break anything you get a much faster
feedback when you you're running your tests as you're working on things.
And both of these also make the initial code take longer. So it takes more
time to think.About the types that you're writing takes more time to
actually write the tests. And they can also be an enormous time sink where
you spend a ton of time working on a task or a ton of time working on the
on the types and then you've later realized that you don't need that code
at all so you just throw all that work away.
So, I I find that typescript and testing are way more related than they are
or similar than they are different. And I think this is a good thing
though, the whole goal is to be more confident in the changes that
were.Making in the application that were shipping. And the cool thing about
TypeScript is that it eliminates an entire category of bugs.
I actually have a blog post about that. And it also eliminates an entire
category of tests, which you're probably not writing but maybe you should.
So one of the things about code coverage is that it doesn't what we really
actually need is data coverage or use case coverage because you may have a
function called ad that accepts two numbers and add.
S them together and you could write a couple of tests for that if you
wanted to but you're probably not writing like it's not very normal for
people to write a test that says what happens if I pass a string what
happens if I pass a boolean but you know, what a you might have a test that
says what happens if I don't pass the arguments or something and because
there are some defaults.
But and that and because there are defaults you're going to want to cover
that. But we've very often don't do a whole lot of defensive programming
and runtime and type assertions of.You know, what the arguments that were
passed? Maybe you do that for some of your functions, but probably not all.
And so you can you don't get a much confidence in in that aspect. And you
you could but it's just way easier to just use a type to language like
TypeScript and then that entire category of bugs in the entire category of
tests don't need to be written. So type script is tests.
Good morning or afternoon or whatever it is for you friends, it's morning
for me. I wanted to talk about how I type a raise in TypeScript, so there
are two ways that I'm aware of that you can type an array and of course I
guess there are a couple ways depending on what type of an array you want
to make but just like a regular array you can either specify the type and
then immediately thereafter with no space a open and closing bracket like
the the syntax for an array and the alternative is there is a built-in.
Array type which is a generic and you say array and then open bracket no
that what are these angle brackets that's what is called an open angle
bracket and then the type of that's in the array and then a closing angle
bracket and I prefer the latter. I like using the generic array and the
reason that I prefer that I I think that I just like just kind of preferred
to that from the beginning, but I think the reason that I prefer using the
generic array is because I don't,Like reading my type and then getting to
the end and be like, oh this is an array of those things so I I see we've
got um user and then I see the opening closing bracket and I say oh no,
actually it's not a user it's an array of users, whereas if I use the
generic I can see oh we've got an array and the things that are in the
array are users and so I'm when I'm reading from left to right it just
seems to make more sense to me to to read it in that way, it's kind of like
in English it.
I I like how in Spanish and you have the,If you have like an exclamation
you're going to have that upset upside down exclamation point I don't know
what that's called but you have that upside down exclamation point at the
beginning of the sentence so you know ahead of time that the thing you're
about to read is an exclamation rather than getting to the end of the
sentence and being oh yeah, I'm supposed to be like excited about in saying
this or something like that when I'm reading a book my kid or something and
so I kind of see that in the same way and that's why I prefer using the
generic over the the special syntax for specifying arrays, it is a little
bit more type.
Of being or more characters but I actually don't care too much about that
and then that comes with the benefit of switching from a regular array to a
read-only array, you know being a bit easier and stuff like that so anyway.
I just thought that would be something I'd share today.
I hope you're having a wonderful day and I'll chat with you soon.
https://twitter.com/kentcdodds/status/1394420201542668289?s=20
So the other day I tweeted about how I really want people to stop minifying
and bundling what they send to NPM. And just to clarify I it's fine if you
want to minify and bundle as one of the things you distribute as part of
your package, but it shouldn't be the only thing and there are a couple of
reasons and what I do for my packages is I actually do have a UMD module
that is bundled and I have a minified version of that as well.
So we have two of those and then I've got an ESM.R version which is like
fake ESM right now eventually I'll get around to making a native VSM
supported version. And then a common JS and those are the the four formats
that I shipped to NPM. So the reason that I really really don't want people
to exclusively ship minified code is even with source maps can it can be
really difficult to debug and especially when we're talking about libraries
that I'm interacting with well even even transitive dependencies.
I like to be able to.Stick a console log in there or to step through with a
debugger and it's just really difficult to do that if you've minified your
code and in particular what motivated me to tweet this in the first place
was I was working with a library that minified everything and it ended up
minifying its implementation of an abort signal and so the constructor name
was incorrect and node fetch actually checks the constructor name to know
if what you've passed is an abort signal which we could argue about whether
that's necessary or not, but the fact is that it does and becauseThey were
minifying it totally is unusable which is a less super annoying.
So that's notification then on the bundling side of things this can get to
be a real problem like if for example your bundling a particular library
and I'm already using that library in my project MPM can't dedupe that and
do means it says, oh you're using this library in this other dependency
uses that library too.
So we'll just have them both use the same files and therefore we don't have
to send.That code to the browser twice so we don't have to require that
code and evaluate it in person all that stuff. And so there are arguments
that people make about bundling as like performance improvement so like you
could do that with some tools and and that could be useful but it could
also be a big problem because then I can't like change the versions of the
things that I'm using and I don't have any control over that.
So there are a lot of issues there in general. So, please don't bundle
don't minify it's better this way. Let meDo that.
Hey friends, so I'm working on this little remix app and just something
about remix that I just this so cool the fact that your server and client
side code run is written in the same file if in case you didn't know that
that's that's what you do and it's really cool for validation so you can
start by validating just a hundred percent on the server and remix makes it
quite nice to be able to do that and that's where your validation should
absolutely.
100% go by default that's like if you're gonna do it anywhere do it right
there, but having client side validation can be nice for you know, showing
error messages and stuff and so because the client side and silver side
code is written in the same file, you don't want to like duplicate that
that logic and so you just extract it to a function and then in the server
you call that function and the client you call that function and when remix
shakes out all of the stuff that function will appear in both places, but
you don't have to write it twice and so.
I'm just writing out a form right now and I had a a maximum length for a
particular field and so I can just put that variable outside of everything
and make sure that I only have one specific place where I say what the max
length of this is gonna be and then I just use it in the client and in the
server all in that same one file.
I don't need to like put in a different module and import it or anything
it's all just right there and I just think that's awesome that I I'd share
that with you remix is just my friends it is something else. IFeel super
productive working with this and yeah I the cool thing is that it's I feel
like it's both pretty quick to get at for it to become familiar so it
doesn't take the long for it to become easy relative to other stuff that
I've worked with but it also seems so simple and so therefore I can build
simple applications with it and and and and I I mean, I haven't written an
application in a million lines of code with remix and,You think but I feel
like this would scale well to that based on the experience I have in
writing and working on enormous applications, so yeah anyway remakes it's
it's awesome and I know that I gush over it but there's a reason it's not
it's certainly not because Ryan and Michael are paying me in fact I paid
them to be able to use it so there's there's no conflict of interest there,
they're my friends, so they're there's a full disclosure but this thing is
out of this world, so if you haven't taken a lucky remix yet and give a
good look at it.
See ya.
https://kentcdodds.com/blog/make-your-test-fail
Hello there friends. I'm just driving now. I was thinking about a blog post
that I wrote a while ago. I think it was called break your tests or
something like that, but the idea is that it's just really easy to write a
test that passes and so you feel really good about it this this especially
happens if you're testing after you've already implemented something if
you're doing TDD this is maybe less of a problem, but it's really easy to
write a test that's green and we're happy with it and,So we commit it and
we move on and then we later find out that that test wasn't running to
completion or it was the it wasn't testing what we thought it was testing
wasn't making the right assertions or something and so it wasn't actually
doing what we thought it was and so then the thing that we were intending
to test ends up breaking in that test doesn't doesn't save us from that and
so what I suggest that you do is you take the time to actually try and make
the thing that you're testing break, so you simulate a failure this could
be.
I'm pretty much like any any step of the process of what it is that you're
testing maybe you're making a request to get some data and then you're
displaying that data in your asserting that the data is displayed properly
and so you could just comment out the code that updates the state or
something like that and so it's normally very easy and it's a manual check.
I don't think that there would be a whole lot of use in like at this point
you're testing the tests and I don't see a whole lot of benefit and like
how far do you go, do you test the test the test the test?It's just sorry
cracking myself up um yeah so like at some point you have to say okay,
we're good with just doing a manual verification of this and so that's
that's what this is is just a manual verification that yes this is indeed
testing what I think it is and I verified that by commenting out the
implementation or changing the implementation and in a certain way to make
sure that the test will catch me if I mistakenly change the implementation
in this way, so yeah, as you're writing your test for your software, I
suggest that you break the test and I will.
Add a link to the blog post where I dive into this little in a little bit
more detail at the top of the notes for this episode so you can go take a
look at that. I hope you have a wonderful day and we will chat with you
later bye.
Friends I'm out and about today so we might hear some like music in the
background and stuff but yeah today I wanted to talk about cypress driven
development. I was working on something that I'm working on for the new
website where you can submit a recording of a question and then I'll be
able to answer it's gonna be really cool but it's all like in browser
recording stuff and lots of what I was testing was like required me to have
to record something and then to continue on through the the work.
Or the flow and that was super annoying to have to you know, make a change
and then go through that whole flow again and so I was like, well, this is
the perfect situation for cypress different driven development so I made
like a I don't know ten lines cypress function or or test that went through
that I did have to do a couple fancy things to make it so that cypress
would accept a fake wave file as input which I made a maniacal laugh and I
found online but uh, yeah, once I had that I'll set up it was really.
Cool every time I made a change to anything I would just have cypress rerun
it would rerun automatically and and then I could look at the terminal
output or the console output and get a good idea of what what was going on
so yeah I was really it was like nail on the head for cypress driven
development.
I don't think that it's always necessary but especially when you're working
on workflows and stuff and like this is the sort of thing that hot module
replacement like yeah, maybe that work okay, but just is not going to do it
for you.For this sort of thing like I never really trusted how much of a
replacement and so the and this is the one situation where people say, oh
yeah how much replacements really nice if you're like what you're working
on is pretty far into some workflow or something that you don't want to
have to do over and over again, well, sometimes you do need to refresh for
one reason or another and having cypress just get me back into that state
and like a half a second yeah that's awesome and it's like a real actual
experience so if you've not tried cypress driven development.
I suggest that you give it.A shot because it's really helped me be really
productive and at the end of it. I'm I may actually be able to use this as
a test as an actual test to keep me confident so there's that I hope that's
interesting and helpful and useful to you and hope you have a spectacular
day you take care and all talk to you later.
Hello friends So today a friend of mine on the KCD Discord is named Rupert.
I'm not sure. I'm pretty sure that's how you say their name. But I created
their very first poll request for open source. I wasn't aware it's the
first poll request but they did a great job.
And it was for the KCD Discord bond. And so the discord has a lot of cool
things you can do with it and one of them is they're a bunch of commands
that you can give. One of those commands is the thanks command where you
can give somebody extra kudos to say thank you and we'll record.
The that in a thanks channel so you can look at and see all the people
who've received gratitude and who've given gratitude and then it will log
that in a github gist. That's our storage mechanism for this bot. And and
actually, I think this is the only thing that requires storage that we have
but um, it's ends up being just this giant JSON object.
And so we've had this for a while Marco built it initially and it was cool
because you could say thanks ranked top and it would give you the top.10
people who'd received the most thanks. But I wanted to also have a rank for
the people who give the most gratitude as well because I think it's a nice
to to have that.
So he Rupert made the a change to also allow you to say thanks gratitude
ranked top and that would give you the the top 10 most grateful people in
the server. And it was just kind of a way to recognize people who are
making our community special and and grateful thankful.
And,Yeah, so I just kind of wanted to talk about that just a little bit and
say, hey, you know gratitude is important and it's helpful and in fostering
a community that I want to be a part of and hopefully you do as well. And
by giving a just the little bit more recognition for people who are
grateful, but also the people who are being thanked, so the people who are
doing helpful things.
I think goes a long way to making people more encouraged to continue to do
helpful and,And good things and and also to be more grateful. So and
gratitude has been scientifically proven to improve people's overall
happiness. So if you're a grateful person, you're happier. So go be
grateful today, and if you're a member of the KCD discord, then go say
thanks to somebody using the Thanks command.
And if you're not then joined because it's a cool place to hang out. All
right. I hope you have an awesome day and we'll talk to you later.
So let's say that you want to convince your coworkers to try a new tech or
something like a new library or whatever and you think it's a really good
idea but people aren't convinced. So what typically happens is you want to
prepare a couple of ideas and stuff and bring it to a meeting and say,
okay, here's here's what I think and why I think this is a good idea.
And then people will present their reasons why they they don't think it's a
good idea. And people may come to the meeting kind of predisposed to
disagree and and want to just say,No this is just extra work that you're
making me do and and so as soon as somebody gives a reasonable good
argument against you against your idea for everybody else that just is like
the thing that they can latch on to and if you're not prepared to deal with
that then then you just lose everything.
So this is what I do and what I've done to convince members of my team that
my idea is a good one. And that is first you have to like that obviously
you have to really believe that it is a good idea and you wouldn't want to
present something that's not necessarily a good idea.
But then,What I have done is I will reach out to everybody who's going to
be coming into the meeting all the decision makers, but also just the
people who are going to show up so even people that may not be making the
decision they just might voice a concern of some kind.
And I will just ask them what are their preconceived issues that they have
with this idea? And I'm just talk a little bit about it not. We're not here
to have an argument or anything about the merits of the idea. We're just
here to gather their hang-ups with it.
And do that with everybody who's coming to the meeting so that you can
prepare and bring up their arguments before they have a chance to bring
them up and and you bring it up in such a way that you can immediately
address it and say now some of you were worried about this, let me explain
why that's not a problem.
Or you may not even need to bring that up. You can just solve that problem
before they before mentioning the problem in the first place. As part of
your presentation, this will go miles to help you convince people that your
idea is a good one and help alleviate concerns and they're concerned.
The real and you need to address them But if you want to have success and
convincing people you want to avoid the mob mentality where one person
shares something that's like now this is not going to work for this reason
and everybody just latches on and they won't listen to your explanation.
And maybe you'll get caught off guard too in that situation. And so by
asking ahead of time you are made aware of things that you may not have
considered and you make sure you address those and it's also possible that
you can cancel a meeting because you realize that oh actually this isn't a
good idea because of these concerns.
So anyway, this is something that's helped me in the past. I hope it helps
you and I hope you.