 All right, I think we can go ahead and get started. Thank you all for coming. This is Writing Modular JavaScript with Browserify. There we go. So my name's John Ferris. I'm the Director of Front-end Engineering at Atten Design Group. You can also find me as pixelwhip on Twitter or jubel.org. And I work for Atten Design Group. We're a strategy, design, and development agency based out of Denver, Colorado. We do a lot of work for organizations, cause-driven organizations around the world, such as Human Rights Watch, the Gubanker Institute. We do a lot of work with higher education, so Stanford, Berkeley. So yeah. Today we're gonna be talking about JavaScript and basically how to use JavaScript as modules. So breaking your scripts up into smaller files. One thing I wanna note at the beginning is modern websites are increasingly using more and more JavaScript. So since 2010, according to the HTTP Archive, the average website is using twice as many requests for JavaScript, and the actual files that it's downloading are three times what they used to be. So this is a graph from the HTTP Archive and you can see back in 2010, the average request for JavaScript files was 11, so they'd load 11 scripts onto the page. Now the average is 22 and used to be 113 kilobytes of JavaScript and now the average is over 300. So the usage of JavaScript has grown quite a bit in the last six years. And there's a few things we can take away from that, back around 2010, there was a huge shift, I think in the mindset of front end development, specifically JavaScript. So in 2009, it's when Node.js was first released. Shortly after early 2010, NPM was released and this is when we first started seeing an interest in using JavaScript outside of the browser, using it on the server side and using it for other applications like your build systems and whatnot. Also in 2010, Steve Jobs wrote his open letter on Adobe Flash basically saying, we're just not gonna support it on the iPhone, so this is three years after the initial iPhone came out, he said, we're not gonna do it. So up until then, a lot of websites in terms of their interactivity were focusing on Flash or that was kind of the main technology used. So once that was gone, the shift of interactivity moved kind of from ActionScript and more into JavaScript. That same year is when Ethan Marcotte published Responsive Web Design on a list of part and I realized that that wasn't, in his article, he doesn't actually specifically talk about JavaScript, it's mostly CSS and images. But the consequences of that article when developers started looking at and designers, like how are we gonna make this one site work across different devices, different sizes, different capabilities, like in reality, to make that work and make that work well, you do need to rely on some JavaScript. You can't get it all done in CSS. And towards the end of that year, so in October, Backbone.js was first released, exactly one week later, Angular.js was released and this is when we start seeing the architecture pattern of SPAs or single page apps. So at this point, we're moving a lot of some of that default native browser behavior that we rely on into JavaScript. So simple things like routing, moving from one page to another, that as in a single page app, that's all handled in JavaScript, not by the browser. So all these things are requiring more and more scripts. We could have that conversation on the effect on performance, obviously more page weight, more calculations on the device, it's not necessarily a great thing, but I think you have to weigh the growth in JavaScript with the actual capabilities and the things that we're relying on. Scripts are meant to be more, or sites are expected to be more app-like now that we have touch devices and phones and whatnot. So another way to kind of demonstrate the growth of JavaScript in the last six years is the growth of NPM. So if you're not familiar with NPM, it's a JavaScript package manager. It actually can do more than JavaScript, you can keep your CSS or publish your CSS to that. So this chart just shows, this is from moduleaccounts.com. They keep a running total in statistics on various package managers out there and how many package packages are published. So you can see RubyGems is kind of, it's just been in a straight growth path. Once they started collecting data on NPM, you can see that line, it just accelerates. And then there's also Bauer on there. Zidoo wouldn't use Bauer, you know, a few people. I think the trend now is people moving more and more towards NPM, just as kind of a central repository for these packages, but Bauer's still used quite a bit. As you can see, not nearly as much. And I think one thing that could be said about this is NPM, it's super easy to publish a module. I mean, you basically type NPM publish, your module goes up, and that line gets bigger. In contrast, it actually didn't include it on this graph, but moduleaccounts did actually just start using or counting Drupal modules on here. And it basically, it shows up here, it's just a little tick right here, but I think that goes to show the difference. I don't know, is anyone published a module to Drupal.org? Anyone here, a couple people? It's kind of a pain in the ass, right? At least for your first one, you have to, Drupal.org has a serious vetting program if you've never published a module before. So once you publish your first module, you're kind of green-lighted and you can publish whatever you want, but NPM's just free for all. But with that said, there's a lot of good tools on NPM, a lot of innovative tools that really, in the last few years, I think, made some positive changes on how we code. So what is an actual JavaScript module? JavaScript modules are basically small chunks of reusable code. There's also, and I don't wanna confuse the module design pattern here, module design patterns and actual pattern for how you write, sorry, a function or an object. What I'm talking about modules today, I'm talking about a single file that exports a value. So I wanna read this quote from an eloquent JavaScript. There are a number of reasons why authors divide their books into chapters and sections. These divisions make it easier for a reader to see how the book is built, sorry, built up and to find specific parts that they are interested in. They also help the author provide a clear focus for every section. The benefits of organizing a program into several files or modules are similar. So breaking your scripts out into small files, there's a lot of organization positives there, as well as findability and just structure-wise and re-usability for those modules. So some other reasons why we would wanna use a JavaScript module, one, we just talked about this, organizing code into smaller files, aka modules. Smaller files are easier to deal with. You're not dealing with thousands of lines of code and having to search through and grep through a code base to find things, as long as you're organizing your modules well. Actual module formats provide a way for exporting and importing values. They respect the global namespace. So one issue with loading a bunch of scripts on your page is that if you have dependencies between one external file and another, most likely the file that you're depending on is exposing a variable globally. For instance, jQuery, if you load jQuery on the page, it adds a variable to the global scope jQuery, and then you reference it with other scripts and whatnot. The problem with that is that you get into namespace collisions, if you get a bunch of modules, all gonna name the same thing, you could be overwriting your modules. Global variables don't get garbage collected, at least as easily as functionally-scoped variables. So that's another thing we wanna look out for. We wanna use modules so we don't pollute that global namespace with a bunch of variable names. And managing dependencies. Nice thing about modules, like I said, they provide a way to export a value. They also provide ways to import a value. So you have a dependency, you have one file depends on another, you can import that other file and use it. And we wanna be able to utilize existing packages. So this goes back to NPM. We wanna be able to say there's a library like load-ash or even jQuery. We wanna be able to just install that quickly, be able to use it and kind of move on with our lives. We're not worried about too much about downloading some file, unzipping it, putting it in the right folder and then referencing that. And one thing I just wanna reiterate, sorry. JavaScript modules export a value. So this value can be anything. It can be a string, it can be a number, it could be a function, it could be an object. There's no set distinction of what you have to export. So if you wanna export just an object full of configuration, you can do that. You wanna export a string that's like your template, you can do that. So when some of these goals were first kinda discussed and defined, two module formats sort of emerged. There was AMD and CommonJS. So AMD was kinda created more with the browser in mind. It was AMD stands for asynchronous module definition. It was a way to be able to import other scripts from within the browser at runtime. So basically the way it would work, it was asynchronous. So once a module loaded, you had a callback that would execute that function that required that module. CommonJS on the other hand is synchronous. This is what the node environment is based on and this is what we're gonna look at mostly today. And then kinda taking the best of those two worlds, there's actually a standard in extramus script. Now on ES6 or ES2015, that actually defines how modules should be imported and exported. And it kinda took the best of both worlds of AMD and CommonJS and brought that into a standard. We'll talk a little bit about how we could use that today. But for the most part, we're gonna focus on CommonJS. I would say if you're first getting started like modular JavaScript, I would definitely look at ES6 and start working with that syntax. It's gonna be the most future proof going forward. So let's look at the actual implementations here. So this is AMD, we have a module A and module B. Module A is our dependency where the syntax is basically you define some value. In this case, we're defining a function that's being exported. And so in module B, if we require module A, we basically get that function and then can use it. Once that function loads, the function within module B will execute. That's pretty much all I'm gonna say about AMD right now. CommonJS, if you've used Node for anything, this probably looks familiar. So you have module.exports equals some value. Put that in a file and then when you require that file in this case module B again, just say variable module A equals require this other file. So whatever module A is exporting, that's what module A will be set to in module B. And then we could do something pointless like alert whatever that function is. Yeah, that is actually super useless now that I look at it because it's actually not gonna do anything but print out the actual function. Real talk, I wrote this example super late last night. Very little sleep and some Irish coffee. So that's CommonJS. Any questions so far? Nope, cool. Taking these examples of what they look like in ES6. So again, we have a module A. One thing that ES6 allows you to do is export a number of different values. So in this case, we're exporting this constant square root, a function called square and a function called diagonal. And then in module B, we can actually import those individual modules out of that file. So this is nice where you don't have to import an entire file, you can just grab the pieces that you want out of it. So there's two different methods of doing that. Module B, we're actually calling or importing square and diagonal specifically. You can also, in module C, where we say import wildcard asterisks as module A from module A. And what that'll do is that'll import all of these exported values out of module A and tack them on as basically properties or methods of this module A object. So you kind of see the difference here if I can highlight it. In this case, we're importing these individual, sorry, this is an exercise in motor skills right here. So we're importing square and diagonal and we're calling those directly. In this case, we're importing all of them as module A. So we reference those by module A.square or module A.diag. Does that all make sense? Cool. So there's also an alternative that this is closer to something like a comma JS or AMD where you're exporting a single value. So here we're saying export default function square. So that default keyword is just saying this is the one thing in this file that I'm exporting. If you use this, you can only export one value. So in module B, you would say import square. Notice we don't have the curly braces around it. We're just importing that one value and then console log. So this is working just like comma JS or require or, sorry, AMD. So how do we actually use these? Right now, even though ES6 modules are standard, no browsers actually support any method for like exporting or loading them. I believe the latest version of Chrome has support for I think importing but not exporting. So in order to utilize this stuff, we need some sort of build step. Either some sort of build step or some environment that natively supports them. Browsers don't support them right now. No JS supports comma JS. If you're using require JS to actually import AMD modules, you can do it that way. But you need some sort of environment to actually use these modules. So what a bundler does, essentially it concatenates files. So taking a bunch of files and grouping them into one file. It manages dependencies. So if you have a file that depends on one file, depends on another file, it'll make sure that those are all loaded in the same order. If you ever end up, you know, you're working on a site and you get the error like jQuery undefined. That's probably because you loaded something out of order. But in this case, a bundler will kinda, it'll look at that dependency tree, which we'll look at here in a second and figure out the actual load order of things. And then it runs at compile time. So it's back to it needs a build step. Now this is opposed to like a module loader like require JS where a loader is loading your modules directly into the browser. So you don't necessarily need a compile step before you like deploy your code or use it. So this is kind of what a typical bundling process might look like. So you have an entry file and a bundle. So the entry file is the single file that's gonna import a bunch of other dependencies. The bundle is the actual output of that. So you can have multiple entry files. Each entry file is gonna produce its own bundle. And then you have what's called the dependency tree. So all these dependencies underneath, those are all getting imported and bundled into bundle.js. So what kind of bundlers are out there? There's kind of three, I would say two main ones and a third one kind of up and coming bundler, I guess. You have Webpack, which Webpack does, it does the bundling. It does like your development server. You can bundle and like your CSS. It kind of, it works, it does a lot more than just bundling JavaScript. Whereas these other two, Browserify and Rollup, they're kind of very specific modules. They do one thing, do it well. Browserify works by default off common JS modules. And we'll look at how you can use the ESX modules in there as well. Rollup.js, very similar to Browserify, except that it uses ESX modules out of the box. And one cool thing that it'll do is, it's called tree shaking. The way ESX modules are defined, you can actually do static analysis on the code, meaning that like when it's compiling, it can kind of look at all the code paths as it's building this thing and find like dead paths where there's code that's not being used, and it'll eliminate that out of the bundle. So they say you're guaranteed to actually get a smaller bundle size if you're using Rollup as opposed to Browserify. We're gonna look at Browserify. Browserify's been around since 2011, so since NPM was released. It was originally built as a way to take all this code that was being written for the Node.js, like the server environment, and be able to use that stuff in the browser. So again, it runs at compile time, it uses common JS, it allows you to require scripts from NPM. And one thing that it does is actually replaces certain files or definitions, like some of Node's core libraries that are meant to run in that server environment. Browserify replaces those with implementations that'll run within the browser. So there's some super helpful stuff in Node, like see the URL module or the path module, Browserify kind of, I don't know if you'd call it monkey passion, but it replaces those in implementations with browser versions. And that's a really nice plug-in API. So you can do, not only can you bundle these files together, you can actually transpile the files, and we'll look at some examples of what that is. So how to get started using it. There's three main ways to use it. You can install it globally. So NPM install Browserify, the dash G says globally, so install this on my whole system so that I can then in my command line type Browserify. And then the syntax is whatever your entry file name is, and you just pipe that or send it to the bundle.js file so you have your input and your output, and that's it, your entry files and all its dependencies have been bundled. Another alternative version of that is to install it locally. So whatever project you're on, wherever your package.json file is, you can install Browserify locally and run it from there. That way you're not installing this package, whatever version of Browserify you're using globally on your machine, you can have a specific version for your project. And the way you would run that is, so you install it just the same way, minus the global flag, so that installs it locally. Then in package.json, you have the scripts property, and you give that whatever script a name. Here we're just calling it build. You can call it whatever, call it bodiemcbookface. And then this is the exact same command that we ran here. So instead of running it on the command line, we're putting it in this file. This is handy if you have, as you're about to see these commands as you're adding more features, more transforms can get really long and pretty verbose, so you don't wanna have to type that every time. This is a way just to kind of take whatever command that you would normally run and run it with npm run and then whatever we call it. So npm run build. And then third way is using the actual API. So this is a lot more verbose than the other two, but when you get a fairly complicated build and a lot of things going on, managing a lot of different files for say a Drupal project, it's nice to be able to have this all broken out and you can add some logic in to how your build will run. So this is essentially doing the exact same thing this is. You can see there's a lot more steps in it, but we'll see in an example why that's beneficial. So here we're requiring FS, which is short for file system. It's just a node core package. This is what allows us to write files to the disk. Require browserify, create an instance of it. We call it B and then we do things to that instance. So we add an entry file and then we bundle it and bundling it doesn't actually send it anywhere. So we actually have to then pipe that to our actual output, the bundle file. So FS create write stream that saves a file to the disk. If you wanted to not save it to the disk and run it to standard out and just show it on your screen, you could do that if that's what's fun for you. And here we're running very similar. We have a build script and in this case, we're running this build file. So not a specific command, but that file and the command for that is just node build. We could just type node build directly into our terminal and that would run as well. So let's look at some different use cases here. So one thing browserify allows you to do is create some custom builds of things. If you've ever used Modernizer, everyone know what Modernizer is. Does anybody not know what Modernizer is and want me to explain it? Modernizer allows you to do browser detection. So say you have a feature that you want to use like CSS animations and whatever design that you've created being a designer. Whatever you've created, say it relies on that animation, but you want to make sure that browsers that don't support animations can actually run it too that you provide a fallback for that. So Modernizer allows you to do those checks. There's a port of Modernizer called browserinizer. The names get more ridiculous than this. And what's cool about this is rather than going to the Modernizer website checking all the boxes of all the builds like the different tests that you want to run and every time you want to add a new test, you have to go back there and check more boxes. This allows you directly in your script just to require the actual tests that you want. So we want to test for animations, we want to test for transforms and CSS columns. Once we require those and we require browserinizer, that'll actually run the checks. Once the browser loads the scripts and it'll add those CSS classes to the body tag. In this case, the lower example where we actually set that require to Modernizer variable, then we have access to that so we can utilize some of the other features of Modernizer. For instance, if there are CSS animations, load this other thing or do this thing. So that's pretty cool. Requiring submodules. So if you're not familiar with Lowdash, Lowdash is kind of like a utility belt for JavaScript. It basically creates a very uniform way towards cross-browser for doing simple things that a browser should be able to do anyway, like array maps, filters and reduce. It'll do that in a consistent way. So this is a tool we use quite a bit. In this example, we have transformers.js. It's exporting an array of transformer objects. And then in autobots.js, we are requiring Lowdash. So that underscore, just like the dollar sign, is kind of the symbol for jQuery. That underscore is often used for Lowdash or underscore. Then we're importing transformers from this other file. So we're just importing that array of transformer objects and then creating a new array called autobots. And we're filtering only the transformers that are autobots. And what we get is that autobots, that single array. Fairly straightforward stuff as far as filtering arrays goes. But the important thing to note here is we are using this entire library. We're loading all of Lowdash just to do a simple filter, something that most browsers can do without any extra library. So that's not very efficient. An alternative to that is we can actually reach into that Lowdash framework or library and require that specific function. And that's gonna only pull out whatever filter depends on out of Lowdash and just load that so we get a smaller build. Basically we're just, rather than requiring the whole library, we're setting that to a variable of underscore filter. Yeah, does that make sense to everybody? Cool. All right, dealing with global dependencies. I mentioned we don't wanna respect the global namespace. Sometimes, we just can't get around that. We need some library that's been loaded globally. In case we're working on Drupal site and especially if it's Drupal 7, it's loading jQuery globally. In this case we wanna require that just so we're being consistent. But rather than, if we do this, it's going to also include jQuery in our bundle. But we don't need to do that. It's already loaded globally. We don't wanna load all that code again. We already have it. So what we can do is use Browserify shim. Browserify shim does a few things. One of those things allows you to require things that have actually already been loaded. So how we use that is in the package JSON. We tell Browserify we're using a transform. Transform is called Browserify shim. And then that accesses its own variable within package JSON. This is Browserify shim. Every time we require jQuery, don't actually load that up. Just reference the global jQuery that's already there. This also works. Drupal is gonna load like in Drupal 7, and you have Drupal with capital D, that library. You can load it in this way so you can require it and access that same. So that way you have access to Drupal.settings. Drupal 8, that's actually its own global variable called Drupal settings. So you can access it that way and not include it in your bundle. So looking at a couple more transforms. So our dependencies don't have to be JavaScript. This is the same tree we were looking at. We have dependency A, B, C, and D. Those don't necessarily have to be JavaScript files. In this case, we have some ES6 files just using a different syntax. We also have header.nunge. So if you're not familiar with nunge, nunchucks is a templating language almost identical to twig in terms of the syntax. A little bit different API, but for most people that are writing templates, it's gonna work just the same. And it's supported pretty well. It's a project from Mozilla. And in this other case, we have a YAML file. So breakpoints.yaml. We have breakpoints that we wanna write in a YAML file and maybe access that in our CSS and our JavaScript. So these files, they don't have to be JavaScript files necessarily. And what browser file will do, along with some transforms, actually take all that junk and convert it down into a JavaScript file. So this is probably my favorite of the browser file terms, nunchuckify. So in this example, we have robots.nunch. And you can see this looks just like twig. So for robot and robots, we want to print out this markup and print out these variables. So robot.name.team.form. So in robots.js, again, we're requiring that same Transformers file and array of objects. And here's what's cool about nunchuckify, allows you to actually require a template file directly. So we have this template. We're requiring it. We've got all our markup kind of segregated into its own template file. And the JavaScript, we just require that file and pass it. Really, the only important part here is the robots.tpl.render. In this example, we're just throwing it on the body of the page. You'd probably never do that. But we're loading that. We're telling it that robots equals Transformers, that other file that we just required. And this is what we would end up with. So just taking those values from those objects in the array and putting it in your template. This is really nice if you're doing maybe a complex navigation, like a mega dropdown, something like that. Anything dynamically loading maybe a JSON file and you want to take all those values and actually input it or output it as markup on the page. You don't have to screw around with like defining all these different jQuery elements and appending and prepending and before and after and kind of jumbling together a menu or whatever that way, it kind of keeps it clean and it's super easy to use. So real quick how you apply Transforms. We looked at, sorry, I'm just checking to see how we're doing on time. So we kind of looked at this already. You can apply Transform through package JSON, super easy. You have the browserify property that has a transform property, which is just an array of all the different Transforms that you want to add. The browser variable, this is something that browser file use anytime you require a specific file, it'll map that file to whatever you have here. So in this case, for Nunchucks, we want to use the slim version of Nunchucks when we're actually building our bundle that's going to get loaded into the browser or our actual production code. Otherwise, if you just require the straight Nunchucks, it's gonna load all the compile code. What Nunchucksify does is pre-compiles all your templates into functions that are much more efficient than having to actually, your page loads up on the client, they're on their phone, and you're doing all this like regex stuff to figure out how to compile a template. So that's what the browser property is. You're gonna apply it through the CLI, so if this is the way you're going, just the T flag and whatever Transform you're using, and then actually applying it in the API. So this is that same example that we showed earlier. So after we add the entry file, we're adding the Transform, in this case Nunchucksify, and then we're bundling it and writing the file. So doing Transforms is pretty straightforward. One really big Transform is Babelify. So if you're not familiar with Babel, it's a transpiler. So it takes the new ES6 syntax that not all browsers support, and transpiles that down to ES5 syntax that like IE 10, 11, I think you can even go back possibly to eight, I don't think so, you definitely need to go back to nine. But it takes, it's kind of like a post-CSS processor. You can write kind of the new syntax and this'll process that file down to the old syntax. So using this, then we can actually, rather than require things, using common JS, we can require using, or import using the ES6 syntax. So Babelify is the name of the Transform, and one thing you have to do with Babel is actually tell it the presets, like what are the things you're really concerned about transpiling. So these are pretty common. We have Babel preset ES2015. That one's probably the most common. And then we have Babel preset React, which does like, allows you to use JSX if you're creating any React applications. So a couple more things, and then I'll get into, I think I'm running out of time, but I'll get into an example of actually implementing this in Drupal. So code splitting, in this case, we have two entry files. We have x.js and y.js. Those, so x requires z and w, y requires just z. So in a normal case, if you create these two bundles, you take your two entry files, even if they require the same file, they're both gonna bundle them. So you have that same library in both files, which isn't very efficient. Factor bundle is a plugin that'll allow you to actually take out the common files and break them out into their own bundle. So just to visualize this, we have x requires z and w, y just requires z. When we bundle those, we end up with x that has x and w in it. We have y that just includes y, and then z, because both of those require z it just kind of sucks that out into its own kind of common library file that then you can load beforehand in both of those x and y will have access to it. Does that make sense? Cool. This is how it works. This is using the API. So we have these source files, which is an array of our entry points. We import those, and then we run it through the factor bundle plugin. So we tell it, what are the outputs? So what are the bundles that our entry points need to end up in? After we do that, what's left over are our common files, and we write those to the disk. So it's a little bit weird to get set up, but once you have it running, it works super well. And then the last thing I wanna talk about is watchify. So browserify has its own watcher. So if you're used to using gulp or grunt, they have their ways of watching files. So this file changes, run these commands. Watchify has its own. You don't actually have to specify which files to watch because it just knows the dependency tree based on your entry points. And what it does is the first time it compiles the whole thing, all your dependencies. And then it keeps kind of a cache of all your different modules that have been required in there, your whole module or dependency tree. And then it watches those individual files. So if those change, it only has to compile like that one file and the things that depend on it. So it's super fast. And a larger code base go from maybe four seconds for the initial compile down to just change in a single dependency and it's more like 30 to 50 milliseconds. It's super fast. So watchify, definitely if you're using grunt or gulp, figure out how to get watchify integrated into that rather than their standard watchers. And thank me later. So how do we actually use this with Drupal, putting it all together? So I've got, this is just laying out what we're trying to do. So we have our theme, we have our various modules. All of those probably have some JavaScript of their own. So here we have, we're just calling it, my theme is the theme and then my theme.js because I'm super creative with the naming. So we have our source files, those get built out into the build files. And then, same with the module, it's got its source js and it's build js. And using factor bundle, we want to any, anything, whether it's in the theme or one of our modules, for our project we wanna pull those out into a single common library. That we can depend on using Drupal. So that's what we're going for. This is how we're gonna run it. So we have in our package JSON, we have two scripts that we've defined. We have bundle and that's gonna run this file in the resources scripts directory called bundle. And then we have bundle watch, which is gonna do the exact same thing but turn on watchify. So that'll be like our development task that'll keep running and watching our files. How we use that, so npm run bundle or npm run bundle watch. Now this file, as I said earlier, this is why I like to use the API because these things can get pretty complicated. We're dealing with like files that can be in different directories depending on how your Drupal site's set up. So this file is a little bit long. I'm gonna actually walk through these different sections. We have our npm modules and the different things that we're loading. Arc v is the thing that allows us to capture arguments in our node scripts. So this is how we're gonna flag it, a particular script to watch with watchify rather than just compile once. We have the file system. We already talked about that. We have globbing. So this is what's gonna allow us to say I want all the JavaScript files that are in these particular folders to make those our entry points. So you don't have to always say like I've added a new theme JavaScript file. It's just gonna look for any scripts within a certain directory and automatically compile those. Path, it's just a node module for figuring out relative and absolute paths and files. Make a Drup, which is make a recursive directory essentially browserify, factor bundle, and then watchify. Then we have like our settings. In a real world use case, I'd probably break these out into a separate file like per project. So I'm not including these like specific project details right in my build file. But for this case, here they are. So we have our source files. So public HTML is our root Drupal directory. This is a Drupal 8 site. So this is just globbing for either of these subfolders. So modules or themes. Inside those, we wanna look at just custom things. So we're only dealing with our specific projects. We're not trying to compile like contrib stuff. This is just saying whatever custom module or theme, if there's a source.js file in there, that's what we want is our entry point. Then we have a common directory. So public HTML, modules, custom. This is where we wanna put our common file that factor bundles can spit out. Oh, sorry. So common path, where the path is, we're actually just joining the file name and the path. And this is just a sort of a helper function to figure out. So wherever we found an entry file, wherever that source JavaScript file is, we wanna basically back up two directories and find a build directory and put our built file in there. And this is actually like the callback that we run. So in this case, we have our browser file intrent, sorry, instance. That's taking entries files. These are the files that come from our glob, cache and package cache or something that we just have to turn on for watch file to work. Here's where we're checking if the dash w is set. If that's the case, then we're gonna watch these on this task. And here we're turning on bablify. In this particular project, we're using React for some applications or some screens on the project. So we're loading the react preset. Here's where we are actually taking the bundle files, saving them out, making sure the common directory exists and then running like the actual, these are event listeners for watchify. So every time something updates, rebundle and log what updated. Every time something logs, actually print it out to the screen so we can see what's going on and then our initial bundle. And this is just writing those out. So I wanted to actually just walk through that. So I know I've had a lot of, I find files or like a gulp task or something and I just copy and paste it and I have no idea what's going on. So I wanted to walk through and kind of explain like each of the individual steps that we're taking here. This file will be available. This is something you can integrate. Like I said, if you're using grunt or gulp, you can absolutely integrate that into your process. But other than that, that is pretty much, oh, sorry, actually including these in Drupal. So this is Drupal 8. We have our module.libraries.yaml file. Here this is where we're putting the common file. The actual MyModule specific.js file. You can see here we've got a dependency on the common file. So Drupal will make sure that anytime we're loading like we wanna load this module JavaScript that it's gonna load the common script first. And then same with our theme files doing the exact same thing. We're just loading it and making sure that the common file loads first. And that's pretty much it. I guess one thing to note that pre-process, false is something, I didn't include it in this example, but we run browser sync as we're developing. So every time browser file will bundle files, it'll refresh any browsers that are attached to like the browser sync instance. So you can have your phone out, your iPad out, you know, Chrome, Firefox, IE all out on the same page. And then all those will refresh and sync together. One thing I found out in doing that, sorry, this is tangent. Browser sync doesn't work with the way Drupal aggregates a ton of CSS files. So I'll put that pre-process false on any file that I'm actually working on. And then I can turn on aggregation for CSS or JavaScript in Drupal. It'll aggregate everything else except for the files that I'm working on. And that really cut down the time between like making a file change, hitting save, and when Drupal actually refreshes a page. So yeah, side note, there's a tip. And that's it. Love to answer any questions if I can. If you don't mind, go into this URL. This is just the session link on the site. Fill out the survey, let me know if you'd like to talk, if you learned anything, if there's something I missed. Yeah, any questions? No questions. Yeah. Do you have a particular list? Yes, sorry. The question was, are there any particular minification plug-ins? This one's actually more ridiculous than non-juxtaphy. It's aglifyify. So that's basically taking aglify and wrapping it in as a transform. But yeah, that works really well. And I would add it kind of the same way we do the watchify task, like check if this is a production bundle, add that. Cool, thank you.