Transcript from the "Implementing Presets" Lesson
>> Sean Larkin: So the last thing that I think is gonna be really fun to talk about is,
>> Sean Larkin: Is going to be like, presets. And it's gonna kinda tie around why we would add a preset system, and it's kinda related to some experimentation that I'm doing in our source code right now to implement a feature that would look like this.
>> Sean Larkin: I do wanna pull this up. I wanna look at the repo I had open before.
>> Sean Larkin: I'm gonna jump to that branch I was in.
>> Sean Larkin: And so, if we are ready, so I wanna talk about this code really quick and just explain it.
>> Sean Larkin: And so, think of, when I started using Webpack, one of the things that frustrated me was that, I would add something to see if it would work, and then I'd either forget to remove it, or I'd irrevocably break things.
[00:01:21] I'd be like, what did I do? And I don't think that's really, that's not a great experience, it doesn't leave people feeling confident. And although we've solved a lot of that just by making defaults of the mode property, the idea of presets is that, there are gonna be more than just dev and prod.
[00:01:45] You're gonna have some different scenarios that might just be like, I wanna try this feature, or I wanna analyze my build just this one time, so it could be ad hoc or it could maybe be something your CI just runs. But you don't want it like shipped right in your prog, config, because it's not relevant every time you run it, right?
[00:02:06] Now, that's kind of where presets came from. Sometimes, I call them add-ons. You can call it whatever you want really. But if you look at this code here and this is what we'll be writing is, we're taking and we're defining a function that takes an env, takes the whole, I guess, env that we would get from the main config, now we're pulling out the presets option.
[00:02:31] Now, these little syntax here is just saying, it's just doing a flatten. So we might get one preset in an array or we might get an array of array presets, but it's just saying like, flatten these into a list of strings. And then, we're gonna map these into a require function that takes that preset name, just as we did the webpack.prod or webpack.dev, or development, and it's gonna call them.
[00:03:00] And so that way, we essentially have one or two or three, or if we have four strings in here, we're gonna get four objects that might be little configs, right? And then, what we do is, we just merge them up, and then we return. So why don't we implement this?
[00:03:18] And then, I'll show you kinda how it relates in our code itself. Always nice to have this one side by side, cuz sometimes I write it a little different every time. Or maybe, I should just publish it to a node module, right? That would be kind of useful.
[00:03:38] So what you can do, actually that's a great idea. Let's go into our load presets file, I had you create it early on. And let's go ahead and implement this code. So first thing is, we're gonna eventually need webpack-merge, so we'll require it.
>> Sean Larkin: Okay, and then,
>> Sean Larkin: I think, maybe, I'm just gonna see, I do wanna change it slightly.
[00:04:11] I'll say, applyPresets equals a function. I think that just looks nicer and I was just preaching you should have moduled out exports at the bottom. So, applyPresets. I don't know, I like that a little better.
>> Sean Larkin: And it's gonna take env.
>> Sean Larkin: Now, the reason why I think I said I want to pull the whole env in here, was because you wanna pass them down to these other configs in case you wanted to have individual behavior.
[00:04:47] Now remember, this is just convention, right? This is just convention that's gonna help you understand, hey, I can compose these things as many ways as I want to, and the options are almost limitless.
>> Sean Larkin: So presents equals env, so we're just doing a de-structure to grab that property, and then I'm gonna say, const mergedPresets =, so essentially just flattening them, I could say flattened the presets.
[00:05:19] So concat, I could pull down Andre Stalz's dot smoosh.
>> Sean Larkin: For any of those who are in Twitter actively and know about this smoosh gig.
>> Sean Larkin: And the, what we're gonna do is, this is just gonna be an array of strings, right? So we're gonna take and say, let's see, this is kinda fun.
[00:05:48] I'm just gonna, really quick, you don't have to do this.
>> Sean Larkin: But it helps with the IntelliSense.
>> Sean Larkin: There we go.
>> Sean Larkin: So I can say, mergedConfigs = merged Presets.map. See now, I get an array string, string and everything. So nice. And I'm gonna say, preset name, we're just gonna return a require,
>> Sean Larkin: And a template string inside of it.
>> Sean Larkin: That's just pulling the old presets/webpack., and then preset name.
>> Sean Larkin: And then, we wanna call it and pass the env in there.
>> Sean Larkin: Here we go. That looks nice and formatted. Okay, so now, we're just gonna return just a webpack-merged version of that.
[00:06:59] So return webpack-merged, and we start with an empty object, just as if you're doing object assign and just use the rest parameter to pipe them all in as individual parameters.
>> Sean Larkin: Does anybody have any question about what this code is doing?
>> Sean Larkin: Or need any clarification?
>> Sean Larkin: Do you think this will be useful if it was just a standalone module, and you could just add your own preset system?
[00:07:38] Maybe? Okay, we've been thinking about this a lot. So why don't we jump into our regular config, and so now, we just need to add a little bit of extra code here to implement the merge presets. So if we jumped in the root of the repo, just gonna verify, it's just adding it to the bottom, right?
[00:08:00] Yep, so what you can do is essentially add, we wanna import this module,
>> Sean Larkin: And I call it const presetConfig.
>> Sean Larkin: Build-utils, think that was right, right?
>> Sean Larkin: I'm so spoiled and I look for the IntelliSense there. Load,
>> Sean Larkin: Now, all we have to do is, we're gonna get presets passed to us from the env parameter, right?
[00:08:42] So we can now just go ahead and add it at the bottom. So we could say presetsConfig, and it look like the way that I passed it in just to make sure,
>> Sean Larkin: I'm keeping track of doing it consistently here. Where did I just have that?
>> Sean Larkin: Then close it.
>> Sean Larkin: Yeah, okay, so we did destructor code and presets back into it.
>> Sean Larkin: So in theory, what does this mean you can do now?
>> Sean Larkin: Now, we can actually take and create tiny configs, or smaller configs, that just have one-off features that we would wanna implement. So we could create a new preset, and it just has to follow the same naming pattern that we've been doing, so like webpack.typescript.
>> Sean Larkin: Typescript.config.
>> Sean Larkin: Or, I'm sorry, typescript.js. So now, on a whim, I can go ahead and say like, oops,
>> Sean Larkin: And I could add a single rule, like module, rules, in the same way that we would wanna support TypeScript, ts, use ts-loader,
>> Sean Larkin: Except making an object.
>> Sean Larkin: There we go.
[00:10:27] And, of course we would wanna add TypeScript. Like, yarn add ts-loader TypeScript, I just use that next.
>> Sean Larkin: But what's super cool now is that, I can add this capability just by adding a parameter, like a command line parameter, right? So we know that you can pass in other properties on this env.
[00:10:58] So let's say, if I wanted to say it like, I wanna run prod typescript, you know? So I would run, npm run prod, I get everything I get out of the box with prod, but now I'm gonna say, env.presets.
>> Sean Larkin: And then, typescript.
>> Sean Larkin: So if we were to try and run this,
>> Sean Larkin: npm run, yarn run prod typescript,
>> Sean Larkin: What did I miss?
>> Sean Larkin: Oops, I know. This file should be up a level, in build-utils.
>> Sean Larkin: And,
>> Sean Larkin: Cannot find module presets.webpack.undefined.
>> Speaker 2: Do you need the double dash in the scripts?
>> Sean Larkin: Double dash.
>> Speaker 2: The package.json scripts.
>> Sean Larkin: My gosh, yes, I absolutely do.
>> Sean Larkin: You saved me today, Kayla. Kayla's got me. So of course, we just added TypeScript support. But you're like, Sean, how do I really know there's typescript support? Like, let's write some typescript. Let's do it. Like this is the power of having an add-on is that, at any time, you can just pilot whatever you want.
[00:12:48] So like, I don't know, we could just say, I'm just going to do foo.ts in this case. So, I could say like, export. I'll do something really typescript-y. Export default class something, like foo. And then like, let's use some illegal syntax that wouldn't be correct. I could just say like, public readonly.
[00:13:36] So like, if I ran it again,
>> Sean Larkin: Import foo from, there we go. Now, I really feel, we have our case here.
>> Sean Larkin: We got an error, foo.ts. And we'll talk about this a little more, I just wanna focus on the preset itself and not like the typescript support.
[00:14:18] I know what's missing but, there we go, so there is an actual typescript error. Like, if they compile and run, it was like, hey dude, if you wanna use typescripts, you have to have a ts config, right? So we can go into the ad hoc typescript case itself, tomorrow, if that's something you think is valuable or supporting it, the main point here is that, we just like on the whim of a flag, just made it possible to add a preset.
[00:14:48] So one preset that I think is really valuable that you should all add, do we have any questions about the preset or the code that was written? Has anybody struggled with adding the support or, and we'll create one that you can actually use, I'm just gonna remove this typescript one and save the branch,
>> Sean Larkin: And delete the texture file, and that reference, there we go. Because, we'll spend some time on it.
>> Sean Larkin: Get checkout,
>> Sean Larkin: 4013-adding-presets.
>> Sean Larkin: 04013.
>> Sean Larkin: Awesome.