Slide 1

Slide 1 text

Images: Dreamstime.

Slide 2

Slide 2 text

Today we’ll take an in-depth look at Polymer tooling. We’ll cover tools for creating elements & apps, setting up a build process, keeping your projects lean and a few new tools for improving your developer productivity.

Slide 3

Slide 3 text

https://goo.gl/lqZyhu Images: Dreamstime.

Slide 4

Slide 4 text

But..before that, a quick story. A few weeks ago I was visiting Japan. A place that’s really big on automation - the idea of solving repetitive tasks with tools & systems. They’ve really taken this concept to a whole other level. One example of this is the idea of parking a bike.

Slide 5

Slide 5 text

https://www.flickr.com/photos/szipiszopi/5159559474/

Slide 6

Slide 6 text

Now, Polymer Summit being in Amsterdam, you may be familiar with the number of bikes here. There are many. Statistically speaking, I’m pretty sure every person in Amsterdam owns 3 million bikes. Parking bikes is a hard problem.

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Japan has solved this problem using the ECO Cycle - an automated system that has a giant robotic arm that pulls down your bike and parks it for you underground. If this is the first time you’ve seen that, you’re probably wondering.. what type of crazy Matrix sorcery is this?!. This is automation saving us time. Why is automation important for webapp developers?

Slide 9

Slide 9 text

If you want to be fast, you have to give up the things keeping you slow.

Slide 10

Slide 10 text

Obviously, we can’t automate everything. If we did we would be out of a job. Japan has struck a balance between automation and where manual craftsmanship still has its place. At my hotel, they would include a paper crane with meals. Someone manually crafted this origami each time rather than automating it with a machine.

Slide 11

Slide 11 text

https://goo.gl/lqZyhu Images: Dreamstime.

Slide 12

Slide 12 text

Paper cranes look pretty graceful.

Slide 13

Slide 13 text

https://goo.gl/lqZyhu Images: Dreamstime, Addy Osmani.

Slide 14

Slide 14 text

I thought..Hey, I can JavaScript. Surely folding paper can’t be all that hard. I’m going to make a paper crane! And, well. The TL;DR is that I’m no longer allowed back in Japan.

Slide 15

Slide 15 text

https://goo.gl/lqZyhu

Slide 16

Slide 16 text

Where are the tools for our declarative shift? 3,427,000 tools HTML Getting better!

Slide 17

Slide 17 text

The JavaScript tooling ecosystem has a huge number of existing tools available. If you’ve used Polymer & Web Components a while, you may have run into few places where running these tools against HTML can be tricky. Things like linting. Good news is that tooling for these problems is getting better.

Slide 18

Slide 18 text

Build Test Lint Serve CSP CDN 127.0.0.1 git > The New Polymer Toolbox¬ Images: Dreamstime.

Slide 19

Slide 19 text

Let’s walk through tools for: Writing Reusable elements Automatically porting elements to Polymer 1.0 Unit Testing elements Adding elements to apps Productionising apps ~ Vulcanize, Crisper, PolyBuild, PolyLint, PolyGit (CDN) Bonus tools for your workflow

Slide 20

Slide 20 text

Tool Requirements¬ Windows / Mac / Linux

Slide 21

Slide 21 text

https://goo.gl/lqZyhu Images: NPM, Node foundation, Bower.

Slide 22

Slide 22 text

Writing Reusable Elements¬ Elements we can share. Images: Dreamstime.

Slide 23

Slide 23 text

¬ Seed for new Polymer elements github.com/polymerlabs/seed-element

Slide 24

Slide 24 text

/demo /test seed-element.html index.html hero.svg bower.json README.md

Slide 25

Slide 25 text

Slide 26

Slide 26 text

demo/index.html Your demo

Slide 27

Slide 27 text

