buildpolymer-2.xpolymer-cli

How to use Polymer 2 Build Process?


I know this might be a duplicate of this question but there was no clear answer ever.

Polymer 2 Framework has a quite good documentation so far but when it comes to the build process there`s not enough explanation.

I've successfully created my own element, also with external scripts referenced and everything runs fine with

polymer serve --open

But I've spent so much time to get this built and to include the output into a minimal HTML template without success. Is it really that tricky?

I`ve even tried again with the empty element template, no chance. This template has a nearly blank polymer.json:

{
    "lint": {
        "rules": [
            "polymer-2"
        ]
    }
}

If I build that right away with

polymer build 

(should use default build behaviour) then I get a default build folder with an index.html and bower_components folder. There`s no reference to my created custom element ("Hello ...").

What do I have to do to get a final build of this "Hello Something" template and include it into a minimum html page?


Solution

  • There are a lot of different ways to go from single component to app with that single component, and I'm not going to say 100% that this is the best, but it should work. "What do I have to do to get a final build of this "Hello Something" template and include it into a minimum html page?", is a pretty flexible request, so even in the below there could be lots of alternatives for you, but the following would be my suggestion. We'll start in the command line, from the Desktop or a folder where you keep you projects.

    mkdir minimal-html-page
    cd minimal-html-page
    polymer init
    // here make sure you choose `polymer-2-application` other questions re of little consequence in this specific use case
    bower install {yourComponent} --save
    // in that case that you haven't published to github, copy and paste also works. Paste into the `src` directory if that's the case.
    atom .
    // or whatever editor you prefer
    

    Now you're in your project, and there is just one change needed to get you going.

    index.html

    Change the current HTML import

    <link rel="import" href="/src/build-test-app/build-test-app.html">
    

    to link to your component.


    At this point you should be free to use polymer build to have the project built, then it'll structure your code to be deployed in other applications via something that will look like

    <script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
    
    <link rel="import" href="/src/build-test-app/build-test-app.html">
    <build-test-app></build-test-app>
    

    This is the most basic of builds and won't account for any x-browser or performance goals you might have in your project. You'll also see in the build/default directory all the files you'd need to copy/paste to use the component elsewhere.


    If you do have x-browser expectations, you can solve them fairly easily by using the polymer build --compile command. This will create slightly more complex embed code to manage either side of the ES5/6 capability boundary and will look something like:

    <script>!function(e){var r=e.babelHelpers={};r.typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r.classCallCheck=function(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")},r.createClass=function(){function e(e,r){for(var t=0;t<r.length;t++){var n=r[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(r,t,n){return t&&e(r.prototype,t),n&&e(r,n),r}}(),r.defineEnumerableProperties=function(e,r){for(var t in r){var n=r[t];n.configurable=n.enumerable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,t,n)}return e},r.defaults=function(e,r){for(var t=Object.getOwnPropertyNames(r),n=0;n<t.length;n++){var o=t[n],i=Object.getOwnPropertyDescriptor(r,o);i&&i.configurable&&void 0===e[o]&&Object.defineProperty(e,o,i)}return e},r.defineProperty=function(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e},r.extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},r.get=function e(r,t,n){null===r&&(r=Function.prototype);var o=Object.getOwnPropertyDescriptor(r,t);if(void 0===o){var i=Object.getPrototypeOf(r);return null===i?void 0:e(i,t,n)}if("value"in o)return o.value;var a=o.get;if(void 0!==a)return a.call(n)},r.inherits=function(e,r){if("function"!=typeof r&&null!==r)throw new TypeError("Super expression must either be null or a function, not "+typeof r);e.prototype=Object.create(r&&r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),r&&(Object.setPrototypeOf?Object.setPrototypeOf(e,r):e.__proto__=r)},r.instanceof=function(e,r){return null!=r&&"undefined"!=typeof Symbol&&r[Symbol.hasInstance]?r[Symbol.hasInstance](e):e instanceof r},r.newArrowCheck=function(e,r){if(e!==r)throw new TypeError("Cannot instantiate an arrow function")},r.objectDestructuringEmpty=function(e){if(null==e)throw new TypeError("Cannot destructure undefined")},r.objectWithoutProperties=function(e,r){var t={};for(var n in e)r.indexOf(n)>=0||Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t},r.possibleConstructorReturn=function(e,r){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!r||"object"!=typeof r&&"function"!=typeof r?e:r},r.set=function e(r,t,n,o){var i=Object.getOwnPropertyDescriptor(r,t);if(void 0===i){var a=Object.getPrototypeOf(r);null!==a&&e(a,t,n,o)}else if("value"in i&&i.writable)i.value=n;else{var u=i.set;void 0!==u&&u.call(o,n)}return n},r.slicedToArray=function(){function e(e,r){var t=[],n=!0,o=!1,i=void 0;try{for(var a,u=e[Symbol.iterator]();!(n=(a=u.next()).done)&&(t.push(a.value),!r||t.length!==r);n=!0);}catch(e){o=!0,i=e}finally{try{!n&&u.return&&u.return()}finally{if(o)throw i}}return t}return function(r,t){if(Array.isArray(r))return r;if(Symbol.iterator in Object(r))return e(r,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r.taggedTemplateLiteral=function(e,r){return Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(r)}}))},r.temporalRef=function(e,r,t){if(e===t)throw new ReferenceError(r+" is not defined - temporal dead zone");return e},r.temporalUndefined={},r.toArray=function(e){return Array.isArray(e)?e:Array.from(e)},r.toConsumableArray=function(e){if(Array.isArray(e)){for(var r=0,t=Array(e.length);r<e.length;r++)t[r]=e[r];return t}return Array.from(e)}}("undefined"==typeof global?self:global);</script>
    
    
    <script>if (!window.customElements) { document.write('<!--'); }</script>
        <script type="text/javascript" src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
        <!--! do not remove -->
    <script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
    
    <link rel="import" href="/src/build-test-app/build-test-app.html">
    <build-test-app></build-test-app>
    

    The <!--! do not remove --> part is super not kidding and it integral to making sure the compiled code works in ES6 environments.


    Beyond that, there is a whole world of things that you can do to tune this up for production deployment. I'd research https://www.polymer-project.org/2.0/docs/tools/polymer-cli-commands#build and https://www.polymer-project.org/2.0/docs/tools/polymer-json to get a better handle on that.