Friday, February 14, 2014

Yak Boxed: Day 2


I cannot stop. I have no idea how close I am to getting Polymer testing working with Karma and PhatomJS, but last night's stopping point felt a little arbitrary.

I enjoyed last night's yaks, so tonight, I give myself an extension on yak-boxed development. Owing to the need to finish up Patterns in Polymer, I yak-box tonight's efforts to no more than 4 yaks shaved before I call it a night.

Last night ended when I was unable to figure out from where the complaints about undefined PolymerExpression were originating. Before tackling that, I take a step back and shave…

Yak #1

If I am building the unminified polyfill platform from source, I ought to do the same with the actual Polymer code. Unlike building platform.js, that requires a little manual effort. Working with the same polymer-dev repository that I downloaded last night, I edit the Grunt configuration. Specifically, I uncomment the configuration that tells the uglify plugin to leave the result uncompressed and human readable:
module.exports = function(grunt) {
  var readManifest = require('../tools/loader/readManifest.js');
  var Polymer = readManifest('build.json');

  grunt.initConfig({
    // ...
    uglify: {
      // ...
      Polymer: {
        options: {
          sourceMap: true,
          sourceMapName: 'build/polymer.js.map',
          sourceMapIncludeSources: true,
          banner: grunt.file.read('LICENSE') + '// @version: <%= buildversion %>',
          mangle: false, beautify: true, compress: false
        },
        files: {
          'build/polymer.js': Polymer
        }
      }
    },
    // ...
  });
  // ...
};
With that, the default Grunt task in polymer-dev will build the very large version of Polymer that I desire:
➜  polymer-dev git:(master) ✗ grunt
Running "version" task

Running "uglify:Polymer" (uglify) task
File build/polymer.js.map created (source map).
File build/polymer.js created.

Done, without errors.
➜  polymer-dev git:(master) ✗ ls -lh build
total 172K
-rw-r--r-- 1 chris chris  208 Feb 13 23:07 polymer.html
-rw-r--r-- 1 chris chris  53K Feb 14 22:28 polymer.js
-rw-r--r-- 1 chris chris 110K Feb 14 22:28 polymer.js.map
This brings me to…

Yak #2

I need these really large files because trying to debug minfied code in PhantomJS is rubbish. I need real line numbers and readable code if I am going to make any headway. I also think that I need the HTML import files in addition to the JS files. Last night I tried copying the generated JavaScript over top of Bower installed components. Tonight, I carve out space for these builds:
➜  js git:(master) mkdir scripts
➜  js git:(master) cp -r ~/repos/polymer_local/components/polymer-dev/build scripts/polymer
➜  js git:(master) ✗ cp -r ~/repos/polymer_local/components/platform-dev/build scripts/platform
Then, in my karma.conf.js configuration file, I add this scripts directory to the list of files that will be served, but not automatically included:
    files: [
      'test/PolymerSetup.js',
      {pattern: 'elements/**', included: false, served: true},
      {pattern: 'scripts/**', included: false, served: true},
      {pattern: 'bower_components/**', included: false, served: true},
      'test/**/*Spec.js'
    ],
    // ...
They are not automatically included because a test setup script does that. I also have to update that to pull in these newly build versions of Polymer and its platform:
// ...
var script = document.createElement("script");
script.src = "/base/scripts/platform/platform-lite.concat.js";
document.getElementsByTagName("head")[0].appendChild(script);
// ...
With that, I still get the following error when I run karma:
PhantomJS 1.9.7 (Linux) ERROR
        ReferenceError: Can't find variable: PolymerExpressions
        at undefined:29
So I am on to…

Yak #3

I think that yesterday's grunt concat task for building Polymer's platform was incorrect. Instead, I need to run grunt with no arguments to build the default (minified) task. BUT… first, I modify the build task with the same non-compress options that I used for building Polymer. After re-copying the build directory into my application's scripts directory and pointing everything to the now non-compressed platform.js, I get a new error:
PhantomJS 1.9.7 (Linux) ERROR
        SyntaxError: Parse error
        at /home/chris/repos/polymer-book/play/svg/js/scripts/platform/platform.js:2662
PhantomJS 1.9.7 (Linux): Executed 0 of 1 ERROR (0.165 secs / 0 secs)
Bother. That is not the same “prototype” error that started me on this adventure, which means that it is time for…

Yak #4

This parse error occurs on a setter in platform.js:
            // ...
            set textContent(textContent) {
              // ...
            },
            // ...
This turns out to be due to the parameter being the same name as the method. That seems like bad form, but not necessarily worth of a parse error. Unfortunately, I do not have many options other than to manually change each of these. Prefixing the parameter with an underscore (and updating the method body accordingly) does the trick:
            // ...
            set textContent(_textContent) {
              // ...
            },
            // ...
And, with that, I finally get:
PhantomJS 1.9.7 (Linux) ERROR
        TypeError: 'undefined' is not an object (evaluating 'nativeConstructor.prototype')
        at /home/chris/repos/polymer-book/play/svg/js/scripts/platform/platform.js:1324
That looks very much like my original error from the compressed JavaScript:
PhantomJS 1.9.7 (Linux) ERROR
        TypeError: 'undefined' is not an object (evaluating 'a.prototype')
        at /home/chris/repos/polymer-book/book/code-js/svg/bower_components/platform/platform.js:29
Unfortunately, the code in question is rather opaque:
        function register(nativeConstructor, wrapperConstructor, opt_instance) {
            var nativePrototype = nativeConstructor.prototype;
            registerInternal(nativePrototype, wrapperConstructor, opt_instance);
            mixinStatics(wrapperConstructor, nativeConstructor);
        }
I am not at all sure how Polymer is reaching this point and what I might do to trick PhantomJS into using a more appropriate value here. But, I have reached my yak limit for tonight, so I leave that for another day.

Day #1,026

No comments:

Post a Comment