... Polymer({ is: 'seed-element', properties: { <seed-element> seed-element.html Your element Images:JSConf

Slide 28

Slide 28 text

https://github.com/addyosmani/emoji-text

Slide 29

Slide 29 text

https://github.com/addyosmani/emoji-text

Slide 30

Slide 30 text

:host { display: block; }
Polymer({ is: 'emoji-text', properties: { text: { type: 'String', notify: true, observer: '_textChanged' } }, _textChanged: function() { ... } textToEmoji: function() { ... } }); seed-element.html > emoji-text.html Images: Polymer

Slide 31

Slide 31 text

$  npm  install  -­‐g  bower   $  bower  install   > Before we forget, install our dependencies

Slide 32

Slide 32 text

PolyServe¬ Serving elements to a browser. 127.0.0.1 github.com/polymerlabs/polyserve Images: Dreamstime, Addy Osmani.

Slide 33

Slide 33 text

$  npm  install  -­‐g  polyserve   $  cd  seed-­‐element   $  polyserve   Starting  Polyserve  on  port  8000     Serving  components  from  bower_components > Simple server for using components locally $  polyserve  -­‐p  9999 > Customise port number

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

#  Navigate  back  to  your  development  directory   $  cd  ..   #  git  clone  the  Polymer  tools  repository   $  git  clone  git://github.com/Polymer/tools.git   #  Create  a  temporary  directory  for  publishing  your  element  and  cd  into  it   $  mkdir  temp  &&  cd  temp   #  Run  the  gp.sh  script.   $  ../tools/bin/gp.sh    emoji-­‐text   #  Finally,  clean-­‐up  your  temporary  directory  as  you  no  longer  require  it   $  cd  ..   $  rm  -­‐rf  temp > Deploy? Publish to GitHub pages with gp.sh

Slide 37

Slide 37 text

PolyUp¬ Automate levelling up 0.5 > 1.0 github.com/polymerlabs/polyup Images: Dreamstime, Polymer.

Slide 38

Slide 38 text

:host { display: block; }
Polymer({ textToEmoji: function(str) { }, _showOriginalText: function() { }, … }); 0.5

Slide 39

Slide 39 text

$  npm  install  -­‐g  polyup   $  polyup  emoji-­‐text.html > Automate your upgrades Polymer 0.5>

Slide 40

Slide 40 text

HTML Transformations

Slide 41

Slide 41 text

:host { display: block; }
Polymer({ is: 'emoji-text', properties: { text: { notify: true } }, textToEmoji: function(str) { }, _showOriginalText: function() { }, ... }); 1.0

Slide 42

Slide 42 text

$  find  .  -­‐name  "*.html"  -­‐execdir  polyup   -­‐-­‐overwrite  "{}"  \;   > PRO-TIP. Recursive upgrades! WIN

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Unit Testing Elements¬ Verifying elements are legit. Images: Dreamstime.

Slide 45

Slide 45 text

Web Component Tester¬ Unit testing for Elements github.com/polymer/web-component-tester

Slide 46

Slide 46 text

$  npm  install  -­‐g  web-­‐component-­‐tester   $  wct > Test your Web Components Images: Mocha & Chai projects.

Slide 47

Slide 47 text

// Load and run all tests (.html, .js): WCT.loadSuites([ 'basic-test.html' ]); test/index.html

Slide 48

Slide 48 text

suite('emoji-text tests', function() { var emojiText = document.querySelector(‘emoji-text’); test('Defines the "text" property', function() { assert.equal(emojiText.text, 'top gun'); }); test('Converts text to emoji', function() { emojiText.textToEmoji(); assert.include(emojiText.innerHTML, ''); assert.include(emojiText.innerHTML, ''); }); }); test/basic-test.html

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

$  wct  -­‐l  chrome > only run tests in chrome $  wct  -­‐p > keep browsers alive after test runs $  wct  test/some-­‐file.html > test only the files you specify Testing #protips

Slide 51

Slide 51 text

Adding Elements To Apps¬ Using Polymer Starter Kit Images: Dreamstime.

Slide 52

Slide 52 text

Polymer Starter Kit Images: Polymer.

Slide 53

Slide 53 text

thestocks.im first-class components end-to-end build process application theming responsive app layout offline-first (optional) 67K DOWNLOADS

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

Let’s walk through building a quick app that builds on the element. Something that clearly has a niche in the market.

Slide 58

Slide 58 text

Emoji Quiz App¬

Slide 59

Slide 59 text

... Submit Answer ... Images: EmojiLib

Slide 60

Slide 60 text

ready: function() { this.items = [ 'princess diaries', 'back to the future', 'sound of music', 'ghost ship', 'china town', 'evil dead', 'money ball']; } Images: EmojiLib

Slide 61

Slide 61 text

Slide 62

Slide 62 text

https://goo.gl/lqZyhu Make BUILD TOOLS & TASK RUNNERS Images: Grunt, Gulp, NPM, Fotosearch.

Slide 63

Slide 63 text

$  npm  install  —g  gulp  bower  &&  npm  install  &&  bower  install   > Install tooling & PSK dependencies Node 0.12+

Slide 64

Slide 64 text

ALL THE INTERNET NPM INSTALL Images: Allie Brosh

Slide 65

Slide 65 text

$  gulp  serve > Serve our application

Slide 66

Slide 66 text

Images: Addy Osmani, EmojiLib

Slide 67

Slide 67 text

Images: Addy Osmani, EmojiLib

Slide 68

Slide 68 text

Images: Addy Osmani, EmojiLib

Slide 69

Slide 69 text

CSS IS AWESOME CUSTOM PROPERTIES MAKE IT BETTER.

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

:root { --dark-primary-color: #388E3C; --default-primary-color: #4CAF50; --light-primary-color: #C8E6C9; --text-primary-color: #FFFFFF; --accent-color: #CDDC39;

Slide 72

Slide 72 text

Production-ising Apps¬ Polymer Build Tools Images: Dreamstime.

Slide 73

Slide 73 text

A build process is a promise to your users.

Slide 74

Slide 74 text

build process Images: Addy Osmani, Hannah Lee, Gulp

Slide 75

Slide 75 text

Vulcanize Crisper PolyBuild PolyLint PolyGit

Slide 76

Slide 76 text

Vulcanize¬ Concatenate Imports for Production github.com/polymer/vulcanize Images: https://www.flickr.com/photos/ssoosay/16771481611/.

Slide 77

Slide 77 text

$  npm  install  -­‐g  vulcanize   $  vulcanize  emoji-­‐app.html  >  build.html   > Reduce an app & its dependents into one file.

Slide 78

Slide 78 text

$  vulcanize  -­‐-­‐inline-­‐scripts  emoji-­‐app.html     > Inline scripts and Imports > Inline Polymerized stylesheets $  vulcanize  -­‐-­‐inline-­‐css  emoji-­‐app.html

Slide 79

Slide 79 text

Crisper¬ Make HTML files CSP compliant github.com/polymerlabs/crisper Images: Dreamstime

Slide 80

Slide 80 text

$  npm  install  -­‐g  crisper   $  crisper  -­‐-­‐source  index.html  -­‐-­‐html  build.html  -­‐-­‐js  build.js   > Split inline scripts from HTML for CSP

Slide 81

Slide 81 text

$  vulcanize  index.html  -­‐-­‐inline-­‐script  |  crisper  -­‐-­‐html  build.html   build.js   > Using Vulcanize? Crisper accepts HTML string output directly.

Slide 82

Slide 82 text

PolyBuild¬ Combines Vulcanize, Crisper & Polyclean github.com/polymerlabs/polybuild

Slide 83

Slide 83 text

vulcanize  -­‐-­‐inline-­‐css  -­‐-­‐inline-­‐scripts  -­‐-­‐strip-­‐comments  index.html  |   polyclean  |  crisper  -­‐-­‐html  index.build.html  -­‐-­‐js  index.build.js   Rather than this.. $  npm  install  -­‐g  polybuild   $  polybuild  index.html     Just do this:

Slide 84

Slide 84 text

PolyBuild with Gulp! var gulp = require('gulp'); var polybuild = require('polybuild'); gulp.task('build', function() { return gulp.src('index.html') .pipe(polybuild()) .pipe(gulp.dest('.')); }); Images: Gulp

Slide 85

Slide 85 text

$  polybuild  —maximum-­‐crush  index.html > MAXIMUM CRUSH! JS MINIFIED || whitespace removed https://www.flickr.com/photos/stigster/4574486940/

Slide 86

Slide 86 text

WIP TOOLS

Slide 87

Slide 87 text

PolyLint¬ > Linting for Elements github.com/polymerlabs/polylint Images: Dreamstime

Slide 88

Slide 88 text

$  npm  install  -­‐g  polylint   $  polylint  index.html > Keep your elements clean and functional

Slide 89

Slide 89 text

$ polylint sample/imports/ bind-to-class.html sample/imports/bind-to- class.html:12:5 The expression [[myVars]] bound to the attribute 'class' should use $= instead of =. I love styling with Polymer! I love styling with Polymer!

Slide 90

Slide 90 text

$ polylint sample/imports/bound- variables-declared.html sample/imports/bound-variables- declared.html:12:11 Property myVar not found in 'properties' for element 'bound- variables-declared' [[myVar]]{{myVars}} ✅ Polymer({ is: 'bound-variables-declared', properties: { myVars: { type: String, value: 'Hello linter!' } } });

Slide 91

Slide 91 text

$ polylint sample/imports/computed- binding.html sample/imports/computed- binding.html:13:11 Computed Binding using property 'notAFunction', which is not a function for element'computed- binding' {{notAFunction(myVars)}}[[isAFunction(myVars)]] ✅ Polymer({ is: 'computed-binding', properties: { myVars: { type: String, value: ‘Hey big linter!' } }, isAFunction: function() { return ''; }, notAFunction: 3 });

Slide 92

Slide 92 text

PolyGit¬ A stateless CDN compatible with deduping polygit.org Images: Dreamstime

Slide 93

Slide 93 text

Loading without configuration polygit.org/components//.html Even better with the tag

Slide 94

Slide 94 text

Auto-organisation selection github.com/WebComponents github.com/PolymerElements github.com/GoogleWebComponents

Slide 95

Slide 95 text

Control orgs, branches & versions Default org, specific version: paper-button+v1.0.2 Default org, master branch: polymer+:master Different org, specific component: super-gif+sjmiles+*

Slide 96

Slide 96 text

Bonus Tools¬ Productivity boosters

Slide 97

Slide 97 text

Polymer Ready Extension

Slide 98

Slide 98 text

Polymer is now used in Chrome!

Slide 99

Slide 99 text

New Chrome PDF Viewer

Slide 100

Slide 100 text

New Chrome Downloads page

Slide 101

Slide 101 text

Upcoming Chrome Settings page

Slide 102

Slide 102 text

Sublime & Atom Snippets

Slide 103

Slide 103 text

PolySearch Images: Eiji Kitamura

Slide 104

Slide 104 text

BUILD & EXPERIMENT

Slide 105

Slide 105 text

gravatar-photo.html Polymer({ is: 'gravatar-photo', .. attached: function () { this.url = window.gravatar.url(this.email, { s: this.size }); } }); Polymer + https://github.com/polymerlabs/gravatar-photo var gulp = require("gulp"); var browserify = require("gulp-browserify"); gulp.task("build", function () { gulp.src("gravatar-photo.js") .pipe(browserify()) .pipe(gulp.dest("build")) }); src/gravatar-photo.js window.gravatar = require("gravatar"); gulpfile.js

Slide 106

Slide 106 text

gravatar-photo.html Polymer({ is: 'gravatar-photo', .. attached: function () { this.url = window.gravatar.url(this.email, { s: this.size }); } }); Polymer + https://github.com/polymerlabs/gravatar-photo var gulp = require("gulp"); var browserify = require("gulp-browserify"); gulp.task("build", function () { gulp.src("gravatar-photo.js") .pipe(browserify()) .pipe(gulp.dest("build")) }); src/gravatar-photo.js window.gravatar = require("gravatar"); gulpfile.js

Slide 107

Slide 107 text

gravatar-photo.html Polymer({ is: 'gravatar-photo', .. attached: function () { this.url = window.gravatar.url(this.email, { s: this.size }); } }); Polymer + https://github.com/polymerlabs/gravatar-photo var gulp = require("gulp"); var browserify = require("gulp-browserify"); gulp.task("build", function () { gulp.src("gravatar-photo.js") .pipe(browserify()) .pipe(gulp.dest("build")) }); src/gravatar-photo.js window.gravatar = require("gravatar"); gulpfile.js

Slide 108

Slide 108 text

Future Polymer Designer Polymer DevTools

Slide 109

Slide 109 text

Polymer Starter Kit¬ NEW Recipes: ES6, Perf, CDE Better tooling pipeline Lots of bug fixes!

Slide 110

Slide 110 text

// Transpile all JS to ES5. gulp.task('js', function () { return gulp.src(['app/{elements,scripts}/**/*.{js,html}']) .pipe($.sourcemaps.init()) .pipe($.if('*.html', $.crisper())) // Extract JS from .html files .pipe($.if('*.js', $.babel())) .pipe($.sourcemaps.write('.')) .pipe(gulp.dest('.tmp/')) .pipe(gulp.dest('dist/')); }); ES6 support via { "preset": "google", "esnext": true } Images: BabelJS, JSCS. Optional

Slide 111

Slide 111 text

Support for the new Chrome for Android Splashscreen When a webapp is launched from the Homescreen, this themes the white screen you see until the renderer has something to show.

Slide 112

Slide 112 text

Tool on!¬ With special thanks to our tool makers.

Slide 113

Slide 113 text

Fin.¬ +AddyOsmani @addyosmani