$30 off During Our Annual Pro Sale. View Details »

Polymer Power Tools

Addy Osmani
September 20, 2015

Polymer Power Tools

We'll cover the new tools now available to help you build with Polymer in production including Polymer Starter Kit, Vulcanize, Crisper, Polyup, Polylint, PolyGit, web-component-tester, our docs and code viewer tools and much more!

Video: https://www.youtube.com/watch?v=LMqM4PfrFxs

Presented at Polymer Summit 2015.

Addy Osmani

September 20, 2015
Tweet

More Decks by Addy Osmani

Other Decks in Programming

Transcript

  1. Images: Dreamstime.

    View Slide

  2. 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.

    View Slide

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

    View Slide

  4. 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.

    View Slide

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

    View Slide

  6. 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.

    View Slide

  7. View Slide

  8. 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?

    View Slide

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

    View Slide

  10. 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.

    View Slide

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

    View Slide

  12. Paper cranes look pretty graceful.

    View Slide

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

    View Slide

  14. 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.

    View Slide

  15. https://goo.gl/lqZyhu

    View Slide

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

    View Slide

  17. 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.

    View Slide

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

    View Slide

  19. 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

    View Slide

  20. Tool Requirements¬
    Windows / Mac / Linux

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide


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

    View Slide


  25. src=“../webcomponentsjs/webcomponents-lite.js">

    href=“../iron-component-page/iron-component-page.html">




    View Slide



  26. <br/>







    demo/index.html
    Your demo

    View Slide





  27. ...


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

    View Slide



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

    View Slide



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

    View Slide




  30. :host { display: block; }



    <br/>Polymer({<br/>is: 'emoji-text',<br/>properties: { text: { type: 'String', notify: true, observer: '_textChanged' } },<br/>_textChanged: function() { ... }<br/>textToEmoji: function() { ... }<br/>});<br/>

    seed-element.html > emoji-text.html
    Images: Polymer

    View Slide

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

    View Slide

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

    View Slide

  33. $  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

    View Slide

  34. View Slide

  35. View Slide

  36. #  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

    View Slide

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

    View Slide



  38. :host { display: block; }


    <br/>Polymer({<br/>textToEmoji: function(str) { },<br/>_showOriginalText: function() { },<br/>…<br/>});<br/>


    0.5

    View Slide

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

    View Slide

  40. HTML Transformations



    index-as='{{i}}'>


    View Slide


  41. :host { display: block; }



    <br/>Polymer({<br/>is: 'emoji-text',<br/>properties: {<br/>text: { notify: true }<br/>},<br/>textToEmoji: function(str) { },<br/>_showOriginalText: function() { },<br/>...<br/>});<br/>

    1.0

    View Slide

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

    View Slide

  43. View Slide

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

    View Slide

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

    View Slide

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

    View Slide





  47. <br/>


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


    test/index.html

    View Slide


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

    View Slide

  49. View Slide

  50. $  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

    View Slide

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

    View Slide

  52. Polymer Starter Kit
    Images: Polymer.

    View Slide

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

    View Slide

  54. View Slide

  55. View Slide

  56. View Slide

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

    View Slide

  58. Emoji Quiz App¬

    View Slide



  59. ...


    required
    pattern="{{questionPattern}}"
    value="{{answer}}"
    error-message="OMG NO!"
    label="Enter your answer">


    Submit Answer
    ... Images: EmojiLib

    View Slide


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

    View Slide















  61. View Slide

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

    View Slide

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

    View Slide

  64. ALL THE INTERNET
    NPM INSTALL
    Images: Allie Brosh

    View Slide

  65. $  gulp  serve
    > Serve our application

    View Slide

  66. Images: Addy Osmani, EmojiLib

    View Slide

  67. Images: Addy Osmani, EmojiLib

    View Slide

  68. Images: Addy Osmani, EmojiLib

    View Slide

  69. CSS
    IS
    AWESOME
    CUSTOM PROPERTIES MAKE IT BETTER.

    View Slide

  70. View Slide

  71. <br/>:root {<br/>--dark-primary-color: #388E3C;<br/>--default-primary-color: #4CAF50;<br/>--light-primary-color: #C8E6C9;<br/>--text-primary-color: #FFFFFF;<br/>--accent-color: #CDDC39;<br/>

    View Slide

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

    View Slide

  73. A build process is a
    promise to your users.

    View Slide

  74. build process
    Images: Addy Osmani, Hannah Lee, Gulp

    View Slide

  75. Vulcanize
    Crisper
    PolyBuild
    PolyLint
    PolyGit

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  83. 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:

    View Slide

  84. 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

    View Slide

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

    View Slide

  86. WIP
    TOOLS

    View Slide

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

    View Slide

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

    View Slide

  89. $ 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!


    View Slide

  90. $ 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}}



    <br/>Polymer({<br/>is: 'bound-variables-declared',<br/>properties: {<br/>myVars: {<br/>type: String,<br/>value: 'Hello linter!'<br/>}<br/>}<br/>});<br/>

    View Slide

  91. $ 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)]] ✅


    <br/>Polymer({<br/>is: 'computed-binding',<br/>properties: {<br/>myVars: {<br/>type: String,<br/>value: ‘Hey big linter!'<br/>}<br/>},<br/>isAFunction: function() {<br/>return '';<br/>},<br/>notAFunction: 3<br/>});<br/>

    View Slide

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

    View Slide

  93. Loading without configuration


    polygit.org/components//.html
    Even better with the tag


    View Slide

  94. Auto-organisation selection

    github.com/WebComponents

    github.com/PolymerElements

    github.com/GoogleWebComponents

    View Slide



  95. 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+*

    View Slide

  96. Bonus Tools¬
    Productivity boosters

    View Slide

  97. Polymer Ready Extension

    View Slide

  98. Polymer is now
    used in Chrome!

    View Slide

  99. New Chrome PDF Viewer

    View Slide

  100. New Chrome Downloads page

    View Slide

  101. Upcoming Chrome Settings page

    View Slide

  102. Sublime & Atom Snippets

    View Slide

  103. PolySearch
    Images: Eiji Kitamura

    View Slide

  104. BUILD & EXPERIMENT

    View Slide

  105. gravatar-photo.html






    <br/>Polymer({<br/>is: 'gravatar-photo',<br/>..<br/>attached: function () {<br/>this.url = window.gravatar.url(this.email,<br/>{ s: this.size });<br/>}<br/>});<br/>
    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

    View Slide

  106. gravatar-photo.html






    <br/>Polymer({<br/>is: 'gravatar-photo',<br/>..<br/>attached: function () {<br/>this.url = window.gravatar.url(this.email,<br/>{ s: this.size });<br/>}<br/>});<br/>
    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

    View Slide

  107. gravatar-photo.html






    <br/>Polymer({<br/>is: 'gravatar-photo',<br/>..<br/>attached: function () {<br/>this.url = window.gravatar.url(this.email,<br/>{ s: this.size });<br/>}<br/>});<br/>
    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

    View Slide

  108. Future
    Polymer
    Designer
    Polymer
    DevTools

    View Slide

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

    View Slide

  110. // 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

    View Slide

  111. 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.

    View Slide

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

    View Slide

  113. Fin.¬
    +AddyOsmani
    @addyosmani

    View Slide