e kind enough to share their time with me, and I really, really appreciate that. I also wanna thank all of you for spending the time to listen to me today. I'm really, really excited to see what you all build and I hope you enjoy the rest of Polymer Summit. Thanks. Awesome job. I wanna see a bumper sticker that says coexist but with the JavaScript framework logos. I think Rob's on a good path there. Our next guest, I met through a bunch of GitHub issues. He was filing on our tools and I've spent the last year trying to get our stuff good enough for him to use. But I think this next talk is gonna show how some of that work is irrelevant and I'm really looking forward to it. This is Chad Killingsworth. Thanks.  But we write US banking software. So why am I talking to you today? Well, in that role, I get to contribute to a lot of open source projects. Polymer being one, another being Google's Closure Compiler. But today, I wanna talk to you about a new project and that's using Polymer with Webpack. Now I can tell from the amount of questions I've already had that there's a lot of interest in this subject. So hopefully I can give you all the detail you need to actually use this today. Before we dive deep into the internals of how Polymer and Webpack can operate together, I wanna talk a little bit about why this is important and how we got here. So my team has been building JavaScript applications for a long time, number of years. But lately we've become pretty disenfranchised with modern monolithic JavaScript frameworks. What we found is over time, even though we tried to guard against it, almost every file in our app became tightly bound to the framework. So if we started up a new project, we didn't have a good set of choices. We were either making the same framework choice we had already made, which kills innovation, or we were rewriting and duplicating code we had already written, which is never fun. The other thing we found with this is modern JavaScript frameworks tended to have a much shorter lifespan than the products we were developing. So once they became deprecated, we were either forced to upgrade or basically maintain old code, and no one likes that. So the idea with Polymer and the Web Component Standards these are baked into the platform. And as we all know, there's a rule out there. You can't break old code in the platform. So if we're using platform-based code, we're guaranteed backwards compatibility. Great, this is perfect. This gives us our long lifespan. In addition, Polymer as a library was just really light syntactic sugar over the standards. And in fact, they went out of their way to not reimplement or even make easier in some case, native APIs, which we loved. Well, it might require us to write more code locally. That code was then closer to the platform thus producing our longer lifespan. So with the promise of Polymer One, I dove into it fully with my team and helped develop this rich component library that we could share among all our projects of UI elements. The idea being that as each project spun up, we could reuse the elements we had already built, just like Rob so aptly demonstrated and talked about, but not be locked into this huge framework. So we did it. And in most cases, things worked great at the element layer. When we put a Polymer element into an old Angular project, it worked. Now there's caveats. Angular couldn't see into ShadowDom, but that was intentional, we expected that. But once we got beyond, hey, this actually works, how do we build it, life was not near as fun. The really interesting thing came down to Polymer being mixed content of HTML, CSS, and JavaScript. Now, like most teams, we'd been through the full gamut of front-end build systems. We started with Grunt, we moved onto Gulp, and we even experimented with just using NPM scripts and rewriting Gulp ourselves. And kind of, actually, truth be told, today have projects that use each of these. It didn't matter which of those build systems we choose, integrating Polymer was not fun. One of the problems we encountered is when you did this, Polymer used HTML imports. Everything else out there uses modules of some sort, CommonJS, ES modules, AMD modules, it didn't matter. They used a module-based syntax. So those dependency trees, there was just no good way to mesh them. What we ended up having to doing felt pretty icky, actually. What we have to do is create a synthetic Polymer import element and add any component we might want to use anywhere in our app to that import, and then we can use it over and reference it over in the JavaScript. But when we switch back or refactor, we have to remember, oh, now I no longer use this, I need to remove it from my HTML import over here. And be careful because I need to make sure I really am not using it anymore. What happens is on larger projects, we ended up writing custom tooling to try to make sure and add checks that those two didn't get out of sync. Again, not a lot of fun. What we found ourselves struggling with was just the sheer weight of the build system code. Over and over in my team's retrospectives, what keeps coming up has got to be a better way. I don't like writing all this build system code. The other clue that there was a problem that needed fixing was the build system itself started requiring substantial documentation. Not the code I set out to write was a build system. I set out to write a product for my company. Enter Webpack. So let me first be clear. Webpack is a build system, and I'm talking about solving build system problems with a new build system. It's okay, it's totally worth it. I know you've heard that a hundred times. Give me a chance to prove that this is the case. So Webpack is a little bit opinionated, but it tends to be opinionated in the ways that help you as a developer instead of getting in your way. For instance, there's a lot of tedious tasks that we work on in build systems that Webpack just bakes in. Calculating the hash of a built file system so that you can add it to the name to do cache busting, there's 14 bajillion plugins that do that in grunt and gulp and name your build system here. Webpack has it included. Don't even mess with it. Just use the naming convention and away you go. One of the other big benefits of Webpack is it comes with the Webpack dev server, which is a local development server and an extremely stable file watcher. And I reference that because if you've tried to roll your own dev server, you know how easy it is for an exception in your build process to crash your dev server. That doesn't happen with Webpack. One of the other defining points about Webpack is the dependency graph. This is nothing new. Lots of build systems have a dependency graphs where they crawl your site and find all the used code. The difference with Webpack is it's all your code, not just your JavaScript, your CSS, your fonts, your images, all your static assets also get added to the build graph and copied to the distribution folder. That means when you stop using them in your code, they don't get copied to the distribution folder. This is magic and just works and is something I never wanna deal with out again. There's one caveat with Webpack though. It only handles JavaScript modules. So how can we add static resources to our dependency graph when they're not a JavaScript module? That's the job of a Webpack loader. A Webpack loader takes one input file and its sole goal is to transform it into a format that the rest of Webpack can handle, a JavaScript module in some way. So this makes most sense when we start out with ECMAScript modules. So maybe we're writing latest and greatest stage two proposal ECMAScript and we just wanna transpile it down to ES5 for delivery. Hey, the Babel loader does that. JavaScript to JavaScript. No problem. The next part comes with TypeScript. That's a little bit different. I am, in a lot of ways, I'm in a different language. Well, the TypeScript loader simply does what the command line TypeScript compiler does and converts it down to a JavaScript module. Still okay. Now we start getting interesting. What about SCSS files? So there I might need two loaders and you can chain loaders in Webpack. So we're gonna pipe by file through a SAS loader which is gonna create a CSS file and then we're gonna pipe it through the CSS loader which will make a style module which is JavaScript and can be dynamically add styles at runtime. Pretty cool. So Webpack just handles that. After we've got our loader set up, the next thing we deal with in Webpack is plugins. And plugins can deal with any part of the rest of the compilation lifecycle. So the easy thing, the natural thing everyone thinks about is something like minification, Uglify.js or whatever other minifier you wanna use. I tend to prefer Closure Compiler. It's not for everyone. But in that case, that's only a small piece of the puzzle. Webpack has plugins to do framework specific things. Webpack has plugins to handle licensing. Webpack has plugins to do internationalization. Optimize modules so that modules don't get duplicated or get bundled in correct ways. On and on. Keep in mind, a plugin works a little bit different than a loader because it's working across multiple files where a loader is concerned with a single file. One of the other strong benefits of Webpack is how easy it makes code splitting and lazy loading. Again, these are not new concepts but they've been strictly painful in most build systems. You as a developer have to maintain one set of files with how does my input map to my output files and in your code, you have to keep in sync as well and make sure you import them in a way that that actually works. Webpack does away with all of that. Instead, it looks at how you wrote your JavaScript and builds the modules for you. It also adds the loader for runtime work so you don't have to do that either. You don't need a separate module loader. Webpack adds it as part of your build. Let's take an example. So in this case, we have a main JavaScript bundle where the whole app is a single bundle. But let's say that last section, aptly called huge, is rarely used. We want to split that off and lazy load it and make our initial payload smaller. All we have to do is change how we import the module. So instead of using a standard import statement, which is static, we change to a synchronous import statement and don't worry, we'll talk about a couple different formats for this. This is the new dynamic import statement for ECMAScript. It's promise-based. So we're importing the same module just in a different way. Webpack recognizes this, automatically pipes out huge.js code to its own file and adds the necessary runtime code to wire it up for me. By the way, I keep saying injects run type code. That's typically pretty scary to anyone who really likes to know what's going on in their JavaScript. The runtime code for this, uncompressed is about 150 lines. So don't feel like a lot is going on here. It pretty much stays out of your way and does the bare minimum and does it well. So with Polymer, we're obviously gonna need a loader. Again, the tricky part here is that a Polymer element is mixed content. It's the problem with build tooling in the first place. So the Polymer webpack loader recognizes the types of content in your file and processes each one a little bit differently. So the first thing it does is it goes through and looks for any HTML imports. Instead of relying on HTML imports, it simply changes this to a JavaScript import statement. Great, that one's easy. The next one's a bit trickier. What to do with the DOM module and the template? In this case, we just make a big string out of it and call a custom runtime function which registers it with Polymer's DOM module loaders at runtime. So it just adds it in. And then the last part is the script tags. So external script references also become module import statements and inline script tags just become the module body. So splitting up, handling all three different contents, what we end up with is an all JavaScript bundle. One of the side effects of doing this, wait for it, you're no longer using HTML imports at all. So now you're not relying on a spec that's not gonna be implemented outside Chrome and you've got a JavaScript bundle which then the rest of your tooling is free to optimize in the way it sees fit. So one sticky point with all Polymer developers has been, I just wanna import from Node modules and use it in my element. With Webpack, you can. You don't have to do anything, it just works. You're already in a JavaScript module. One little note here, we're gonna start, and I'm gonna talk about this multiple times, the script element has type equals module. This is a clue to everyone who looks at your code that you're opting into module syntax and that's a little bit different than normal. You may have code that's not all using NPM yet if you're using Polymer. So you can also configure Webpack to do the same type of lookup from your Bower components. All right, so we talked about adding static files to the graph. What about images? Well, typically with HTML files in Webpack you would use the HTML loader. It would scan your file, look for any image sources and add them to the dependency graph. Now adding an image to a JavaScript module dependency graph may seem a little bit odd but in here Webpack again really shines. So all it does is you typically use a file loader for images and that loader's job is simply copy this file using the naming conventions I specify to the distribution folder and the JavaScript module part of it is the path name I just copied to. So then I have a valid JavaScript module which in this case just returns the image path and everything just works. The trick is Polymer elements we've already done all this manipulation on so we can't use the normal Webpack bundlers and loaders to handle this. The Polymer Webpack loader does this for you. It's internally going to pass your HTML content off to the HTML loader and let it do the same thing and it's gonna do a similar set of steps with your styles. Both of these can also minify as they go giving you more bang for the buck. So there's a few differences in how you write your code when you're using Webpack. One of the things to note is that in Polymer to lazy load an element, we typically use Polymer.import href. So that uses HTML imports, that's not going to work. Instead, we need to use JavaScript asynchronous imports. And like I referenced, there's a couple different varieties. The ECMAScript dynamic import statement, you can hear more about this tomorrow in Sam's Talk, is the easiest way and the recommended way to do this. It's promise based so you put your path to your component and then say dot then and use the results. But perhaps you're not there yet and you'd like to use CommonJS. So this has actually been supported for a long time. No one just knows about it but there's a CommonJS require call called require.insure which takes a callback and does a very similar thing. It's job is to asynchronously load a module and then call the callback when it's ready. So we can use that in Webpack today and then we've got our dynamic import. Both of these import statements work in Webpack and will be treated as a split point for code splitting. Now, you'll notice in my paths that I'm importing HTML files.  At this point, those files have been packaged as a JavaScript bundle. So it's totally appropriate to import them using a JavaScript function. The Webpack config itself is kind of interesting to look at. I think of it as kind of the best of both worlds between the grunt configuration file and gulp programability. You don't have to do near as much work and it doesn't get near as out of control as grunt does but it's a lot more declarative than gulp ever it was. So like most systems, Webpack is gonna start from an entry point or a set of entry points. With Polymer, your entry point is probably going to be an HTML element and that's just fine. The loader will do its job and everything will just work. But like I said earlier, we probably also wanna tell Webpack where to resolve and look up named modules from. By default, it's already gonna look in node modules but we might want Bower components too. So we just override the module lookup algorithm and specify two folders. It will now look in both and I don't even have to worry about it. Now we need to configure our loaders. Loaders are just a set of rules. Each rule has a test that helps filter down what files it needs to look at. Normally the test is just a regular expression on the file extension. Followed by that as a use block with the list of loaders I wanna run through. One note on this, it runs last to first. So in this case, we're running the Polymer Webpack loader to create a JavaScript bundle and then running Babel to transpile that bundle to ES5. And last, you can use include and exclude definitions to further restrict where it looks. In this case, I'm restricting it to my source components folder so that the rest of the HTML in my project doesn't get treated as a Polymer component. Now, member. Everything in Webpack is a JavaScript module. Modules do not have the same semantics as scripts. Probably the biggest difference here is as soon as you use a module, you're no longer in the global scope. The easiest way to address this with Webpack for your own code is simply to declare your elements on the window element, thus forcing them to be global. Now everything works again. You only need to do this if you need to reference the class constructor or the class itself somewhere else. If you don't need to reference it, if you just need to define it, you don't have to do this. But if you need to reference it somewhere else, you can declare it as a property on the window element. But perhaps you'd like to use a more modern method. You can also use module importing and exporting to do this. Again, notice the script type equals module. The import and export keywords are not valid in a browser unless you're already in a module. So they weren't working a script tag. So by adding type equals module, I'm telling the browser that I'm in a module. Now, one note, Webpack doesn't care one way or the other, you're going to be in a module. This is just an indication to anyone else looking at your element, what's going on. So now that I have script typing module, I can just say export default class, whatever, and that's now exported. Other things can now import it. One little note here. You can't actually import from an inline script tag. So while this is valid syntax, it doesn't really make any sense unless you're using Webpack. And then that block of code will become my module body and I most certainly can't import from it. So if you're trying to live in two spaces at once, this might be a good way to handle it. But a lot of the code we deal with isn't our own. It's library code. And for that case, we can't go change how it was declared. Webpack has a whole set of shimming options where you can at build time make minor adjustments to how code is declared to make it work. So in the top, I've got a script tag, and I do mean script at this point, not module. It's in the global scope and it's called add some mix in. I need to use it in another module. Well, since it's no longer going to be in the global scope, Webpack's exports loader helps. In that, I can declare exactly what file I'm talking about and I say I need to export the add some mix in symbol. Webpack will automatically add the export statement to the bottom of my file, which doesn't interfere with source maps and everything goes from there. On the reverse side is the provide plugin. So let's say a different piece of library code expected that add some mix in function to be global. Now it's not. The provide plugin says if any part of my compilation tries to reference add some mix in globally, add an import statement for it so that it's defined locally. So you can shim back and forth in that way. Now, if you have a large existing code base that uses a lot of script semantics, you're gonna be doing a lot of shimming. So just keep that in mind. Don't expect this to be just a plugin that works in it for all scenarios. There is a little bit of play around here. You can do it, but there'll be a lot of configuration to make that work. One of the other really cool things about Webpack is it natively normalizes modules. And by that I means it understands an ECMAScript static import, an ESNX dynamic import statement, the common JS require call and the asynchronous common JS require.insure call. If all the rest of your code is using language semantics that are already supported in your development browser, you don't need a transpiler for modules. Why is this a big deal? Well, one, it speeds up your builds not to have to run them through a transpiler like Babbel. But two, debugging is a whole lot nicer when you've got the native untranspiled code right there to look at. One of the gotchas here though is that as you start using Webpack and module syntax, especially with Polymer 2 and earlier, you're gonna lock yourselves in very easily to Webpack-specific syntax. That's okay for your own elements. Just be aware you've limited the ability to share your components with others. Here's an example. We're importing from node modules. Awesome, this works. We're using the node module resolution format except that anybody else who uses this element also has to be able to use the node module resolution format. So we've just limited our ability to share this to webcomponents.org. That's just not allowed. So just keep that in mind. Another thing to keep in mind is that how a browser resolves a URL and how it resolves modules and how nodes resolves modules, all three of these things have different semantics. For instance, the top link in the HTML import section is mycomponent.html. Well, you look at that and you know that that means find mycomponent.html in the same directory I'm currently in. Except that, if you're translating that to a JavaScript import, that could mean import from node modules or a sibling folder. So to get around that ambiguity, we require that the import statement has a dot slash. So the Polymer Webpack loader is going to add that for you. But what happens if you wanted to use a named import for a component? Well, Webpack adds specific syntax for this and it comes up in any place a URL is used, like CSS background images. By adding a tilde character in front of the URL, you tell Webpack, I really want this to be a module resolution and not a URL lookup. But again, that's very Webpack-specific, so be careful where you use it. One of the really tricky things that happens when you get away from HTML imports is that the polyfills start feeling very fragile to get bootstrapped. You have to do this precisely in the right order. So a couple things. One, if you're transpiling, you'll need the custom elements ES5 adapter and any browser that has native custom element support. But you can't transpile that folder and you shouldn't bundle it with any other polyfills because by design it can throw an exception. So watch out for that. The next thing is the rest of the web components polyfills, if you're using the web components loader, load asynchronously. So you have to delay your main bundle load until after the web components ready event fires. Now, if this all seems a bit tricky, it is, but there's a demo folder in the Polymer Webpack loader that shows exactly how to do this and I recommend you just reference and follow that and try not to overthink this. A lot of Polymer developers always seem to ask, how do I use a CSS preprocessor like SAS with my Polymer elements? The standard answer is you really don't need them, which is true, but not what they ask. And sometimes when you're working with other frameworks, you just really wanna reference those global color variables without using it. The problem is that the shady CSS polyfill features can't see an external style sheet. Adding an external style sheet reference, like I'm showing here, is completely supported by the Shadow DOM spec. The imported styles will automatically be added to Shadow DOM and properly scoped. But again, the shady CSS polyfill doesn't see it, so older browsers, you can't use custom CSS properties and in no browser can you use the add-apply mixing syntax. The Polymer Webpack loader has an opt-in option that in cases like this, it will inline your CSS into the element. So you can run your preprocessor on it and then the inlined elements will let the shady CSS polyfill match it and you can have both worlds at that point. All right, what about Polymer 3? So all of the functionality that the Polymer team is moving towards with Polymer 3 can already be used with this loader. In fact, it's doing almost exactly the same thing. You can bundle and use ECMAScript modules as you need right now. Where are we going with Polymer 3? Well, so maybe you're not thrilled with the idea of authoring your HTML inside a template literal in ECMAScript modules. Don't worry, Webpack should be able to do that for you. So we'll just run the same process we run today and stick it in the template property once Polymer 3 is far enough along in the development that that makes sense. My team, in fact, I didn't actually do most of the code. The developer who did is with me. We wrote this to reduce a lot of the build friction we were seeing. We're using this in production today with AngularJS applications. I also know of developers who are here who are using it in TypeScript projects. My team is gonna continue to collaborate with both the Polymer team and the Webpack core team to improve the experience in Webpack and Polymer for both of these to give you as a developer the best of both worlds. We really tried to design this to leverage the strength of both systems rather than try to let them fight together. A couple takeaways for you. In the Polymer Webpack Loader project, you're gonna find that demo project I referenced earlier. Rob Dotson actually wrote it. It's a great reference point for just the bare bones examples of what to use. But in addition, my team maintains a copy of the Polymer starter kit which shows the changes needed to make to a Polymer app to build with Webpack. That link is also referenced. You're free to reference both. Thanks, and I'll be around later for Q and A. Thanks, Chad. All right, we got one more. And our next speaker is somewhat unclassifiable.  When I asked her what I should do for an intro, she actually suggested. Meow, meow, meow, meow, meow, meow, meow, meow. Here's Myunica. It's not wrong. It's what's about to happen. 25 minutes. Hi, y'all. I have to make some banter with you. So I have the nightmare set up where I have slides for 12 minutes and then a live demo for 12 minutes. That's two computers. So everybody loves me right now. Cool. I'm just gonna go. Awesome. Hi, everyone. I am Myunica. I am not clicking. Can I have a clicker, please? I'm sorry. Hi, I'm Myunica. I'm that person with the cat. I'm not Weldorf on Twitter and GitHub and internet places. And I've been on the Polymer team for about two years. You may have seen me meowing about web components a lot. But I started right before Polymer 1 was shipped. This was exciting because back then, I thought web components were really cool, but nobody really knew about them. I would go to conferences and be like, I work on web components and people would be like, I don't know what that is. Is it an iFrame? No, it isn't. And I really liked doing that because I sort of became this traveling saleswoman door-to-door selling web components and be like, let me tell you how web components are right for you. And I'm glad I did that because talking to people, I sort of formed a story about the kind of teams that web components were good for and the kind of people that enjoyed using web components. And that story starts with the world around us. The world around us is built by people like you and me and sometimes we're crafters and sometimes we're assemblers.   You didn't do that. Even if you use something like IKEA, you didn't really craft that table. You assembled it.  You took things that other people did and you made them and you glued them together and you made a thing out of it. The same thing happens if you cook. When you make a meal, you take all these ingredients and you mix them together. You don't find your own tomatoes and corn and churn your own butter and grind your own spices. And this is very good that you don't do this because assembling is faster and it's more efficient and more performant and more accessible. I have no idea how to farm my own tomatoes. I know that because I have a plant, it's in my patio, it makes one tomato every month. I would die of starvation if that was my only tomato. And as a society, assembling is really fast for us. It was the whole point of the industrial resolution, got revolution to move from everybody crafting a lot and doing a lot of manual work and sort of assembling more and making it faster and more oriented. And the thing is, the exact same truth for the web. The web is kind of like a society, but on the web, we tend to be more crafting than assembling and that's a little bit weird because that means we're not gonna progress as a society if we don't learn from societies we already have. And the reason why I like this crafters and assemblers metaphor is that web components sit really nicely as a bridge in between these two. If you think about somebody who makes components or elements, they have a lot of institutional knowledge about what makes that element good and all the heavy lifting that you need for that element. Something like paper dialogue requires a lot of really weird knowledge about animations in the CSS spec and what a stacking context is and how you can't just produce one from thin air every time you want that. But on the other hand, while somebody has made you a web component, this enables people to just pick it up and use it and form a really nice experience with it. I can use anybody's custom element. I don't need to know how it works and that's really great because if you take my metaphor from before, this is great. It's advancing the web society as a whole. It's faster to make things and it's more efficient. The CDO of ING said this at last year's Polymer Summit and I really loved it and it stuck with me and he said that what he wants to see in the world is less crafting and more assembling, less people doing things by hand. You shouldn't have to know how to build a table from scratch to have a really nice living room. You shouldn't have to know what a CSS stacking context is to just have a modal dialogue that tells somebody there's a sale on your website. And this is true of every other industry but it's not exactly true for the web. Like in the real world, I can be a crafter if I want to. I can be an assembler if I want to. I get to choose. I don't have to be both at once but a lot on the web we have to both craft and assemble at the same time and that isn't really great. And all of this comes together in design systems. So before web components, when I say a design system, I mean like the elements, with the elements library, the things that your brand should look like, like the colors and the padding and the margins and the visual elements that an app can use. And before web components, having a design system was very craft-oriented. If you look at something like Bootstrap, which is amazing, but Bootstrap was like, somebody crafted you this enormous CSS file that had all these styles and it was great but even putting the elements in your page was a little bit hand-healthy. For example, this is a brand nav bar that you could have in your application and I took this from the Bootstrap site. But imagine that at some point, your brand changes. Maybe you need to have like that container fluid class needs to go away. What do you do then? You have to literally go in all of this DOM you produce and start deleting code or adding code. And that doesn't feel a lot like assembling to me. And of course we know this, web components came and they fixed this because now we have a custom element that abstracts all of this like garbage that we don't actually care about that somebody else built for us because the only thing you care about in this element is just that image. So that's good. But the thing is, this story only works if we have tools around this. The story only works if, you know, like Bootstrap, we have a catalog of elements. We know as a developer, like all of these things that are available to me and that I don't have to reinvent them from scratch that somebody already made, you know, the perfect kind of blue button that I'm allowed to use. So we made webcomponents.org, which you know very well. It's a public catalog of webcomponents and everybody can upload their components and it's got demos and it's got docs and the world was good and we were happy. Only we weren't super happy because it turns out that didn't work for everyone. There's a lot of companies like EA, like Comcast that are really sold into webcomponents and use webcomponents a lot, but their webcomponents aren't public. They can't use webcomponents.org because they can't publish their elements. They develop them internally. So as a result, every one of these companies basically built their own catalog. They could have forked webcomponents.org, but webcomponents.org solves a different problem, which is how do we let people upload arbitrary components and that isn't the problem that companies with private elements have. They just want to display this fairly limited set of elements they have. And the problem here is that there's no such thing as a one-size-fits-all. Steve told you this morning when he was talking about elements and it's true for apps and solutions. At best, you have something that works in the 80% case. 80% of developers probably want to upload a public web component, but in the 20% case, it's all edgy and weird and you have to do something different. And it's usually a more simpler and assemblier solution. So in this case, I build indie elements catalog, which it's fairly ugly. It's not amazing, but it's also a very specific problem. You have a JSON file and in it, you specify what kind of elements you want to load docs and demos for. And these can be Polymer 1 elements or Polymer 2 elements or just vanilla custom elements. They can be anything you want and the code is there for you to do this. And if this doesn't work for you, which is fine, you can fork it, you can clone it, you can fix it to make it work with your workflow and then it's good. And the world was good again. Well, it really wasn't. We again solved another 80% of a bigger problem and left 20% off. It's really great that, you know, now your developers know what elements are available for them, but they also need to know how they fit together. Because in an organization with real workflows and real people, you need to be able to validate your prototypes against code that you actually have, not code that you think you might have. And most of my examples when I give talks are from Chrome, from Chrome the browser, because I used to work on it and I know the developers and the workflows. And this is a page from Chrome Settings. And the way the Chrome Settings page gets designed is first, we give it to a designer, Alan Betz. He's a fantastic human being. And he designs all of these workflows in Sketch. He calls these sticker sheets because he basically has stickers of all the material elements that he would like to use or is allowed to use according to material design rules. And then he assembles them together and figures out the screens. And for each particular screen, he does a whole bunch of iterations. Should the bottom be on the left? Should it be on the right? Should the text be centered?  But the thing is, real elements have bugs and have problems. They have implementation limitations. And I know this because I wrote those elements. So a lot of the times Alan would be like, this toggle button needs to be 16 pixels. And the developer will be, it only works at 18 pixels because Monica didn't make it a resizable. Which is annoying because this means that the prototype that somebody made cannot actually be implemented.  You hope that the prototype that you get from the designer, you actually get to see in real life. There's no guarantee about it. And it's nobody's fault that there's no guarantee. It's just not everything works like it is on paper. Because instead of what you need is a common ground or a tool that is a common ground between developers and designers so they can look at the same elements and improve that workflow. Which is what you see is what you get, a whizzy wig. And something like this has been a long time dream of many of the Polymer team members. We had this in 0.5 and it was called Designer. It was really awesome. And Justin is the visionary on our team.  It was gonna let you do the UI and it was gonna let you do the JavaScript and all the data bindings.  And literally from using that app what you would see is what you would get. But he's always dreaming up really big ideas like the Polymer CLI and lit HTML which you'll see tomorrow. So he's never actually finished this. But lucky for you, I have incredibly small ideas and very little patience. So I had two free weeks and basically stole his milkshake and build this other thing. Which is more like a getting started tool. It gives you the ability to create something like a prototype but not a full blown app. It doesn't work super well all the time but it helps you get started. Because what you do is you deserve Justin's tool but we don't have it yet. So instead you get a WYSIWYD which is like a shittier version of that. And I'm gonna show it to you. Maybe, okay. So I really, really, really hate live demos and I'm really, really nervous about it.  Okay, so this is WYSIWYD. You can, oh, I just got a screensaver. It's going well. Okay, it's in polymerlabs.github.io slash WYSIWYD. The code should be open sourced very soon. It's kind of terrible but you'll live. So here's what the app does. It has a couple of panes and one of the things that it lets you is you can select some elements and drag them in. So I can do something like a div which is a native element. I can resize it. I can move it. I can change some of its styles so I can make a background color. And if you see over here, it has properties. I'm gonna zoom in. So it's got like a class list, hidden, and title. There's also things like custom elements. So for example, I can find God, a good one, paper input. Paper input is my favorite. And when I add it, paper input has different kinds of properties because we actually crawl the prototype chain so that we look at what properties or attributes your custom element has. So in this case, you can see that I have something like value and labeled and disabled and the pattern and all that goodness that comes with paper input. And you can change them. You can change styles. Flex is just the collection of the flex attributes that you might use. And once you're satisfied with the code that you've been producing, there's a code tab where you actually get the code for this element. It's got two imports, the Polymer element and paper input, which makes sense. Let me zoom in. And then as you scroll, it basically gives you an index.html that has both the element definition and the declaration at once. So we have our app and then the DOM module for that app. And you can see that it's got all the styles like I added a div, I added a paper input and here they are in my template. And then it has the element definition at the bottom. You can also see a live preview of it, which is where we actually render the code because I don't trust that designer pane, so I give you this. And because this code isn't editable, because again, that would be a very complicated app and then I would have to like re-render everything. There's also an option to pop this out into a JS Fiddle where it's a conference Wi-Fi is amazing. There it is and it's your paper input and it does all the things. And you can from here on start adding logic or JavaScript or whatever you want. Cool. So let's build a thing. Let's delete all the things first and then build a thing. What I'm going to try to build, again, thoughts and prayers, is a YouTube app where basically I'm gonna bang on a paper input and then get a whole bunch of YouTube videos related to that input. And in particular, they're gonna be related to cats because why not? Let me see how I'm doing for time. Okay. So one of the tabs that I didn't show you over here is the Samples tab. And these are basically combinations of elements that I've added because I really don't like rebuilding the same thing over and over again. And again, this is the kind of app that you would be able to clone and fork and take home and you could add your own samples for whatever team you have or your particular workflow. So in this case, I'm going to start with a header sample, which is basically an app header with a toolbar in it and it has a div. And over here, I'm gonna rename my div to meow tube and put some emoji in there. You can tell that I've practiced this. Let's put a television too. Sweet. So that's it. And now when I save it, it's there. If I preview it, it's there. If I look at the code, I actually have an app header with all of its attributes, a toolbar, and everything else. Cool. So I have my thing and now I wanna render my results. So in here, I'm going to add a DOM repeat because I'm probably going to get a whole bunch of results. Actually, I need an IronAgeX first because we're gonna need to ask YouTube for this. So in my custom elements, IronAgeX, here it is. And IronAgeX has a bunch of things we need to populate. A URL, for example, which I'm going to paste because nobody can remember this unless you're zilling probably.  So here is things like your API key, your query, which in this case, I'm hard coding to cats. Oh, what do you care about? Which is the snippet handle as JSON. So this basically tells IronAgeX that whatever it gets back from the server, it should be a JSON. We wanna set auto to true so that the moment we refresh the page, it actually fetches this. These are just attributes that you can get from the IronAgeX documentation. They're not made up or anything. And last response, I wanna populate an object with this. So here I'm gonna put videos. And what this means is that IronAgeX is going to get a JSON object from the server and then put it in this video's object. This is just a regular Polymer data binding, if you're familiar with data bindings. It's just it. It's exactly how you would write it. Cool. So now I have my IronAgeX, it's set up. And then I'm gonna create my DOM repeat. And this is where everything can go south. So, DOM repeat, here we go. I have it. I'm gonna drag it in. It's hanging out. It doesn't look like anything. I also have a paper card sample which basically has an image and a link in it. And I'm gonna move it around so that it goes into my DOM repeat. So there's these arrows here because sometimes dragging and dropping is infuriating. So if you don't wanna do that, you can just traverse the tree. Speaking of the tree, here on the left-hand side, I haven't shown you this yet, it's basically all of the elements in your app so that you can see the hierarchy and you can click on them and select them because again, dragging and dropping is infuriating. And I know this because I built this and it was just rage. Okay, we have IronAgeX, it's getting data for us. We have a DOM repeat which repeats, stamps the same thing over and over again. So it's gonna stamp one of these paper cards for every result that we have. And we need to tell the DOM repeat to take the elements from IronAgeX. So, IronAgeX was populating an object called videos and because I've memorized this demo, I know that videos actually has a sub-object called items, that's the one I care about. So here, videos.items is what I wanted my DOM repeat. Now the DOM repeat is gonna take every single thing in this object and create an item object. So to this paper card, I can now give my item. So, I have an image. The image should be this thing that I'm gonna paste called item.snipit.thumbnails.hi.url, very memorable. And then for my link, I'm going to change the text content to be, let me zoom in again. Item, ooh, hello. Item.snipit.title. And then for my href, every snippet has a video ID. So it's gonna be item.id.videoid. And now if everything goes well, if I go to the preview, I get nothing, amazing. Something that didn't go well. So let's figure it out. We have our image and we, oh, maybe we don't have data. Let's wait for it for a little bit. Nope. Okay. Pardon me? Oh, way louder and thank you. See, drag and dropping. All right, so let's move this one back and move it into the DOM repeat. Nailed it. Thank you. But I'm honestly kind of surprised at work, I'll be honest. So it looks a little bit terrible because links are, you know, display inline and we don't have an input. So let's do that now that we know our thing it works. So first of all, we're going to change our link to be display inline block so that it's sized correctly. And then because I don't want it to grow so that all my things are still aligned correctly, I can also add extra styles. So the thing that I did in here is that as a lazy developer, I didn't add every single CSS style to this designer because I'd be crazy. So instead I give you the option to just add whatever you want. If you add garbage, nothing's gonna happen because the CSS parser is smart. So in this case, I want an overflow auto and then that'll be great. So I have my DOM repeat, I need my input. So let's add a paper input again in here. And then I'll drag it into here and then move it before the DOM repeat. My paper input is going to have a label and it's gonna say find your meows. And whenever you type it into an input, it has a value property. So I'm going to save that into a query property. Cool, and now all I have to do is give this query to the IronAgeX. So if you move back to IronAgeX, it used to have this parameters object that you know about. And one of the things in here was cats, the query queue. So I'm just gonna add my query here and still keep the cats because it's a meow tube. We only look at cats. Why would you ever want to look at anything else? Now let's just check the code for a second before we run it.  I just like dragged and dropped it and typed into some text fields and that was awesome. And now if I look at the preview and I look for a burrito, I get burrito cats. Here is a wet cat and if I open that video, it should work and it does. Here's your favorite cats, just getting wet and miserable. Ah, that's it. That was my demo. Cool, so this is live. It's polymerlabs.github.io slash withewid. If Elliot didn't forget about me, he'll probably switch it to open source now so you can actually check the code and judge me and complain about it later at the party. And I think I have like one more slide to tell you about if we can switch back to the suite. Oh my God, it worked. Never doing a live demo again till tomorrow.  But the best thing about it is because it's open source and because of how I try to build it, you can take it, you can fork it, you can clone it, you can change it and make it work for you.  Fork this tool and build it into that. Maybe you need a designer where your designers can use four of their UI elements to build things. Please fork it, please build it into that and give it to your team. Maybe you want designers instead of designers instead of designers because why not would you want that, in particular, if your name is Dan Friedman and you get a bigger screen so you can do like nine of them inside of each other, best use of designer ever. Wendy said this morning that her dream was to bring web components to every browser and every developer and I think the way we're gonna really do this is to start thinking more about visual tools. It's not all about your CLIs and your web packs and your gulps and your whatever other tools you use. Sometimes assembling is really visual and we haven't been really good at building visual tools for visual people. So I hope that this at least proves that there's a value to do this, that it's kind of exciting to build this and to use this and it takes it a little bit closer because we're now a little bit closer to just assembling more things and crafting less. Thank you. Awesome job. So happy end of day one, Polymer. Thanks everyone for coming. Thanks to our live stream attendees for joining us. Got a full day tomorrow, starting at 10 a.m. I got some announcements for our in-person attendees now. Just a bullet list was getting longer and longer. I memorized the points until there were 20 of them. Okay, so we've got a party going on in a little bit so stick around. We have a fun after party with dinner drinks and a DJ. There are both non-alcoholic drinks, non-alcoholic drinks, drink responsibly. And don't forget the community guidelines that are posted around the venue. On a similar note, before you get started on the party, have a plan for how you're getting home or wherever. If you need help figuring out how to get a taxi, you can talk to any of the staff members that are wearing the pink shirts and they'll help you with that stuff. Let's see, coat check, be open until the end of the night. Tomorrow morning, we've got breakfast starting at 8 a.m. There's also starting at 9 a.m. You may attend the Polymer Women's Breakfast and that'll feature a panel discussion with Wendy Ginsburg, Mariko Kosaka and Monica Dinkulescu. Sessions tomorrow start at 10 a.m. sharp and finally, oh, anyone that attended the code labs, some of you may have noticed that we might be rate limited on the GitHub API with all those Polymer init calls. I think that has to do with our IP locality. If you are encountering that issue, you can go to the Polymer elements. So let me just read this verbatim instead of paraphrasing. If you are running into this issue when running Polymer init, you can instead just press the download zip button in the Polymer starter kit repository from the Polymer elements org. Okay, thank you so much, see you at the party. Party!


