Showing posts with label tooling. Show all posts
Showing posts with label tooling. Show all posts

Tuesday, September 12, 2017

Differential Serving on Firebase Hosting (and moving to Medium)

Polymer 2.x/3.x brought the standards-compliant ES6 class-based syntax for defining Web Components. This works well for most modern browsers and ES6 has a lot of other nice features (like arrow functions) to make your JS code cleaner and more fun to write.
But if you need to support older browsers like IE 11 you will have to compile your code to ES5 which comes with performance drawbacks for modern browsers compared to running ES6 on them directly.
The ideal approach is to use differential serving to serve the ES6 version to modern browsers and a fallback ES5 version to older browser. prpl-server-node is a sample implementation of a Node server that uses this pattern. I took the ideas from this implementation and created a sample based on the polymer-starter-kit on how you can use differential serving on Firebase Hosting using Cloud Functions for Firebase for dynamically sending the right version to the user.
Since blogger has started to look quite old I'm currently testing Medium, so you will find the rest of this article there: https://medium.com/@scarygami/differential-serving-on-firebase-hosting-f83c33b83a8e

Thursday, May 4, 2017

Doing more with your Google Location History

With the discontinuation of the Google Latitude API several years ago some nice third party tools to visualize your location history disappeared, which at that time triggered me to look into what can be done with Google Takeout data. The result was the location_history_json_converter (or latitude_json_converter as it was called back then) which thanks to several contributions from the open source community has turned out to be a rather useful and powerful tool to prepare your takeout data for further manipulation and visualization.
Since I've recently used the tool myself again for a travel report (more about this below) and I never actively promoted or explained the tool, I've decided to put together this blog post to tell you about the tool and some samples of what can be done with it.

Wednesday, May 25, 2016

I/O 2016

I/O 2016 is over again already, so it's time to sum up my thoughts about what I/O brought for developers and what announcements/updates you should check out.



Tuesday, January 26, 2016

Polymer in a corporate network

(a.k.a. The Things You Do For Money)


Working as a developer in a non-tech company can be challenging since usually the corporate IT infrastructure and regulations aren't designed for developer tasks but for day-to-day office business. So when I took over some new responsibilities at work and had the chance to finally include Polymer in some internal web projects (with the biggest stopping point of IE8 finally gone) I had some hurdles to overcome to make use of the full Polymer-related tool chain I've come to love for my private projects.

1. Microsoft Windows

The main OS in big corporations (at least in Austria) is still Microsoft Windows and usually you can't just install another OS on company hardware. However, as it turns out, all the tools needed are readily available on Windows, so it might be a unfair to list it among the problems. Consider this part mainly as a summary of what I use for developing with Polymer.

Node.js (with all web development tools being Node-based these days) is pretty well supported across all platforms. It comes with npm as package manager that lets you install other tools you will need like Bower or Gulp.

Git (for fetching Bower dependencies) has a Windows installation that also comes with a bash emulator, that is so much nicer to use than the Windows command prompt.

As for text editors you have a wide variety to choose from, personally I like Sublime Text but have also used Notepad++ quite frequently.

2. Group Policies

Having installation files available for Windows is nice, but you might not actually be allowed to install non-standard applications on your PC thanks to all settings and permissions being managed through Active Directory and Group Policies. If you are nice to your local IT department they might make an exception and give you local administrator rights or install custom applications for you, and luckily I have a very nice local IT department ;)

But in many cases not even the local IT department can help you, depending themselves on a global team that manages all permissions, and then you will have to start looking at portable solutions that you can simply put anywhere you want without having to install anything.

Here's one possible approach to put your whole development environment on an USB stick.
  1. Download the latest version of PortableGit and "install" = extract it to any location you want.
  2. Create a usr/local/bin folder in the same location
  3. Download the latest node.exe (from win-x64 or win-x86), which is all that Node.js needs to run, and put it in usr/local/bin folder you just created.
  4. Download the latest npm release and extract it into usr/local/bin/node_modules/npm/
  5. Copy npm and npm.cmd from usr/local/bin/node_modules/npm/bin/ to usr/local/bin
Your final folder structure should look something like this:


When you run git-bash now you can already use npm to install Bower and any other node modules you may want to use with npm install -g bower

With the default settings PortableGit still has some issues though, the biggest one being that it is not truly portable with some global config settings being written to $HOME which defaults to C:/Users/YourUser

