 Hello. My name is Sam Thurgood, and I'm looking for the Bipper. Here it is. So I'm from Sydney, as Matthew mentioned. I'm on the developer relations team there. So today, I'm going to talk to you guys about the Closure Compiler. It's actually quite old for Google, right? It's been around for 10 or 11 years, but it's something that can make you more productive. So with that, let's dive in. But I want to start with a happy cat first. So I've been at Google for a long time. I've worked on C++ projects, Java projects, Objective C projects, and I love a compile step, right? It makes me feel like warm and fuzzy like this. I think this is the same cat as Eric used, actually. But this is what I feel like when you statically compile languages. It's like this confidence that your code is doing the right thing. You're getting build time checks to make sure that things aren't going to break spontaneously for your users. So with that in mind, I want to reintroduce the Closure Compiler. It's a JavaScript optimizer, transpiler, and type checker. And what some people don't really know is that it's also like an ES6 to ES5 translate, a transpiler. It supports all kind of normal stuff you'd expect from a tool like that. And being on the cutting edge of ES is pretty much the highest thing on the team's priority. They're keen to support things like async and await. And that's coming soon in some future release of Closure Compiler. It's a Java jar. It was released many years ago as a pure Java thing. You had to install Java to run it. But just recently, Google has released a version of Closure Compiler that runs in pure JavaScript. So it turns out when you tell developers you have one fewer dependency and that dependency is Java, people are really happy. And so obviously, Closure Compiler loves Polymer. This talk is really about how to make these two wonderful, strange, sometimes behemoth things work together to make you more productive. So I want to talk about your first compile. How are we going to compile your Polymer code with Closure Compiler? So I won't go into the exact build steps. There's some resources online, including some later in the end of the talk. But basically, you'll have to set this Polymer pass flag. So it understands a few Polymer quirks, the Polymer function and its properties object. And this will change over time as 2.0 comes out. I've been reliably told that there's fewer hacks than 2.0. So Closure Compiler will be much happier. But you'll probably still need this flag for whatever quirks we have happened to have in that release. To start with, I'm also going to talk about Closure's simple mode. So it has a couple of modes. I'm going to focus on simple today, but I will talk about advanced because I really love advanced. But simple is really where it's at. Let's show a quick example. So this is a Polymer element. It's pretty simple. And it has a single Closure annotation. It's a bit out of place. So you might be able to spot it. But there's also a bug. So let's look at the compiled version. So this is pretty familiar. Anyone who's done any kind of JavaScript minification is used to this thing on the top. It's a minified blob of JavaScript. It's short. It's made some concessions. It's turned variables into A's versus real names and things like that. It's pretty similar to most tools. But what Closure is also giving you is this warning. It's found an error. This is configurable. It can be a warning or an error. In this case, it's just a warning. It's telling us that there's no method called toLowerCaseOnNumber, which is right. Turns out it can't lowercase a number. The annotation you saw before, and I'll just go back to show you, which I'm not sure back will work. There it goes. So that annotation before, the number, tells us that this method expects a number. So therefore, Closure has given us a warning. It's not a number. What's going on? So let's talk about what simple gets you, as well as this kind of basic type checking. So it minifies, gives you local variables. Sorry, it minifies local variables. It turns them into short names. It gives you notices about side effect misuse. This is a bit of a weird thing to explain. But let's have an example. If you have this line on its own, without anything adjacent to it, Closure can basically tell you, why do you have this? It doesn't do anything. And so it will actually warn you about that. It'll also catch common JS pitfalls. It's a bit out of scope, what that means. But if you look up Closure compiler, it'll tell you a little bit more about the things it'll look for, and the problems it'll find in your code. It'll also do type checking. And while you saw an annotation before, one thing I want to point out is that Closure with no extra work will still give you some benefit. Because turns out, we know what the platform is. We know what it returns. So the same parse in function, we know it returns a number. So whenever we see x, and we see x move around your code, we know there's going to be a number. We know if you're going to use it incorrectly. Or we know that you've passed it to some method that doesn't expect a number. So you get a lot of benefit, even while doing nothing. So this is great, right? This is a simple example. And you can imagine, as your code gets more complicated, that these kind of annotations and checks will help you, right? Your code gets bigger. It'll find more nuanced problems. It'll kind of give you warnings and errors all over the place. I can show you some of my projects which have hundreds of lines of errors, but it wouldn't make a very good talk. And so this cat's pretty happy about that. So we're done, right? Well, it's hard. I mean, what makes this hard? And why wouldn't you use this closure stuff? You saw one example already. It was kind of subtle, but you'll need annotations occasionally to help hint to the compiler of certain types. What else? Closure expects JavaScript, not HTML. It's pretty basic. We can probably fix that. Duck typing. We've got that lovely picture there. It's fragile. This is kind of a pro and a con. Turns out, I've written polymer elements in a vacuum before. I've written something that has some properties and some functions, and I've given it to a colleague or coworker and said, call this method. It'll totally work the way I've told you. And there's no guarantee there. There's no contract. Yeah, of course you can solve this with testing and other approaches. Using static analysis is not the only solution to this problem, but as a pro, if you can provide the right closure information or the right information to closure, you can actually tell your colleagues or your neighbors or even yourself about what this method expects or what this class looks like. And you can be more productive because of that. I guess what I'm trying to say is, if closure is not a silver bullet, remember that you do need to provide some level of information, and that is a con. And one thing I want to talk about again is advanced mode. So this interesting point will come up a few times. So as I said, I love advanced mode. It's awesome. It makes closure really, really powerful. But it does this strange thing for closure. And the problem we have, is if you have stringed named observers or computed values, closure doesn't know how to look at these. It goes, it's a string. I'm not gonna touch it. But in advanced mode, closure will minify your property names, including your method names, which means that that update foo is now a one letter mapping that is much shorter or much neater, saving your space. So this is a common problem with closure in advanced mode. But I'll focus on simple mode for now. So what's the first problem? Well, you need JavaScript. Pretty basic stuff. Let's use something like CRISPR to pull out your JavaScript from your HTML. Next, as I mentioned before, closure is about types. So we need to provide some level of type information to closure to get the most benefit out of it. You know, we've got some built-in ones. We've got number and string and function. We've got built-in HTML types, like that maps to an input tag. And every Polymer gets a default type in closure's mind unless you override that. So it's the camel-cased version of your element. So an element called my-element will be called my-element-element. And it inherits from something called PolymerElement, which has a bunch of definitions about, you know, this.fire or attached or other callback methods. And so closure will actually help you if you use those incorrectly. What else is Polymer specific? Polymer has this.dull sign. So everything on the dollar sign here is of a completely unknown type. Closure doesn't know anything about what that element is because it doesn't see your HTML. It only sees your JavaScript. So it literally thinks this is of type question mark, which is the most generic type you can have in closure. What we can do is add an annotation here. So if this is of type my-element-element, then I can pull this out into a local variable. And we can tell closure that it's actually of a known type. So you'll see this kind of formatting pretty commonly throughout closure annotated code. Another interesting part of Polymer is behaviors. You know, I've deferred to the UK spelling here, you know, in honor of our hosts. And there's some minor caveats here. They're pretty not very exciting, but I'll go through them anyway. They need to be fully qualified. Closure needs to be able to get at them. So that means they need to be on window as opposed to hidden inside a closure. And by that I mean function closure, not closure compiler, just in case there's some confusion about those terms. They need to be annotated, but in researching this talk, I actually found out that the compiler tells you to annotate it, which I find a bit strange, right? Surely if it knows, then it doesn't need to tell you, but in a kind of a suggestion to go on network, I actually talked to a Polymer engineer this morning and he explained to me why this is the case. So if anything, come find me later if you are curious about why we have this double level of annotation. It's not overly exciting, but I find as a nerd, it's very interesting to know how these things work. So I've mentioned simple and I've gone through some of the requirements or things you might need to do to make simple work. So I'm gonna talk about advanced very briefly. What does advanced do that simple doesn't? So as I mentioned, it minifies property names. That'll make your code even smaller. It also does dead code removal and tree shaking. And these features together actually make closure one of the sort of best JavaScript compilers in terms of size. And it'll regularly do at least very well on kind of shootouts of what is the best compiler for reducing your code size. And what this will actually do is any code that's not run in a kind of a statically analyzed way will be completely dropped from your output. It'll even do things like inlining where functions that are actually shorter within your code but maybe better presented as an engineer as you're building it outside your code will be brought inside and inline directly in that position. And of course, it'll do all of simple. But I will continue about advanced a little bit. The big takeaway here is that most Polymer elements won't compile with advanced. If you want to use it for your own, that's great. And this property renaming stuff, which I keep coming back to, there are a few approaches to solve it. You could in fact put your methods in strings themselves. The keyword of your object defining a Polymer class could have on foo in a string. But that rapidly becomes a bit unwieldy. There's also something called goog.reflect.object which now I'm getting very, very detailed, which actually lets you introspect Clojure compiler's internal renaming table so that you can actually see what the compiler's doing while it works, kind of like a macro or a pre-processor. Yet again, a bit nuanced and a bit detailed. But if you can do it, it's really cool. You'll get a huge benefit, but only try it in isolation. Don't try to compile your whole code base with this because you'll get errors aplenty. So if I want to leave you with anything, it's basically to keep it simple. Clojure gives you a huge amount of benefit for very little work, actually. If you're writing Polymer elements with VAR and old style functions because you're worried about browser support, turn on simple mode, get Clojure compiler, add it to your projects because you get some of this really cool stuff. You get transpilation, you get static type checking, you get minification. And probably the most important part of all this is it's what we do at Google. And it's worked for us for 10 or 11 years. It's migrated into the Polymer era. And in fact, nearly all of our Polymer projects actually use it to be more productive. So this talk was largely drawn from a blog post called Using Polymer with Clojure Compiler. All these resources will be in the YouTube video, but you can Google for them later as well. So it was written by one of our key mystics and all contributors. It's in three parts. The first part talks about largely what I've mentioned today. And the next two parts go into a bit more detail about advanced and a few other topics. There's also a tool called Polymer Rename, which helps with this process. And finally, just this morning, I actually quickly put out a post called Polymer and Clojure Compiler, which you can read, which is really a how-to guide of how to add Clojure Compiler to an existing Polymer project. And there's even a repo you can check out to just literally type get clone MPM install and you'll have something that's been compiled and minified right in front of you. As a bit of an adjunct, I'm gonna talk a bit about the use of Polymer within Google. Because turns out, we use Clojure Compiler within Google, so it's a perfect segue. So inside Google, we use these things called build files. I'm not gonna cover them here, but they're basically part of our open source build tool called Bazel. We have a couple of simple rules that we use that actually help us build Hermetic, which means self-contained HTML and JavaScript files. This contains all of the elements that are used inside a particular project. This number here, this 350 projects, is the, I did a search a few days ago, for the binary target. So each one of those targets is something that gets built, that gets viewed in a browser and that is a real Google product. Some of them are internal-facing, some of them are external-facing. Most are probably things like internal dashboards or tools that are used by a small number of people. So finally, this binary target we have will also run Clojure, which is known internally as JS compiler. And it has a sort of special process for handling this property renaming stuff, which I've been mentioning. How do we store this code? We use something called Piper, which is a global version control system. One of its interesting properties is that it has deterministic build numbers, I'm sorry. I can do a build at any particular version and know whether that's gonna be green or red and know all the dependencies will be consistent at that version. So this is a nice property to have, right? I can basically check out any point in history and say whether my target was built successfully or it failed. But it has some side effects. So we have at Google what's called a one-version policy. So within our code base, we only really have one version of any open source or third-party library checked in at once. This includes Polymer. So while we might have rapid development in the public on GitHub, what will actually happen is we'll only occasionally do imports of that code into our mainline code base. And this turns out as like most companies, right? You don't wanna move or change your dependencies too rapidly. But of course, occasionally, we wanna do emergency releases. We wanna bring in a security fix or some urgent patch we need to make. What we have is something called a global pre-submit. And this is the lovely part about working at Google and I can literally run every single target and every single test, at least the ones that depend on Polymer, relatively quickly and find out whether that change will be successful. And of course, if you're feeling lucky, you can always just ignore the pre-submit and submit anyway. So finally, I'm gonna leave you on a few public projects which use Polymer. I mean, you've seen some of these already today. But for big projects, we've got things like Chrome itself, YouTube, the Google Developers Code Lab site, which is Eric mentioned, and you'll actually see if you go into the back room and do some code labs today. And actually for me, I'm actually the lead of Santa Tracker. So it turns out Santa is Australian after all. And he's pretty happy about our choice of framework, as you can see. And the secret is that actually I'm gonna go home and watch all these talks and go, what can we make Santa Tracker do this year that's even better at using Polymer? But just like all the good boys and girls around the world, you'll too have to wait until December to see what new features we've come out with this year. So that's it. Thanks, everyone. And I'll be around for Q&A later. Thank you.