For those familiar with the workshop from Moodle already, there have been quite a lot of changes which you'll find very interesting. For those not so familiar, it's best to quickly explain what the workshop is. A Moodle workshop is a peer assessment activity with many, many options. It allows participants to submit and assess each other's projects in a number of ways. It also coordinates the collection and distribution of these assessments. Now although in Moodle 1.9 it is disabled by default, it did work but it just wasn't so simple to use. So what about workshop in Moodle 2? Well that's a really good question. The usage of the workshop in Moodle 2 is controlled by what stage it is in. That there are five stages. There's a setup phase, submission, assessment, grading and evaluation and closed. Now during setup, the workshop is viewable but is unusable by students in this phase. In the submission phase, students can see the instructions and can submit their assignments. And teachers, they can allocate the submissions for peer review if that's needed. The assessment phase is what it says. During this phase, students assess the assignments assigned to them. The fourth phase is a teacher only phase and teachers review the assignments and the students assessments and then they can calculate and override any of the grades provided. Now once this is all complete, the workshop is closed and grades go into the grade book. Before I take you through an example workshop, I should point out the three useful features of the workshop. And of which in the example we'll just use one. So the three are, one, use examples. Teachers can add examples and users can practice evaluating on the example submissions. Two, using peer assessment. This is where users can perform peer assessment of others' work. And three, the use of self-assessment. That users can perform self-assessment of their own work. In our example, we are just going to use peer assessment. Let's have a look at an example workshop very similar to the one on the Moodle 2 QA side. So first let's look from a student's point of view. Here we have the workshop. We can see the various phases and we can see what the instructions are. But as of yet, we can't actually add anything. So now for the teacher off-screen, I go and I start the next phase. Back on here, let's just reload the page. And you can now see that I can start submitting. So let's edit our submission because we haven't submitted anything yet. Okay, so there we have our limberk. And if I can scroll down here, I have the option to add attachments to it. But in this case I won't be so I'll just click save. Let's go back out to the exercise. And here you can see we're now in submission phase. My work has been submitted and here it is. Now that I've submitted that, as a student I will need to wait until the assignment is given to somebody else for peer review. And the phase is changed to assessment phase so I can also peer review someone. So now that I've reloaded, I can see that the teacher has given me an assignment to assess. So let's click on assess. So this is the limberk that was submitted. And these are the criteria which I have to assess it against. So let's just choose three of them randomly. And as you see I can save and continue editing or save and close. So let's close. At this point, all that is left for me to do is to wait for my grade. So once all the students have done their assessment and the teacher then has gone through phase four of grade evaluation, giving feedback to both the submitter and the assessor, the teacher then closes the workshop and the grade appears. So if we go back out to the course here, we can see now that within the actual workshop it is closed. And go back out and have a look at the grades. And we can see here that my limberk exercise got 80 and got 20 because it was a brilliant poem. And so that's really it from the student point of view. So let's have a look at this from the teacher's point of view. Now bypassing the creation and the assessment form and all that stuff, here we have the assessment ready to roll. Now to enable submissions, the teacher just clicks here to switch the phase into the submission phase. Now once confirmed, the students can now submit. And now that I see items are submitted, we can see down here from Barry and from Joe, the next thing I need to do is to allocate those submissions. So I click on allocate submissions. And for Barry I'm going to set Joe to be his reviewer. So let's just do that. And for Joe, let's set Barry. And so now both have been successfully allocated. We can go back out to the exercise. So at this point I need to move it to the assessment phase so the students can actually do the assessment. So let's click on assessment phase and confirm that. And now in here you can see the unallocated results while we wait for assessment. Now that the students have assessed, what I'm going to do is I'm just going to reload this page so we can see the assessments. So now we can see down here there has been an assessment. One was a 0, one was a 80. So let's move into the grading and evaluation phase. This is the phase where a teacher can come down here and make decisions on each of the submissions and the assessments. I'm going to have a look at the entry, look at the score and the feedback, or look at the actual reviewer and see what they did. So you've got a 5 here, all matching correctly, yes, and give some feedback. So great, fair feedback. Now once the teacher has checked all of the entries, then the teacher has just to recalculate the grades if they've made any changes. And at this point they can close. Now what happens when it closes? Well the key thing is that here it pushes the calculated grades into the grade book. And then the workshops can see their work and any of the assessment. And so that's it from the teacher point of view. So there we have it, the new workshop activity in Moodle 2. Quasi a lot in there and I'm sure this activity will be heavily used. Don't forget to check out my YouTube channel for more review videos.