To solve this issue you will need to create a /home/YourUser folder in your PortableGit location. To prevent messing around with the default config scripts (which will be overwritten when updating PortableGit) you can create a batch file to temporarily (so we don't mess up other applications that need the %HOME% environment variable) set HOME to that folder before starting git-bash.

setlocal
set HOME=%~dp0home\%USERNAME%
git-bash.exe
endlocal

You can have different settings for different usernames that way, or if you prefer hard-code the username in the batch file so it will always refer to the same home folder.

Some bower commands (especially bower init) and probably others sometimes have problems with Mintty that the current version of git-bash uses as terminal emulator, so sometimes you might have to use bash.exe directly. You can use another batch file for that.

setlocal
set HOME=%~dp0home\%USERNAME%
bin\bash.exe -login -i
endlocal

3. Corporate Firewall

With all of this set up, you might already have stumbled across another problem in the previous step when trying to run npm install -g bower since the corporate firewall most likely blocked that request.

git, bower and npm all observe the http_proxy and https_proxy environment variables so once you know which proxy to use (easiest by looking at the Internet options IE) you can set those with

export http_proxy=http://company-proxy:port
export https_proxy=http://company-proxy:port

And so you don't have to do this every time you should create a .bashrc file in your /home/YourUser folder and put the commands in that file, which will be executed everytime you start bash.

Hint: since Windows gets easily confused with dot-files the easiest way to do this is via git-bash like this:

cd ~
touch .bashrc
notepad .bashrc

And with this I'm all set to bring Polymer goodness to the company, let's see where this journey takes me. I'll expect some more blogposts along the way :)

Tuesday, August 4, 2015

Custom elements for Chrome Apps APIs

Continuing with my Polymer Chrome App I needed access to the Chrome Storage API. A quick search revealed only elements that haven't been updated to Polymer 1.0 so I started to create my own element based on iron-localstorage.

The "problem" with elements that depend on Chrome Apps APIs is that you can't test/use them outside of Chrome Apps, so I went ahead and created some gulp tasks to make things easier for me.

The main idea of these tasks is to put the contents of demo or test, which you would normally run directly, and all dependencies into one Chrome app that would then use demo/index.html or test/index.html as main page.

First I take all the files relevant for the element itself + the test/demo files, run the html files through crisper and put the result into the output components/my-element/ folder (following the layout of gh-pages for Polymer elements).
All bower dependencies are run through crisper as well and put into the components folder.
For the Chrome App itself only two files are important.

manifest.json defines the necessary permissions (e.g. to use chrome-storage the "storage" permission is required).
main.js launches the test or demo page.
The gulp task copies those two files to the main output folder, and changes the window.create call to point to the right file, e.g at components/my-element/test/index.html
The Chrome demo and test apps created that way can then be loaded as unpacked extensions.



This works nicely for the demo app, but unfortunately the test app reveals this in the console when starting it:

Uncaught Error: document.write() is not available in packaged apps.

Investigating the problem reveals this line in the web-component-tester to cause the issue, which makes sure that all dependencies are loaded before WCT is actually started.

To work around this issue you have to include the necessary scripts in the test files explicitly...
...and tell it not to load any scripts itself...
...before loading web-component-tester/browser.js on all the test pages.

So that I don't have to copy the same couple of lines into each of the test files separately, I extended the gulp-copy task to automatically insert the necessary lines in all files that include a reference to web-component-tester/browser.js
And with this change tests can be run in the Chrome App.


Following the idea of my previous article I also wanted to enable live-reload for this workflow

As opposed to my article where the livereload.js is removed for the production build, I did it the other way round here by adding it to the test/index.html or demo/index.html when running the gulp-live-task.
Watching for changes, rebuilding the app if necessary and triggering the reload works basically the same though.
And with this I can leave the test and/or demo apps running and see right away if all tests still pass after making changes and if the demos work as expected.

And now back to actually working on my app. All those distractions you run into while traversing (mostly) uncharted waters ☺

Thursday, July 30, 2015

Live-reload for Polymer Chrome Apps

While working on a new Chrome App using Polymer (details of which shall remain secret for now) I've encountered the following annoying repetitive steps:
  1. Change some code
  2. Run the code through crisper because the Content Security Policy for Chrome Apps doesn't allow inline scripts
  3. Reload the Chrome App from chrome://extensions/
  4. Repeat
The Polymer Start Kit offers a nice for solution this using Browsersync, which automatically updates all connected browser instances when the source code changes, but that only works for "normal" web apps meant to be hosted on a server which isn't the case for Chrome Apps.

After a bit of googling I found this nice article by Konstantin Raev that deals with the problem of live-reload for (non-Polymer) Chrome Apps and offers a straight-forward, working solution,
using tiny-lr and his own adapation of livereload.js (to work around some Chrome Apps security restrictions).

Using this gulp task will update or reload the Chrome App when any of the source files change, and you can just load your source folder as unpacked extensions, launch your app and start developing/testing:

While this works great for "normal" Chrome Apps the issue with Polymer Chrome Apps is that they at least need one extra crisper step to get all the JavaScript out of the .html as separate .js files.

My first lazy approach was to listen for any changes in the source folders, then run a full build and use the dist folder as unpacked extension.

A full build as per the Polymer Starter Kit involves quite a few steps, like minimizing the css/js/html, optimizing the images and vulcanizing the elements:

The only extra step you have to add in addition to what the Polymer Starter Kit does, is crisper after the vulcanize:

In the dev task (to be started with gulp dev) I first run a build, and then repeat the build step whenever something changes in the app folder. The build creates files in the dist folder (which is loaded as unpacked app), and livereload is triggered by listening to changes in this folder.

Of course this approach has several issues. Not only can the build sometimes take quite a while for even small changes, but you also get a minimized, vulcanized app, which can be terrible for debugging.

So instead I added a simplified dev-build that basically only copies all the files to a `dev` folder (to be loaded as unpacked app)...

and runs crisper on all .html files to get the .js parts out of the elements and their dependencies.

While working on that part I encountered an issue where gulp-crisper would ignore all folder structure and e.g. put all files directly into dev/bower_components/ instead of dev/bower_components/polymer/.  This issue is now fixed so make sure to use the newest version 0.0.5 of gulp-crisper.

When watching for changes I also don't update everything, every time something changes but listen for specific changes and only update the necessary parts.

And to prevent live reload to trigger for each single file change (and the build process creates several file changes for each source change) I'm using gulp-batch, collecting all changes in a batch before sending the info to tiny-lr.


Here's a quick video of how this process looks like now.


So with all of this done I can now proceed to work on my Polymer Chrome App after having learnt far more about gulp than I originally intended ☺