 Welcome to, can everyone hear me all right? Yeah, cool. Welcome to Getting Started with Brun, for better front end operations. My name's Steven Bassett, I'm with a small firm out of Oakland, California called Calamuna. You can find me on Twitter at Bassett SJ, for Steven Jeffery, and also on GitHub under the same handle. So what is this thing called grunt? Raise your hand if you've ever used CodeKit or any of those other automation tools. So grunt basically is the same principle behind it. It's all about automating things we should be doing in our front end workflows or workflows in general, except it provides more robust APIs and is highly configurable. So why would you even want to use grunt? Well, it helps us do the things we should be doing easier by automating it, making it easier, and sharing it. It allows us to work in really small bits of code using modular JavaScript or CSS, all maintainable files. But then it brings all of that code together and compiles it and minifies it to help improve our website performance. It helps encourage quality assurance by linting, checking for errors, and also running unit tests. Raise your hand if you're writing any unit tests for JavaScript. It's actually better than I thought. Yay. Also, it helps us abstract our code using tools like SAS, less, stylus, what have you, all the same, roughly, and helps enable that. I think the coolest thing is it becomes part of the project and onboarding a new team member becomes really simple. All the configuration for these tasks live inside the project. I know that CodeKit has a standard, but CodeKit costs money. It's not cross-platform. There's a lot of pitfalls there. So some common misconceptions when I hear people talking about reasons not to use grunt. I don't need these things for my Drupal project or Drupal already kind of does it. There's not really a great build tool out there for Drupal. This is a great compliment to the stuff, to tools like Drush and things we should already be doing. Grunt uses Node.js. I don't know Node. It's pretty easy. If you're already a themeer and working with JavaScript and you have some basic programming experience, it becomes very easy to work with. I'm not a programmer. I don't know how to use the command line. It becomes really easy. All you need to be able to do is type in grunt on the command line. It'll run the default task. It's pretty simple to work with. Can you hear me? Sorry. Is that better? Good. Okay. I'm sorry. A little bit of a throat issue, of course, the day I speak. For this presentation, I came up with an example project. You can kind of follow it along. I tried tagging each step as I went through. It's not exactly perfect, but you can kind of look at it there. There is an example theme. It has some basic components to it. We're using SAS. We have some logic in the template. We have an index JavaScript file for all of our plugins. Steps to get started. We're going to first, of course, have to install Node, which is extremely easy, define our project in terms that Node understands, get the plugin, the actual tools that we need, configure the task, and then we win. Installing Node is extremely easy. If you use homebrew, type in that line, it pretty much takes care of it. It's really nice, big fan. Or you can just download the binary. Node will run pretty much in anything. If you are working in Vega and it's super easy to install, if you're working on a Linux box, easy. Runs pretty much anywhere, really nice. Now the package.json, this is kind of in Drupal terms it would be the module.info or in composer.json, exact same thing. We're basically just defining some attributes so that grunt and Node know a little bit about our project. Really nifty utility. Just typing in npm and nit will kind of guide you through a nice little command prompt that will even try and auto fill in some stuff. This is where you get remote is, or this is the home page, or this is the version you have. A really basic outline might look something like this, just answering where your main file is, some keywords, what type of licensing information underneath. There's really great documentation on the package.json spec on the npm docs. Now we're going to need the one global utility, the command line utility, so they broke off the interface that you actually run from the command line into its own plugin. So you need that universally, it will download and link it, and it should just be right available on your path. So you might just want to run grunt-version just to make sure that it's there. Now we need to install some grunt plugins. There are a ton of them, and later I'll show you great ways of finding them. And we also need to make sure that we install our local grunt package, and if you add the dash D capital flag that will also append it to your package.json, or the dash dash save dash dev will append it. So now you're adding instructions for fellow team members to be able to quickly get up and go. So if there's already a defined package.json, all you need to do is type in npm install. npm will figure out what things it means and take care of itself. It's really easy. So grunt is going to be looking for the grunt file. It can be either in JavaScript or CoffeeScript. For this demo I just used JavaScript. The most simple grunt file is just this. It tells you what the module is exporting and that it requires grunt. So let's go ahead and start configuring tasks. One thing that's really helpful is to go ahead and expose some of the project configuration through the package.json. And this init config is where most of our tasks will go. We're basically just assembling a lot of plain JavaScript objects. Let's go ahead and add the sass plugin. You'll notice in the name that contrib, that means it's maintained by the core grunt team, which is a good sign it usually means quality in general. So after we install that, you'll notice in the package.json that we have both grunt and grunt contrib sass, the version we've used, and it's all there. Sorry. Now for each task it'll have a name, and then underneath that is a target. So you can have multiple targets for each task, so a good example might be whether or not you want it compressed or not, or if you have different files you're associating with it. Each task will have an options object and usually a files object, and there's a hierarchy. If you set an option just below the task, it'll be inherited to the targets below unless it's overwritten. Now we'll also want to make sure that the node task, or the node plugin's available, so we'll have grunt load it with grunt load npm tasks as a method. And then we'll want to go ahead and define the required default action. The default action is whatever runs whenever you type in grunt. This most often is like building out a project, deploying it, whatever, and you probably want to provide a little bit of help information here to make it a little bit more usable for other people working on the project. But as you can see there's not really that much difference than just running sass. So the real power comes from adding more tasks and targets to this. So let's go ahead and do that. I've really been enjoying using auto-prefixer. It'll go out there to I can use, or can I use, sorry, a database that'll basically tell what browser or vendor prefixes you need for your targeted browsers. So now all of a sudden you don't have to worry about including mixins to get the vendor prefixes or writing them yourselves. You just write as you shouldn't be able to, and it'll figure it out for you. It's really nice. So as you can see, something really simple. You let the machine do it, and it's all there. And guess what? Ask for it, surprise. Most often I just Google grunt auto-prefixer, but I also like checking out the grunt plugin directory. So just go to the grunt website, and it'll sort it by most popular. You'll notice that all the contrib ones are at the top. It's really easy. And then the first thing I usually do is when I land on the project page, I scroll immediately down to the bottom. You'll pretty much find a template for the task that you want. You might have to change a few variables, read which properties you need to change in the configuration, copy and paste. So I kind of did that again here. So I found one that showed how to use the source map, which is really nice to be able to tell debugging where things came from, and just pointed it to the CSS directory. And then if you leave it off here in the documents it says, it'll just go ahead and auto-prefix the file itself so you don't have to worry about moving it to a temporary location and then moving it back over there. And then I, of course, do the load npm task and append it to the default task. So what becomes really helpful, and I think pretty much everyone uses the watch task in their grunt file, it's really handy for when you're developing. It waits for changes and does it. It helps save you time from going back to the terminal, typing in grunt or grunt target blah or task target. And it just really helps. So in our example, we would just configure it again to look at files in SCSS, the tasks, run the two tasks that are associated with it. And now all you have to do is run front watch. But you can do more. Has anyone used live reload? Yeah. Best thing ever. Helped save refresh. So I recommend having grunt watch for the files after they're generated, especially if you're doing a lot of things with the files, you want to make sure that it auto-reloads the file once it's done with it. So once it's in the dist folder or whatever you call it, the build folder, go ahead and reload it. So in the projects, I'm going to go through these quickly just because it becomes a lot of the same. And I'll get to the good parts of how to do these things better. We'll probably want to minify the CSS, probably run JSent, browserify for using common JS style modules. You could also use kinkat, which would be kinkatenating the files together so you can work in really small ones. That's a really good place to start out with. And then minifying and uglifying the JavaScript, mangling it and making it small and compact. So the CSS min task, just go ahead and go through. And something really key is if you notice it's filtering out the non-appended with minified. So the expand will go through and look for all the directories. And within the dist folder and then append the min.css, so it doesn't run in a loop. And then JSent is really nice. I'm really excited to see that in Drupal 8, now that we have a JSent standard, go through and have it actually hint your grunt file, which can be good, especially with the task. So any of our theme as we code. And then browserify, go ahead and put that in there, aim at our index or main file, and go ahead and pull in the modules that we want. And then after we packaged, we bundled our JavaScript, go ahead and uglify it and put it out there. Really cool this banner argument here is if you can go ahead and use the built-in grunt dot templating engine, you can go ahead and go through and grab information from the package.json and be able to have, you know, like today's date, the version number, et cetera, appended to the top of each of your compiled files when you're done. And there are also some really nice PHP tools out there, and I'm sure there are many more beyond this list. Grunt PHP code sniffer will actually go through and check for coding standards. This would be good if you're developing a module or even just in the theme itself. I suggest using Composer to download the code sniffer itself, PHP Blunt, it's really simple, it just runs PHP-L, it's a nice little wrapper around it, but it will give you some really obvious syntax errors as you're coding, kind of similar to an IDE. And then for the upcoming PHP unit and Drupal 8, there's a nice PHP unit plugin as well. Also there's a really simple Drush plugin, and this could be really nice for, you know, making track of when you make changes in the templates folder, being able to just clear the theme registry when you need it and not constantly having it rebuild or, you know, getting started in development mode, turning it off, setting variables, it gets really nice there. So as you noticed, each time we add a new task, we have to hit the load tasks. There's got to be a better way to do that. Luckily there's load grunt tasks. You'll also notice that your grunt file becomes really long, load grunt config, grunt notify. If you're using watch and running unit tests on save, it'd be nice to know when it fails or some error happens. Grunt notify will plug into the notification center and growl to help notify you when there's an error. And then speed. You'll also notice as the grunt build becomes more longer and you start doing more advanced things that you might want to decrease your build time. So concurrent, grunt newer, and time grunt will all help encourage a faster build. So looking at grunt load tasks, you'll see it becomes kind of monotonous loading all of these tasks. You can change that and just load a single task right there. But even better is being able to split your config into individual files. And this includes grunt load tasks as well. So grunt load config is super nice. You just simply define a file, either a coffee script, javascript, or yaml that holds the single task configuration. By default, it looks at the grunt folder and for the file name to that task, you'll notice that it gives you a, it also has an alias file. So for defining the default task, it gets really easy. You can start creating, you know, tests. So it'll compile your tests template down. It'll run your QUnit or Jasmine tests quickly and report back. That's a nice way of grouping information together. And then if we look at grunt notify, awesome plugin. It's really easy to configure the notification messages on build and fail. And it works pretty much cross-platform. And then grunt newer, this one's really good for tasks that take a while. It will only process changes for newer files. Instead of a good example of where you'd want to use this might be like image modification or optimization. You might only want to run that on new files that have been added since the last time you ran that, and that way your build time, it doesn't have to do it all over every time you hit grunt default or whatever. And then grunt concurrent. This is a little tricky to get running well, but you can run grunt tasks concurrently. So you could, for example, compile jshent and browserify the files all at the same time and that can help save time. And the way to tell what's taking the longest would be time grunt. It gives you this really nice feedback letting you know how long the task took and which task took the longest. So there's a lot of, Gulp has recently come out. It's another awesome tool to help with this build process automation. So why would you want to use grunt when there's new fancy shiny option is out there? Well, there's also the fear of using the wrong tool. So either or just choose which works best for you. They both have a lot of good advantages. I said the plug-in ecosystems probably a lot more robust in grunt and a lot of projects are already using it. And if you're already using it, great. And many of the same principles apply. Just to take a quick look, this is what a very simple Gulp task would look like. It's a lot more, it follows a lot more of the node principles of loading in tasks just by using require, for example. And what allows it to be a little bit more performant would be the streaming APIs of moving the files and piping it from one process to the other. And it's a little bit of a, it's less configuration heavy and more focused on programming the tasks themselves. So that's it. Do you have any questions? There's a microphone right in the middle. Can you talk about when you would use Drupals, like default CSS minification and the JS minification versus the grunt? Yeah, definitely. So Drupal does do pretty good CSS minification and aggregation, which is nice and it'll actually handle that pretty well. As far as minification of JavaScripts, there are a few, I think there might be a contributed module that uses some sort of PHP library to minify PHP. But it only concatenates the JavaScript files themselves into bundles. It doesn't actually minify and nullify. So you're going to get better results using grunt over the built-in preprocessing of CSS and PHP and JavaScript and Drupal. Thanks. Yeah, no problem. So with, the mic is right there. So with JS and Drupal and combined, can you hear? Yeah, yeah. It's mostly for the video recording. Okay, sorry. With JS and Drupal, there's so many dependencies and oddities of what JS assets are loading, concatenation of files, you don't want to take everything in core and just throw it into one concatenated file. That is a huge waste of resources. Can you address how you instead of picking out each file, how you get to do that with grunt? I think that's one of those weird things. Yeah, I generally, like any of the core provided JavaScript, you just kind of have to accept that at least in Drupal will expose it to the window, right? So within the realm of like a theme or a project, that's when you can pull in different like packages and handle it on that level. So that's where you get the advantage of using grunt in that you can, you know, if you decide to use a jQuery plugin, you can pull it in and process it and then make it that much smaller and minified for Drupal to then handle itself. So it's like you're packaging it nicely and handing it off to Drupal and then Drupal repackages it a little bit and then throws it on the page. Yeah. Yeah, go for it. Uh-huh. How? I think it's being mindful of what you're including, obviously. So that's kind of like a lame answer. But you know, Compass takes a little bit longer to compile because it's pulling in. It provides a ton of tools for you. So if you are using Compass to compile your SAS and you're not really using Compass, maybe you should reconsider and use just straight up SAS and then pull in the assets. I find that auto-prefixer is way faster than including the SAS Compass mixins. And then you get pretty much the same result. And it updates itself. It's just really nice. So you saw we were using grunt-contrib-sass. There's also lib-sass, which is still being really heavily developed. But it's amazingly fast. It's a native port of SAS, so it's not using Ruby itself. You do lose some features, like extends. So it's not something I'm ready to switch over to, but it's amazingly fast if you can use it. I think, yeah, that's about it. Yeah, I think that's really good feedback is being able to, instead of watching every single thing and then trying to run all, like pointing it directly at your project route and trying to recompile everything all at the same time, is focusing on running the tasks that you actually need with Watch. And it becomes a lot easier to deal with and also really getting good at building, registering aliases or registering tasks when you do it. Any other questions? Yeah, so Omega-4 integrates grunt out of the box when you instantiate a sub-theme. OK. Are you familiar with that at all? Yeah, I think that's really cool, though. So and I think it addresses some of this. I've never gone through the trouble of using it other than to know that I see the Ruby of libraries a lot appropriately in the node. And PM, I'd be curious to hear if anyone has positive or negative experiences with Omega-4's grunt integration. Positive or negative? Have you felt a delay? And that also brings up another. Yo-Man is a really great tool that helps scaffold out different applications or projects. That might be a really good use for that. There's even just a specific Yo-Man grunt file generator that'll kind of scaffold out the very base tasks that you need to run. And that could be really good. Or you could just create a simple gist of a grunt file that you use over and over again. And that's a good way of getting up and going. But I'd say start really simple. Maybe just have grunt sass and grunt watch and go from there. The more you do it, the faster you can start writing out these tasks. And as soon as you realize it's all basically just a giant JavaScript object, it becomes really easy to understand. Any other questions? Yeah, it's always in the project route. You can have it point at, you know, you can pass it to, by default, it looks at the project route. And I think by convention, that's where it goes. Go for it? Yeah. Yeah, I mean, I would say look into using both. Goal does have faster build times, which is huge. You'll notice as you start getting more advanced with your grunt tasks that it does take a little bit longer. And you also don't. One of the biggest annoyances I have with grunt is you take this file. Let's say I have a sass file. It compiles it down. I put it over in temp dist or whatever. And then I have auto-prefixer move it over to another directory. Let me go back to the grunt tab, the goal example. Instead of doing that, I could just have in the actual task itself add another pipe to an object called auto-prefixer and pass in auto-prefixer. And it will do all the things before it even outputs a file itself, so it doesn't even read and write before the task is done, which is pretty nice. Go for it, Tiago? Grunt concurrent is pretty popular. Yeah, I mean, the amazing thing about grunt over a goal, I'd say, is just the plugin. There's already so many tasks that have already been built out there that you can probably find something for what you're trying to do. I've used grunt deploy sites. I've used grunt for my .files, for example. Bringing those around. It's pretty easy to work with. Any other questions? Please let me know what you thought about this talk. And the slides are available at that address up on the screen. And it's also on the session node. Great. Thanks.