Building Polymer apps with gulp

Once you outgrow polymer-cli, there is lots of boilerplate code required in your gulp build. Here is our best practice.

Ronny Roeller
NEXT Engineering
3 min readAug 10, 2017

--

The polymer-cli provides great out-of-the-box functionality to build Polymer apps. Configure your polymer.json, type polymer build, and you are done! Unfortunately, we have been outgrowing polymer-cli even for the simplest of our projects: Add CSP compliance? Add cache busting? Inject the Git rev number? Do anything else custom? Bad luck. Not possible with polymer-cli.

The Polymer documentation advises to use gulp and polymer-build once polymer-cli becomes insufficient for the project’s needs. Yet, there is quite some nice functionality in polymer-cli that needs to be replicated — and maintained — when doing this step. For example: compile to ES5, minification, build presets, polymer.json config for those steps, etc. All provided by polymer-cli but not in polymer-build. We did raise an issue with the polymer-cli team to expose these great features to the gulp world.

But until that ticket is implemented, here is our best practice build process! To ease reusage, we open sourced all the generic bits as gulp-polymer-build-utils.

Build 101

First, install the gulp plugin for the polymer-build-utils:

npm install gulp-polymer-build-utils --save-dev

Now, your gulpfile.js can be as simple as:

const del = require('del');
const gulp = require('gulp');
const polymerBuildUtils = require('gulp-polymer-build-utils');
const runSequence = require('run-sequence');
gulp.task('default', cb => {
return runSequence('dist:prepare', 'inline-references', cb);
});
gulp.task('dist:prepare', ['dist:clean'], () => {
const config = require('./polymer.json');
return polymerBuildUtils.build(config)()
.pipe(gulp.dest('dist'));
});
gulp.task('dist:clean', () => del('dist'));

polymerBuildUtils.build() triggers various build steps:

  • Trigger polymer-build itself
  • Add CSP compliance (split JavaScript from the HTML)
  • Add cache busting, so you can aggressively cache the generated artifacts
  • Optimize the created assets, e.g. convert ES6 to ES5, minify HTML and CSS
  • Inject the custom-elements-es5-adapter to make your (now) ES5 app work also in modern browsers

If you want to execute only some of the steps, just call them individually instead of the complete integrated build (see reference).

Finally, the inline-reference task inlines the built artifacts into your index.html to minimize the number of backend requests on load.

To start the build, type gulp on the command line from your project root directory. This will build your app in the dist/ folder.

Local testing

Running your tests on the distribution version of your code (e.g. ES5 code) is certainly a good idea because that’s what your users will see as well.

The web-component-tester allows you to easily install the wct:local task. wct:local is great for Continuous Integration testing but we found it too limited for testing during development/bug fixing, e.g.:

  • Limit the browsers on which the tests should run: you normally don’t want to run the tests in dozens of browsers while reproducing a bug locally
  • Limit the to-be-executed test suites: Web component tests take their time. Hence, you likely only want to re-run the failing tests while fixing them.
  • Keep the browser open: You don’t want to auto-close the browser when trying to debug why a test is failing.

For those scenarios, we added another plugin that allows configuring these settings via the command line:

const del = require('del');
const gulp = require('gulp');
const polymerBuildUtils = require('gulp-polymer-build-utils');
const runSequence = require('run-sequence');
const yargs = require('yargs');
const argv = polymerBuildUtils.addYargs(yargs).help().argv;gulp.task('dist:clean', () => del('dist'));gulp.task('dist:prepare', ['dist:clean'], () => {
const config = require('./polymer.json');
return polymerBuildUtils.build(config)()
.pipe(gulp.dest('dist'));
});
gulp.task('default', cb => {
return runSequence('dist:prepare', 'inline-references', cb);
});
gulp.task('dist:test', function() {
return polymerBuildUtils.runWct(argv);
});

Now, you can start e.g. your tests in debug mode on Chrome and Firefox:

gulp dist:test --browser chrome --browser firefox --debug

Hint: Run gulp --help to learn more about all command line options.

Happy building!

Want to learn more about Polymer? Have a look to all our Medium posts on Polymer.

--

--

Ronny Roeller
NEXT Engineering

CTO at nextapp.co # Product discovery platform for high performing teams that bring their customers into every decision