What's the state of the art technique when it comes to asset bundling in WordPress? Should we use grid for every component? How should we test ecommerce site builds? And Dave goes back to the Mac!
Time Jump Links
- 01:44:00 What would you say is the state of the art technique when it comes to asset bundling/management when it comes to WordPress?
- 21:44:18 Sponsor: AWS Amplify
- 24:29:00 Should we use grid for every component we're building?
- 35:59:00 Sponsor: Netlify
- 38:51:02 Dave Goes back to the Mac?
- 00:44:15 What strategy do you recommend for testing ecommerce?
MANTRA: Just Build Websites!
Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another episode of the ShopTalk Show, a podcast all about front-end Web design and development. I am Dave--at home with the kids--Rupert--and there's a trashman outside. With me is Chris--new officer, old booth--Coyier. Hey Chris.
Chris Coyier: [Laughter]
Dave: How are you, Chris?
Chris: Doing just fine. Doing just fine. All that office crap is behind me now. We are 100% out and into the new place and all that - having fun.
Dave: You know we're recording this a smidge ahead but, if all goes well, there should be a pit of concrete in my backyard by now. [Laughter] So, that's very exciting to have a pit of concrete, so looking forward to that.
Chris: I agree.
Chris: Upon which a shed will be built, which will be Dave's work reservoir or whatever - oasis.
Dave: Paravel Far West.
Dave: So, there we go. There we go.
Chris: Yeah. All y'all are moving, I hear. Anyway--
Dave: Oh, yes. Except Reagan added on, so that was probably a smart move, so there you go.
Chris: More value. Well, we've been talking. Let's do some questions and then we'll get into some stuff a little bit - just for fun.
Dave: Because we do have a bit of a special announcement that we're building up to.
Dave: It's probably in the show title, but it's a bit of a special announcement.
Chris: Not a banana, not a pear button. Marcus Kober writes in. He's been a WordPress developer for a long time. Made 160 WordPress themes for customers, so yeah, I'd say he knows what he's doing in there.
Chris: "I've built sort of a framework for myself." This is Marcus talking. "It all works fine, but what I'm messing around with now is asset bundling. I've used Gulp." We know Gulp, right? Gulp is a task runner.
Chris: Just with the Webpack, then moved to Parcel.
Chris: Then eventually switched back to Gulp. What a funny, little, tricky thing there. He's bundling assets for just like generic themes.
Dave: [Singing voice] The circle of life.
It kind of makes sense as an entry point file, whereas Webpack, you are much more used to pointing it at an index.js file as kind of the entry point and multiple entry points were less of a thing. Although, I don't know if that's changed or whatever. I know Webpack 5 is out now and all that, whereas Gulp, you just configure it however you want. It doesn't really have the concept of an entry point. It's just like, "Do this job."
Dave: Gulp is very much like, "Go grab every CSS file or Sass file and just do it." [Laughter]
Chris: Yeah, instead of globbing, right?
Chris: Yeah. Okay, so I need various entry points. The CSS on the homepage, the CSS used, for example, by Advanced Custom Fields. He's a little opinionated about how he wants things bundled, which so am I.
The reason I switched from Webpack back to Gulp--the detour to Parcel was because of the multiple entry points thing--is how tedious adding new entry points when creating, for example, a new ACF block was, except the fact that I was pretty happy with Webpack because it automated so much. Now I have to manually do that in my Gulp file. He's making a new block, which I don't know how many of you have done this, but it's pretty cool. I think ACF blocks are remarkably cool in WordPress. They did a good job with those.
Dave: [Laughter] It's my own Gutenberg block that spits out a text paragraph.
Dave: Yeah, it's cool. Yeah.
Chris: Honestly, I do have one that I don't think has any CSS because I scaffolded out my own detail summary block. I don't know if this has changed in Gutenberg now, but at the time, it didn't have one. What you want in a detail summary block is a summary element but then absolutely arbitrary everything else.
Chris: I know you've talked about this before. It's a little dangerous to put lots of stuff in a details element because all the semantics of it gets totally wiped, but you might want a list in there.
Dave: A summary, yeah. Yeah, yeah. Yeah, yeah.
Chris: Yeah. Yeah, just anything in the details. The summary is the thing that you click on to toggle it and then everything else inside there. Like if you put a header in there, not going to be a header. Whomp-whomp.
Dave: Yeah or it's hidden by default or whatever.
Chris: Or is it the summary that gets wiped out?
Dave: The summary gets wiped out because that's a button and it has a role type button.
Dave: Some browsers have role summary, but it's basically--
Chris: So, don't make that. You can put an H3 in there if you want, but then that won't read as a header. But what if you put an H3 in just the details? Is that cool somehow?
Dave: It will still be in document outline, you know, but basically if it's hidden, it's hidden.
Dave: I don't know if it gets stripped or not.
Chris: The fact that you have a header that's hidden or not is maybe not the best idea anyway.
Chris: All right.
Dave: It's a disclosure. It's optional content, basically.
Chris: Optional content. Okay. So, Marcus here is back on Gulp. Here, it took some time to get to my question, finally. [Laughter] "What would you say is the state of the art technique when it comes to asset bundling management, when it comes to WordPress and something that you're going to need multiple entry points and output files for?"
[Raspberry] Yeah, right. You're not going to get an answer to that, I don't think.
Dave: [Laughter] I think you have a good tool in Gulp. You have a good friend and you know it works. We had Gulpers on the show. It's not dead. It's not a dead project. It's still going. There's a community.
Dave: Yeah, Blaine. I just had his last name, and so I was just like, "Wait a minute. That's not his first name."
Dave: Yeah, so it's a thriving project, so I wouldn't even worry about it, but it does sort of have this -- when the Web has moved on to Webpack 9000 and you're like, "Dude, Gulp works for me," you feel antiquated or whatever, but that's not necessarily the case. If it's working for you and it's working real good, then use it.
Dave: That's awesome.
Chris: I use Gulp on my WordPress projects, for the most part. Do we have a Gulp thing on ShopTalk? Yeah, I think we do.
Dave: Then what is Gatsby? It's just a really fancy Webpack config.
Dave: You know? I don't think that's said enough. You know what I mean? Maybe you have a whole startup there - $16 million in funding. Yeah, I think it's fine. If you want new-new hotness, develop it. Jason Miller--
Chris: No. Does Jason Miller have a new, fancy bundler?
Dave: It's called WMR, which I think Warm Module Reloading portmanteau there, but it's popular in the Twitters. Literally, this week, I got DMs about it. They'll probably be talking about it at Chrome Summit too. I think it's kind of more optimized for the React workflow.
Dave: It's kind of this single entry point sort of thing. Again, it kind of maybe doesn't work. That's like the new hotness, but--
Chris: Well, he needs something to process Sass and stuff, right? I don't know that this -- is that thing going to do that or does it run tasks?
Dave: It sort of. It is an ESM build server locally. It's kind of more for like all in JS things, in my opinion.
Dave: It has a server and I think it's called the ES6 server. Let me make sure. Or ESM server. I'm very close but I'm not exact.
Chris: So, it'll spin up a local host thing for you?
Dave: But it will also -- it also has a build feature, so you can run it through a build. Then it'll do the proper bundling with all the sharding and stuff like that.
Chris: I think of Snowpack here, too, whereas Snowpack will do your Sass and stuff too, but is mostly for NPM, you know, like pull some crap off NPM. Then what it did was, it was like, I'm not going to--
I wish I could talk about it more intelligent. We've got to get Frank on the show or whatever, somebody from that team to talk about it. It doesn't recompile it over and over and over. It just does it once and then it's ready to go, so it's warm. It reminds me of the stuff that you're talking about with Jason Miller's thing.
Dave: Yeah. Yeah. It can do that, but it's always like, "Use our server and we'll solve the problem." It's like, "Well, I'm on Mamp with WordPress. What do I do there? I just run a Web server? Then you recompile my WordPress theme, my PHP includes, and ... scripts?"
Chris: Everybody wants to be your server, don't they?
Dave: Everyone wants to be my server and I have one. It's called Lamp. [Laughter] I love Lamp.
Dave: What if I have build tools and servers?
Chris: Even with Gulp, I usually have it spin up a browser-sync or something so that there is some kind of server there. That way I can tie the tasks together like, "If Sass gets processed, then do hot reloading," because I kind of like having those two pieces of code sitting next to each other.
Chris: They don't always have to be, though. I noticed in Local by Flywheel, which is another way to spin up a WordPress site. Of course, it wants to be your server, too. In fact, it kind of has to be because they're these little docker container things, right?
Chris: Then if you want to use this Gulp setup, too, in your browser sync, you're telling these two servers to talk to each other. Browsers think you have to put a line of code in there. It's like, well, actually, then proxy it to this other server location.
You kind of have two local hosts that are up. You have local that's running at port 3000 or something and then some other browser-sync thing that's running at port 12000 or something. It's just the nature of the beast.
Chris: Oftentimes, you have to have these servers kind of proxy to each other because they all have different jobs.
Chris: Now, here's another way to throw at this for you, just because we're talking about all these things. Remember CodeKit? Not like it doesn't exist anymore. I'm just being like, we don't talk about it that much. It's a Mac app. We didn't use it, like Dave and I on ShopTalk--we used to--because Dave went Windows. We'll talk about that in a minute.
Then if you have a new folder that happens to be an ACF block or whatever, it'll just know what to do. It'll just be like, "Oh, I see a new .scss file there. I'm just going to process it for you."
I don't think that's to be discounted. I think that might work really nice, especially if you're A) alone or B) on a team where you know you can buy CodeKit for everybody and you kind of control their working environment a little bit. It does assume CodeKit, though. It's like one person can use Gulp and the other person can use CodeKit. It is kind of an all-in thing in that way. But it does say in sync between people, which I think is cool.
Dave: Yeah. If you needed the deployment server to compile a Sass because you get into Sass collisions or whatever.
Dave: That's a thing.
Chris: And it runs a server, so you could potentially have three servers running. It's just silly.
Dave: Yeah. Well, yeah. I'm all for invention in there are cool, module-based JS packers and servers kind of coming out, which is cool. Veet from Evan You on the Vue team is pretty cool. I've experimented with that. It's basically that ESM server for Vue and then you can put React in it and there's hot module reloading and all the fancy features people want.
Chris: The next-gen of this is cool. I don't want to crap on Webpack because I think it was a big deal and I think tons of projects use it. Literally, we use it at CodePen and it works for us. It's not like this evil thing in the world, but I feel like the next-gen is not Webpack. I've just fought with it way too many times in my life and been really bummed out about not being able to do the work that I wanted to do because of Webpack that I'm starting to be, like, not hot on it. I don't like it.
Chris: Every time I play with a next-gen thing I'm like, this is fast, smooth, easy, understandable, and I like it.
Dave: Yeah. I read somewhere. It was some blog post. I wish I could quote it. I was trying to do a quick search through my Twitters.
Somebody was saying the next generation of tools, wouldn't it be cool if they had a broader audience than developers. Right? Right now, all the tools are like, "Command line this and blah-blah-blah and do this." You know? What if the next set of tools had other personas involved like the content author or the whatever? The person who just has to click a button once a week to update--whatever--the stat chart on the website or something. You know? What is that generation of tools and can we get there? Is that possible? I don't know. Can we have GUIs for tools to make it easier to deal with?
The problem with Webpack, it's a workhorse. It works really good but then you open up the thing and you're like, Good lord! What's happening?" [Laughter] There are all these transforms and doodads and things I don't get. The mental overhead of opening a complex Webpack config is tough, so how do we ease that?
Chris: Even when you're super fresh and you look at it and you're like, I'm ready to deal with this today. I can figure this out. Like, oh, I see it looks for these type of files. I don't know.
You look at the config when you're in the mood to do it and it's not incomprehensible. It's kind of fine.
Dave: [Laughter] Yeah. Yeah, yeah.
Dave: Yeah, and no one knows where that is.
Chris: Yeah. That's not a file path. It doesn't end in JS. What am I even looking for here?
What I struggled with recently was you can't get Webpack to just leave those ES module imports alone.
Dave: [Laughter] Whatever. Ugh.
Chris: I get why people don't want to write ./nodemodules and then deep link into a folder or something. I don't know. Maybe we do want to, though, because at least it's reality. I don't know.
Dave: Yeah, I wondered. There's just a smidge of magic that I don't think people understand or even realize magic is happening. You know?
Dave: You just input foo from bar or foo from foo, that's node magic or something. NodeJS is literally the required magic. I don't know. It's interesting, right?
Dave: Yeah. Have you ever been where you're like, import foo from whatever, and then it's just like, "Dude, I don't know. I can't do it"? You're just like, require foo? Like const foo equals require foo?
Chris: It's like, oh, okay, that's fine.
Dave: It's like, yeah, dude. That's great.
Chris: Yeah. [Laughter]
Dave: I get that. [Laughter] You're just like, "I'm sorry? What did we do wrong?" I'm sure there's some kind of logical, like some export was configured or something like that.
Chris: Yeah, right, some other project that uses Webpack put CommonJS instead of VSM. Marcus, good luck. Try Gulp, I guess, or keep on Gulp. Look at Webpack.
Dave: Stick with Gulp. I don't think there's a multi-entry endpoint thing that's better or even on the horizon. You know what I mean? I can't think of--
Chris: Not really, but I think my CodePen point has merit only because now, you make a new block, you have to remember to go into your Gulp file and teach it where that new thing is. Maybe. There may be a way you could write a file glob thing that watches broadly enough to catch those new files, too. You probably can. But it sounds like that was your pain point before was, "Oh, now I make a new SCSS file. Now I have to teach my Gulp how I want that process, too." I could see that being annoying enough that you want off.
Chris: But maybe just look at configuring it in a more broad way and maybe it will be your friend.
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by AWS Amplify. Amplify had a huge release at the beginning of December this year. It's called their Admin UI.
Amplify is already this kind of like JAMstack-based thing, right? They're static hosting, and so it's the same thing that we expect that you push to master and your static site goes live and stuff. But AWS Amplify, it's been a CLI or it has a CLI (and it, of course, always will) that helps you scaffold out stuff for your site like, "Okay, I'm building a site. I need some storage for it." Well, AWS has great storage stuff.
"Uh, I'm going to need to upload user avatars." Okay. I'm going to put those in an S3 bucket. How do I wire up an S3 bucket again? No problem. AWS Amplify (through the CLI) will walk you through that and get it all wired up.
You're like, "Well, this is a user login thing. I need Auth. How do I get that all wired up?" AWS Amplify (through the CLI) walks you through it. You get it all scaffolded out and set up in your app.
Then you're like, "I need a GraphQL API, data storage. Not file storage, data storage; how do I do that?" Amplify gets you going there.
It doesn't care what you build. You could be building a Vue app or a Next app or a Flutter app or whatever. It doesn't care about that. It'll help you with the infrastructural bits. Where do I store data? Where do I store files? How do I do Auth and all the other stuff AWS can do?
Obviously, AWS powers a lot of the Internet - a really robust set of solutions over there. But for the good developer experience, you use Amplify to help you with that stuff.
Now, I haven't even mentioned the Admin UI yet. The Admin UI is literally a UI. Imagine you're working on your site locally, but you could just go to a route on your own local site like /admin or whatever you set it up to be. It's not just a CLI helping you navigate your site. Now it's a webpage. It's like your secret backend of your site with a UI.
It helps you do all this stuff, like, what's happening with my Auth? Not only how do I get set up with Auth, but who are the users of my app? Now you have a UI for the users of your app. All that Auth stuff is in a UI that you have access to. It works locally and, of course, in production.
It helps you scaffold out the data, so now you're not on your own writing GraphQL schema - makes me nervous. You use a UI to build how you want the GraphQL to be structured and then it scaffolds that out in your code. So cool. I just think this Admin UI is just a super great idea for this kind of thing. It's really kind of the first of its kind, I think, so check it out.
Thanks for the support, AWS Amplify.
[Banjo music ends]
Dave: All right, Joey M-H writes in, "Support for CSS Grid is pretty great now and our agency is using it in production. Our designers love it because it translates one to one to their designs. My question is, should we use Grid for every component we're building? Is it worth placing a full-width headline on a grid even though our regular centered text element does the job or text block regular centered block element does the job? On the other hand, having everything on the same grid is great for consistency and, on the other hand, it can create extra complexity, grid blowout, et cetera. Defining all the grid placements and stuff, so what are your thoughts? Grid always or Grid on occasion?"
Chris: I mean that just seems weird to me. Should you dogmatically make sure that you're in absolutely 100% of all elements on your entire page are participating on the same grid? No, that's way too far. That's not how anybody wants you to do that. It was never suggested by anyone.
[Winning sound - ta da]
Dave: Yeah, and I think if you're hard coding, again, that should be the tell, right? I even don't use Grid template areas that often because I feel like, oh, this is starting to get hard code-y.
Dave: That's sort of like where you describe with words the layout of the site and you can do columns and rows. It's awesome but I get a little "ooh-ooh--I'm not sure" because that's very -- you start getting hardcoded and then, if somebody comes in as, like, "I need a whole new thing," you're like, "Oh, no!" That doesn't just plop in there.
Chris: It funny to me, though, because it's an abstraction layer between so, in some ways, it's the opposite of hard coding. You can say, like, "I want it to be in the footer location," and then you can update the middleman there and say, "Well, the footer location has now changed. It's now from column two to four instead of three to six."
Dave: Well, and I guess the fallback is it's just a block. It's just 100% wide thing if it's not specified, right?
Chris: Oh, that's true, or it gets auto-placed if it's on a grid.
Dave: What we've been doing at Paravel is we usually have a major layout on the whatever sidebar columns or something like that. We have a major layout and then, at the component level, when something is complex, we just find a grid there. That could get tricky. We'd need Subgrid if that grid has to match the parent grid but, usually, it kind of doesn't. Usually, it's like, "I want three things here or two things here." That's kind of what we've been doing.
I recently started doing containers with Grid, like where you do one FR, one FR, and then max-content in the middle. Sorry, one FR max-content, one FR - I think is what it is. You can do min/max one FR. I'm trying to think. Like 60 min/max at like 30 REMS and 60 REMS or something just to give it a min and max-width.
Dave: So that it behaves. Again, I could describe it a lot better. I think I have a CodePen I can link up here, but I started doing that because, every once in a while, you do a container and then somebody is like, "I want that to go full screen." You're like, "Ah!" Or somebody is like, "Oh, I want that to go hug the right side or hug the left side."
Chris: Oh, I like this. It looks largely like a centered column, but really the whole screen is a grid so that, in case you need to use that space, it's available to you without doing something super weird like negative margins or whatever.
Dave: Yeah. Yeah.
Dave: So, let me see if I can find my hug start.
Chris: There was an Ethan article about this, too. Why do a centered column with just auto-margins when you can kind of make a three-column grid and just use the middle column of it? That way those other grids are -- I don't know if he said this exactly, but that was the implication is that it's kind of like usable space.
Dave: Mm-hmm. Mm-hmm.
Dave: Yeah, I mean it's space you could occupy and you could actually go. I have it on just three, but I could see five, so you have slightly larger elements and slightly smaller elements.
Dave: Maybe they behave differently on mobile, like the slightly larger ones go full width on mobile and the slightly smaller ones don't.
Chris: Sure. This gives you space for, like, what if I need a little ad over there or a call-out or, more likely, what if I just don't want it to be centered.
Chris: Well, then just adjust that left or right column.
Chris: There is no magic here. It's like you told it how big to be. That's pretty cool. That's the opposite of what I just said. You're like, make more stuff for Grid than you might normally think of to make a grid. I was kind of like, well, don't use too much Grid. Don't use Grid if you don't need it. You know?
Dave: This took me a while to get into because I just was kind of like, you know, container. Simply, it's just max width 60 CH and margin auto. You know? Don't overthink it - container. I totally agree.
But then the second somebody is like, "I want to do something weird," you're like, "Darn it! I was not wanting weird."
Chris: Mm-hmm. [Laughter]
Dave: I just was like, maybe Grid is a little bit more expressive for that, and so this is kind of our main container.
Chris: Yeah, so you're doing that thing. This is the thing that's not ... weird. It's not like an anti-it. It's just like, it just gives me some kind of weird vibrations. You have this container and it's got your three columns in it. You're saying maybe it could be five columns, whatever, but yours has three columns in it. Then you have to say just whatever is inside that container, so just star, like direct descendent star selector. Please put that in the middle column.
Chris: I've seen people do this with just paragraph tags, image tags, block quotes. It'll just select anything and just slap it into that middle column.
Chris: That's mind-screwy to me to just be like, Ooh, really?"
Chris: "You don't have a wrapper container on it? Really?" Look, there's little stuff like now they're Grid items and not block elements. They behave a little differently, so you don't get margin collapsing, so you've got to make sure your brain is ready to deal with that. Maybe that's better for your brain because margin collapsing is weird and complicated, but it is different behavior.
Dave: Mm-hmm. Yeah, no, I wish there was Grid flow start or Grid columns flow start or something on the parent.
Chris: Yeah, like, "See all this stuff? Chuck it in the middle column." [Laughter]
Dave: Like, this is where I want stuff to go by default, but the star works.
Chris: Unless I specifically say, "Please put it over there in that other column." [Laughter]
Dave: Right. Right. Lord knows we don't need more grid systems, I feel like. I feel like Grid solved grid systems.
Dave: But you know I am into finding a language that expresses or how do I express my Grid or the design? This is just a start. I don't think it's perfect. I think it's just an attempt to start it, so we'll see. I'm kind of poking around.
Chris: Um, okay, so here's another one for us for Grid stuff, just because Joey specifically asked. He's like, "Let's say you've got an H1 sitting there or whatever. It's just fill width. It's display block. It's just sitting there. Should it be on a grid though, too, just because it should or something?" That's where I'm like, I don't know. Is it just hanging out there doing what it should? I wouldn't force it onto that grid just because you think you should. Sure. Right?
Then I think that this topic of Subgrid factors in here because if you came to the other conclusion on your design team and said that "Everything should be on a grid just so we have lots of control, it matches the designs, and there's a good mental model for us - whatever," that the danger then is that you have to flatten everything. That you can't have this semantic structure where you nest things like how you think they should be nested because if they need to participate on the same grid, they can't be nested. They have to all be at the same level to participate on the grid.
That's complicated by the fact that we have stuff like display contents now, which just removes a div. It looks like it's not nested anymore, which complicates things a little bit. But more realistically, we have Subgrid, which allows sub-elements. It's kind of like they're participating on the same grid but not really. It's just that they say, "Please inherit your lines from the parent." If there happens to be a row or column that happens to intersect through that element, you can be like, "I want access to that. I want to be able to line things up based on the parent's gridlines, not my own," which is kind of cool.
Now that Subgrid exists, I think maybe -- I don't think it's used enough yet and it's not used enough because I don't even think it's in Chrome. These days (like it or not), if it's not in Chrome -- Chrome has such dominant share being that it's also IE and also Opera and all that. Come on.
Dave: Mm-hmm. Yeah.
Chris: That's big. You kind of have to support it. But once Subgrid drops there, I think we're going to see a lot more usage of it. It's just a big deal that you can get things participating on parent grid lines. You're going to see grids starting to penetrate down into semantic layouts a lot more, I absolutely promise. [Laughter]
Dave: Yeah. No. Yeah, it doesn't look like it's there yet or not in the next versions either, but yeah. I think, yeah, then it becomes super useful because, when you have grids but you have two grids or children next to each other that have to look the same, that's where it really matters.
Chris: I can't even say I have it fully penetrated my mind yet, but there are definitely moments where I'm just like, "Oh, I wish I could do this," and then you're like, "Oh, you can with Subgrid? Oh, my. Thank the Lord! Oh, I love this feature!"
Dave: [Speaking in a Foghorn Leghorn voice] Oh, an expressive grid system without the overhead of rambunctious class names. I do declare, that is quite appetizing to my sensibilities.
Chris: I am pleased with the outcome that this produces.
Dave: I'm pleased as peaches with that sentiment. [Laughter] Oh, boy. Hey!
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by Netlify. High five, Netlify. Thanks for the support.
You know Cassidy Williams works over there now and has been on a tear this December blogging all kinds of stuff you should know about NextJS and Netlify. Other stuff too, but she just is a big NextJS fan, I think, and is showing off how well it works on Netlify.
For one thing, you can one-click install it. They have a fancy plugin for that. You just go whoop and it has a repo and is ready for you to work as a developer on, and then you know how easy it is to deploy on Netlify. You just push to master or main and there it goes.
I think Next is compelling for a whole bunch of reasons. One of the things is, I was looking at hot module reloading for React as kind of okay but never really worked super-duper well. Then there are some next-generation React fast refresh or something they call it these days. It's just built right into Next. That's highly appealing to me to know that I'm starting with a framework that has that going on.
Now, one of the reasons you might reach for Next is that it has that client-side rendered thing going on if you want to use it for that. It has that going on, client-side rendering, of course. But it has server-side rendering, too. If you want server-side rendering, that means you need to have a Node server behind it, which you can do on Netlify by virtue of Lambdas that can run the Node code to do that. That's pretty rad.
Then Next does pre-building files too, so like no wonder it works on Netlify, right? JAMstack for days. Next can do all three of the things of rendering websites: client-side rendering, server-side rendering with a server behind it, and the pre-building, you know, pre-generating files too. Very clever technology in that way.
When I think of using it on a site like CodePen, I'm like, "Uh, we'd probably make use of all three of those, in a way," you know? Client-side render stuff so it feels fast and you're bouncing around the site really quick, but so many of the pages need SSR, too, and probably can't be pre-built because there are too many of them. But then some pages could be pre-built like landing pages and stuff.
I just think that it's interesting to think of all those rendering methods that are really relevant for all websites. NextJS kind of handles all in one framework. Pretty cool.
Thanks for the support, Netlify.
[Banjo music stops]
Chris: What'd you buy recently, Dave? Have you forsaken your past?
Dave: Well, I've got some special news. If you've been following the Dave Goes Windows saga, I have purchased a brand new MacBook Pro.
Dave: Ta-da -- sound.
["Guess Who's Back," by Eminem]
Guess who's back-back-back, back again.
Chris: What's the plan? You're using your Windows computer now. Are you planning to abort ship and come back or are you just going to have two computers around?
Dave: I think I'll have a gaming computer and a Mac work computer.
Dave: I know, like in the last episode, we literally just talked about computer stuff and stuff like that, but I've been fighting. For two months, I didn't have an email client and a calendar. As a businessman, I kind of need that stuff. It was just a little ridiculous.
Chris: Oh, it wasn't a development problem. It was an email problem?
Dave: Well, that was a software problem. That is fixed as of yesterday. Well, the day we were recording this. It's like, "Okay, cool. I didn't know that was coming, but great I had a crappy two months and no one said sorry about it, but whatever." They broke Gmail inside the mail app, but whatever. That was frustrating.
The other day, I got a popup for, like, "Hey, man. You're liking OneDrive? How about you rate OneDrive?" I just was like, you know, I don't want to do this, Windows. I'm very upset at the mail app. Could you just fix that instead of giving me a survey?
Then the kind of critical thing was this week, literally this week, I was like, "I want to do some open source. I want to work on this little Web component thing." I pulled it down and I was like, "I'm going to be a good citizen. It has tests. I'm going to do the test-driven development, Chris."
Dave: I'm going to be test man, test boy.
Chris: Heck yeah. I'm all about it.
Dave: Of course, I just start writing a test. I'm like, write the test, do-do-do. NPM install. Okay, that sounds all good. Then I run the test and it's like, can't connect to Puppeteer.
Puppeteer is basically a driver for Chrome. It controls Chrome like a puppeteer.
Dave: I'm like three dependencies deep. It's Web test runner and @web/testrunner @web/testrunnerchrome and then Puppeteer. I'm three and it's actually Puppeteer Core. That'll come into play later. [Laughter]
Puppeteer Core is Puppeteer without the actual Chrome install or without its own Chrome install. It uses -- it stuffs a version of Chrome inside your Node modules. Puppeteer Core is like, "I'll just assume you have Chrome on your system," is sort of how Puppeteer Core works.
Chris: Okay, so it would work locally but less well in a Lambda or something.
Dave: Yeah. Yeah.
Dave: For tests, that's probably fine, I guess. Okay, so it just doesn't work. And so, I'm like, "Dude, I swear I've had Puppeteer working on my system before. I've used it. I've played with it."
Chris: It's an error, "Please use Playwright."
Dave: Yeah, basically, right? But because it's three dependencies deep, I can't really just be like, "Oh, hello, chaps. We're going to use a totally different thing now." You know? Like, "Take that, Google," who maintains @web or whatever.
I can't. That's not even in the cards for this open-source project, so I'm just like, "Well, I can't even contribute to this. I spend two days, three days trying to get Puppeteer running on my local machine. I can on WSL for Windows and I can actually install a local Chromium and I can run that in headless mode, but this uses head mode, which spawns a browser.
I was like, well, maybe I can spawn the Windows Chrome and they can communicate. I get it to spawn the Windows Chrome. It spawns the Windows Chrome but then there's a WebSocket error. It can't communicate with the Windows Chrome how it needs to. I even boiled all this down and I was just like, okay, we're going to do this just Hello World Puppeteer.
Dave: Get it to open a browser and close a browser.
Dave: The same thing - couldn't do it. But I was like, well, okay. I got it to at least talk to my Chrome one. Maybe I can do that with Puppeteer Core, but Puppeteer Core (just through whatever I guess sort bugs or whatever - I don't know) it basically is like, "I can't find Chrome. I can't find it."
I'm like, okay, well, maybe I can install Chrome. I try to install Chrome. I tried to install Chrome and then Ubuntu is like, "Dude, you don't have Snap," which is the new sort of way to install things on Ubuntu. It's not apt, it's Snap.
Chris: Homebrew for Ubuntu?
Dave: Homebrew for Ubuntu, so I'm like, "Okay, how do I install Snap?" Well, I have to replace the kernel in my entire Ubuntu, like replace the kernel, and I just was like, "I'm not doing that. I'm not going to void my warranty and nuke my whole entire dev environment just to get Snap running so I can install Chrome. It just was frustrating me.
Then even if I found another way to install Chrome straight from the Debian package manager or whatever, I install that, compile a whole version of Chrome, I have it, and then I try to pass it to Puppeteer Core. Puppeteer Core, you can't pass variables. You can't pass environment variables to it, so it just doesn't work, Chris.
I'm just frustrated and I'm like, "Is this better?"
Chris: I'm so sorry.
Dave: Well, that's it. It's like workarounds for workarounds. I'm talking to somebody at Microsoft and they're like, "Oh, you've got to install this VCX-serve thing," and that's like a Windows X server, like basically you can view your Ubuntu installation window, like the GUI of your Ubuntu using this thing. He was like, "Go download this from SourceForge." I'm just like, "I'm not going to download some app from SourceForge just to run a test. This is not what I want to do."
I just was like, "You know I've lost two days on this. I'm just going to buy a Mac," and so I bought a fricken' Macintosh just to unblock myself because not only does this open-source project I want to contribute to use Puppeteer, but I'm working on another little project with Paravel and we're probably going to leverage Puppeteer as well. It's like, man, what--?j
Chris: I can feel you. I can feel the emotion in your voice about this, kind of, just like, "I just need to unblock myself."
Dave: I'm tired.
Chris: Yeah. [Laughter]
Dave: I've got to unblock myself. I'm tired and I like Windows. I'm using it right this minute, but I really like it. I really enjoy it. It is on a great trajectory, but I'm just tired of workarounds for workarounds and I had to unblock myself. It could be ten months of the pandemic talking or whatever, but I'm just tired. You know? So, I'm just going to--
Chris: I would do it. You have way more tolerance than me. I have one little problem and I will just open my money and just start throwing money at things just because I'm just in a position in my life where I can't handle the stress. I have more important things to do, like I need whatever the solution is. If the solution is to buy my way out of it, I absolutely will. Not that I'm not capable of measuring that and figuring out the balance between things, but yeah.
Dave: Yeah. No, so I just was like, "I'll buy my way out of the problem," but then I'm hit with the place, right? It's like, okay, these new Macintosh just came out. The battery life is awesome. They last like 400 years. [Laughter] But it's on the ARM chip, which not everything kind of works on the ARM chip, so now what do I do?
Chris: Did you look up Puppeteer before you bought it? Does Puppeteer run on it okay?
Dave: I've got some bad news for you, Chris. [Laughter]
Chris: [Laughter] No, it doesn't.
Dave: It doesn't work, but--
Dave: --the workaround is you install everything through Rosetta, the X86 Intel side of things.
Dave: And so--
Chris: Doesn't that come on it automatically?
Dave: It's on there. Yeah, but you install Node through that. I'm working with my coworker Julien on this and he's like Dr. J., help me out. But I'm trying to -- you have to install Node on Intel, but that's obviously pretty -- it's a lot slower than Node on ARM because you have to go through the whole transpilation process, but it's fast enough. You know what I mean?
Chris: Oh, okay.
Dave: There's a translation processes.
Chris: Is that a temporary thing anyway? Everybody is stoked about these machines.
Dave: Well, that's what I was thinking, too. I bought the M1 just because, again, I think in trajectories a lot. I think I realized this as I was blogging my feelings, as I was installing all of God's Earth on this computer. But I think about trajectories and this is a big one for Apple. They're not messing around. The battery life is way too good for them to be like, "You know, we actually changed our mind. We're not going to do this." I think they're just like, "This is too good."
Chris: The reports on it are astounding. People are very -- there are no reports that are like, "This is bad." The only negativity I've heard at all is stuff like Docker. I literally just can't do it until Docker is ready to go.
Dave: No. That's a hard stop for people, and I think that's totally respectable.
Chris: Also, that they (on purpose) didn't release the 16. I don't want a 13. I want a 16. The reason they didn't is it's almost surely that the 16 is going to have some even more badass chip in it.
Dave: Totally. No, it'll probably be the 2 or the M1S or the M1X.
Dave: The M13.
Dave: They'll skip a generation.
Chris: Super down. Super down. I'm ready. As soon as a few more things drop, I'm on board.
Dave: My coworker Julien Jones, he was saying, "It feels like I paid $1,000 to be a beta tester." [Laughter] You know?
Dave: I was like, "Dang. That's cold," but that's kind of how it feels a little bit. Again, I'm maybe trading one set of workarounds for another set of workarounds, but I searched for Puppeteer M1 problems when I hit them and guess what. There are people working on it, they've already forked it, and there's already a workaround. It's not like I have to discover and brute force the workaround, and not large workarounds but temporary workarounds. You know what I mean?
Dave: Until this software all comes together, and so, again, I think it's probably on the order of months, not years, for some of these things to get solved. Docker is probably a ways out. Again, thinking in trajectories, I'd rather buy the device that's on a good trajectory kind of going forward. Whatever. I can do a hand-me-down situation if I need to.
Chris: Well, congratulations. We'll see how that -- we'll check in over time.
Chris: It didn't always use to be like this. I remember a day when it would be laughable to use a Mac because you're the one doing all the workarounds and crap and things just work on Windows. The times have just changed at least for development stuff. They are just developer machines now and they tend to work pretty well for that. I know I rarely have any trouble.
Dave: Yeah, and that's it. I'm paying a tax, the aluminum tax, you know, the Apple tax to basically skirt some problems.
Dave: It's cool. I do think there is--
Chris: You used them for a long time, too, so you get to just come home to something you've already done. You're not going to have to relearn where the system preferences are and stuff.
Dave: No, it's not hard. There are a few things I'm already like, "Ack!" but--
Chris: I want that blog post--
Dave: You want that blog post?
Chris: --because I've been using it for so long and I've never done it. The ones that, like, "I was gone for a while and came back. Here's what sucks about your platform that you don't even know." Yeah, do a mouth blog.
Dave: I've got a mouth blog for you. Number one, let me touch the screen. Touching the screen is awesome. I know designers are like, "Man, don't touch my screen," but touch the screen. Just let me swipe a webpage. Let me swipe an email off the screen. It's on Windows. It works on Windows. It's fricken' wonderful.
Dave: Just have it.
Dave: It is so dumb. They have the iPad. Just put the iPad on the thing. Anyway, I think it's just utterly ridiculous that they don't have that functionality. Anyway, you get really used to it. It's fine. It's dirty. But you know what? You get a microfiber and problem solved.
The OS, man, the look and feel of the OS, and coming from Windows--
Chris: Did you get Big Sur right away?
Dave: I got Big Sur right away, which is--
Chris: Oh, it's so good.
Dave: That's a lot of action. I affectionately call it the cartoon OS because everything is a primary color and very big, bold colors. Everything is a color, man.
Chris: Super border-radius. Border radius all day.
Dave: Oh, god. If I could pay [laughter] $100 to unlock a feature to remove the border-radius on apps--
Chris: Would you go all the way down to zero?
Dave: Maybe two pixels.
Chris: Two pixels, yeah.
Dave: But literally zero or two pixels because it is a joke. It's like every app is a little card. "Hey, look at this card. I made a card. Your app is a card. It's Slack but in a card." It's just ridiculous.
Dave: [Laughter] That would be the first change I would make - wholesale change. Yeah, the cartooniness, it's not for me. If you open up system preferences, none of those icons match. I know they redid all those icons and good job to everyone who worked on icons, but none of those icons match. It's a fricken' disaster zone. Windows's new settings is way better - even inside the thing.
Then they have all the icons. You open up finder and it's just icons. It's like Gmail. It's just icons that mean nothing, like icons with dropdowns. What do those mean? I don't know what those do. I've been gone for five years. Tell me what those do. [Laughter]
Chris: Those are a little worse in Big Sur. At the top of a finder window, it's a little messy.
Dave: I have literally no clue what that stuff does. [Laughter]
Dave: It's just like -- I don't know.
Chris: Some of them are just grayed out and don't work. Yeah. Not my favorite.
Dave: Yeah, so that's a little bit frustrating. You know I do think there's going to be a time where you're kind of on this sort of dual system thing, which again that's sort of what Windows is doing is a dual system, a Linux thing, and so that could be kind of frustrating in the long-run.
But you know there are also some nice things. My wife is on Mac and iPhone and stuff like that, and I opened up Calendar. It's like we're already connected through iCloud or whatever. We already have a family calendar. I was just like, "Oh, honey, we can just use the family calendar. You don't have to even tell me when tennis is or whatever. I'll just know. That's great."
Chris: Oh, my god.
Dave: We don't have to talk anymore, honey. This is wonderful.
Chris: Being on the same system is so great like that. My wife went Android, so we don't, but I use Google Calendar, so that stuff is okay. But we do miss out on some stuff sometimes. I have to use Google Photos to get our photos synced. Whatever. It would be easier if we just were on--
Dave: Yeah. Yeah.
Chris: I even went back to Apple Music instead of Spotify because it just tends to work a little better on my Apple stuff. I got a Home Pod at the office now that doesn't work super well with Spotify, in my experience.
Chris: The more I just dive into the aluminum paradise, Dave, I don't mind it.
Dave: Heading down. You're down the aluminum money train, dude.
Dave: But no, I think that is a thing. I have AirPods because I have an iPhone and I listen to 4,000 audiobooks a year or whatever. [Laughter] It's nice that the AirPods work with the Mac, right?
Dave: What I miss is -- already -- I'm six hours into this experience--
Dave: What I miss is my Surface earbuds, which pair to my Windows computer just great over Bluetooth and they last all day, not like the AirPods, which last like 1.5 hours and unpair every time you talk to somebody. Anyway, the pairing -- I don't know.
I think there's -- I said this, I think, in my Windows journey. Apple used to be the pinnacle of hardware, software, and design. I don't know that they are the pinnacle of all those things right now. I think, though, the hardware story is maybe the most interesting story right now. They've always usually lagged from--whatever--X9000 Intel or whatever. The hardware story is very compelling with these new chips because, man, I was six hours straight on the computer just getting it tuned up, set up, and stuff like that. I lost 30% of my battery.
Dave: Can you believe that?
Chris: That's sweet. Yeah.
Dave: That's hardcore.
Chris: Plus, when we're starting to leave the house again, that'll be really useful.
Dave: Well, my friend Yuanling, he was saying, "Imagine going to a conference and you don't have to plug in." [Laughter]
Dave: That's kind of revolutionary, right? Have you ever been to a conference where it's like, "Where's the charger?" "It's onstage." "Okay. Cool. I guess I'll go sit there or leave my laptop on the stage to charge." You know? Imagine conferences where you don't have to charge. That's kind of cool.
Chris: Yeah. Battery life unlocks all kinds of doors. As Tesla well knows, it's a big frontier for cars and devices of all kinds and everything.
Chris: Definitely, it doesn't take much of a science fiction mind to anticipate the day where computers are so fast that you're not just waiting for little crap all the time. Everything you do just happens immediately and you don't have to worry about power. There are no wires or cords anywhere. Things last for incredibly long periods of time. That's the most obvious science fiction thing going forward.
Dave: Mm-hmm. Well, and that's what it seems like Apple has almost achieved is this near -- they've increased the battery and the performance (according to their metrics or whatever), battery and performance, and it appears to be holding up. That's cool. That's a big technology leap. That's what even all my Windows hardware reviewers are like, "This is a big leap," so that sort of inspired me or gave me confidence, I guess, to just bite into the M1 even if it's not perfect. Anyway, I bought a new computer. It doesn't actually solve all my problems, but here we go. Let's go.
Chris: Yeah. I would have hoped that Puppeteer would have just ran just fine on Node and all that.
Dave: I was so hoping for that story.
Dave: Bing-bong-boom, and then I got the same error and I was like, "Gol-dang." [Laughter]
Dave: But I knew -- it's clearly -- because it's looking for the Unix version of Chromium, so it's clearly an if statement gone awry. It's just very clearly trying to find -- it's looking for the wrong thing, so anyway.
Chris: Let's do this last one, because it's related to this, from Felicia Betancourt. "Hi. I'm a full-stack developer who is about to delve into e-commerce for the first time. My client has a WordPress site so, naturally, we're using WooCommerce. However, I believe that my question is relevant to any e-commerce platform. What strategy do you recommend for testing? I am practically sweating bullets just thinking about all the things that could go catastrophically wrong every time I update a plugin or whatever. I need to know that the store is working, but how best to do this? The more automatic process the better."
Well, we've spent a lot of this show talking about Puppeteer. That's where my mind goes immediately. This is integration test material here.
You could write one. You could write one that goes to your store. It puts something in a cart. It moves to the checkout process. It puts fake details into the checkout process and just clicking those buttons, the right things happen. That's going to go so far - one Puppeteer test. Puppeteer Jest, probably, because you'd have expectations.
Dave: Yeah. No, I mean because the syntax is wild. It's like const page equals new page. [Laughter] Then you give it a URL or whatever. It's like page go to some URL.
Dave: Then it's like page.click jQuery selector button. Then it's like page.fill form.
Dave: The API is so, just -- and that's sort of the stuff we're using it for is just like, can we automate--?
Chris: Look at Cyprus. Cyprus is even cleaner.
Dave: Yeah, and Cyprus has a GUI to program the Puppeteer or whatever. Just try that.
Chris: Yeah. You don't have to write -- it's kind of a little thing, but it's all Async 08 based Puppeteer, which is fine.
Chris: You need to write things sequentially, so cool. But the Cyprus syntax, you don't have to do that. You just type it out and it just is synchronous anyway.
Dave: I think with Cyprus, I just talked to them recently. They're doing cool stuff, but Cyprus, you can download their app and not even you--somebody at the office--can just click through the website and say, "Do this." It'll record those actions and now you have a test for the rest of your life and you didn't even have to do anything.
Chris: That's the absolute number one dream. Selenium had little crap like that back in the day, but I think modernized and having it actually work and having it then express itself in code that somebody can debug that way if they need to, it's all a big deal.
Chris: Puppeteer is just a little closer to the metal in case you needed to do some special stuff, but I don't know. Cyprus is probably what to look at first and you should only ever leave Cyprus if you absolutely have to because it's definitely the cleanest integration test, I think.
Dave: Yeah. The thing I'm working on is like a Crud thing, but I need to know: Can you create a thing with data? Can you see the thing? And then can you delete the thing or can you edit the thing and then can you delete the thing?
If I have that test set up for every line of code I write, man, I'm cooking with grease, man. That's great. I know I didn't break anything, and so that's cool.
Chris: Yeah. I'm going to go one little step further for you, Felicia. (You put the pronunciation there and I still screwed it up.)
Okay, so it's a WordPress site, which is like BYO deployment. How are you going to deploy this thing? I don't know. There are a million ways to do it. Almost, it has to be done -- almost certainly at some point some kind of thing needs to FTP up your files because that's just how PHP of that world works, for the most part.
Chris: You have some hosting somewhere and you have those credentials, but maybe you abstract that in some way. I used Buddy (buddy.works) for a lot of this stuff. You give it the credentials. You hook it up to a Git repo, and then it becomes a little bit more like Netlify or whatever. You just push files to the Git repo and they automatically get pushed live, ultimately through FTP, but you're not manually FTP-ing anything - or something.
But you could write that same thing any number of different ways. You could write it into a GitHub action. You know the deployment is kind of configured through that - however you configure. Imagine it's something like Buddy or like DeployBot or Beanstalk. There are all kinds of these tools that do that.
What you'd probably do is say, "When I have a pull request against master, it automatically pushes to staging." You're going to have to have some host that supports staging. A lot do. I use Flywheel. They have staging.
Chris: The idea is that your master branch is always staging. This is just one way to do it. There are other ways you could do it. Master could also be deployed if you want. You could have a staging branch and it could be required.
A possibility is that master only takes PRs from staging and no other branches. It's like a protected branch. That could be a way to do it.
Dave: Yeah, you can set that up. Yep.
Chris: But I'd maybe just have a staging branch or master is staging and then you have production, which goes to production or something. Use some agreement with you and your team that these branches represent these things and then you set up your deployment that does that.
Let's say master is automatically staging. Any code that goes to master automatically goes to staging and there can be little actions that get triggered. Buddy can trigger the action. Any kind of CI thing can trigger the action. GitHub actions can trigger the action. That action says, "Run these tests. Run this Cyprus test." Run anything you want. "Run these unit tests. Run Prettier." Run whatever.
Chris: In your case, maybe Cyprus is the way to go because it's an easy integration test. You'll love it. I promise. Run the Cyprus test against the staging URL. Now it's automated. The second you push, every single time, people push ten times a day to staging, it'll run ten times a day. Totally automated and it's going to run Cyprus against that staging URL, so you're going to catch it.
If your test fails, you're going to know it before it goes to production. You can wire it up that says, "If the test passed, you can't go to production." You know? That's the kind of DevOps wiring up, and this stuff is like--
I don't mean to make it sound too easy. You're going to struggle with it and stuff. It's going to be weird. But that's why DevOps is a job these days because that's the kind of crap they work on.
Dave: No. I think, yeah, you have the right problem. You know your problem, and so yeah, I think just getting a staging server is a big thing, too. Even that might take your sweat level down just knowing, okay, I pushed it here and I did a little manual click-through. The Cyprus stuff is to eliminate the manual click-through. You've tried to figure out ways to eliminate that and I'm not even fully there yet, so I'm with you. Man, wouldn't it be great to just have a little insurance, just a little to take the sweat out, take the stress out, and it just happens? It just kind of happens without you even asking it to.
Chris: Heck, yeah.
Dave: I assume all these, like Buddy and stuff, they all have post-commit kind of hooks or whatever, right?
Chris: Oh, yeah.
Dave: A post-deploy webhook thing.
Chris: For sure. That's what they want you to use.
Chris: As a business, that's what they're trying to push you towards, not the most basic usage. It's because that's how they get their hooks in you because those are all buttons and stuff that you click to get ready. It's not configurable.
Dave: They literally sell hooks. [Laughter]
Dave: They literally sell hooks.
Chris: Yeah, but they make it easy for you, so it's kind of worth it. But it's not configurable. That's why there are always nerds being like, you know -- like we use Pulumi a lot. You've heard of Kubernetes, too. It's configuration for these things. It's like writing what you want to happen with your DevOps flow in code that you check into the repo and then, when you check-in, that's executed that says, "I want this staging environment. It's on this type of computer with these types of resources and scales like this and has these hooks."
That way it's not some buttons that one person pressed but then they quit because Netflix gave them more money than they got over at Yahoo or whatever. That person that clicked the buttons is gone. Now you don't have to click any buttons. It's code.
Chris: That's nice, but that's a level up. That's extra nerdy. The companies that provide the buttons, I'm all about it because I need buttons. [Laughter]
Dave: Well, and you can do it yourself but, for me, it's like, can I solve a problem with the button? If I can do that, that's great for right now. Then I can do the full nerd stuff later. Yeah, hopefully that helps.
Chris: Yeah, you definitely step up to the levels. Do the simplest thing first, like buy a Mac. [Laughter]
Dave: Like buy a Mac to write an open-source test. Why not?
Dave: It's only a few thousand-ish dollars, but the new Macs are cheap, too, I should say. They're a lot more affordable than Macintosh used to be.
Chris: Is that right? I didn't know that. Anyway--
Dave: It started at one, but it's compute -- more Mac talk. We're now an Apple podcast. Sorry, everybody.
Dave: But the eight gigabytes.
Dave: They offer RAM in 8 and 16. You're like, "No way eight works," right? Every computer I bought with eight, the sides of the computer fall off. It actually kind of works. It's just like how your iPad only has like four gigs. It's like eight is kind of enough.
Dave: Sixteen is like turbocharged. I only have eight and it seems to be working just fine. Maybe a stutter here and there.
Chris: That's cool. How responsible of you. I find it impossible not to just make all the selects go to the bottom.
Dave: Max out. It was more of a time thing. Yeah, no, I'm into the--
Chris: Well, they had one available. You could have it right then. Yeah.
Dave: Oh, yeah. We walked into BestBuy and got a computer, so that was easy.
Chris: Oh, BestBuy has got these things already? I assumed they'd get them later than the Apple stores.
Dave: Yeah, they usually do, but I think there are supplier agreements and all that. Anyway, this show has gone on. But anyway, I'm back on Windows -- sorry, Mac. If you have utility app suggestions, I will take them because that's sort of what I'm most excited about this whole switch.
Chris: Utility apps? Really? Oh, my god.
Dave: Good, third-party apps, that's what I'm interested in. Anyway--
Chris: You've got to get Setapp, like today then. I'm not a show for them, but I feel like Setapp has all the good stuff in it.
Dave: All my utilities for $5 a month? Okay, well, maybe.
Dave: All right. Okay. Cool. Cool.
Thank you, dear listener, for downloading this in your podcatcher of choice. Be sure to star, heart, favorite it up. That's how people find out about the show. Follow us on Twitter, @ShopTalkShow, for tons of tweets a month.
Head over to ShopTalkShow.com/jobs and get a brand new one because people want to hire people like you. Maybe like this company.
Chris, do you have anything else you'd like to say?