Wednesday, April 16, 2014

Never Forget the Polymer.dart Transformer (No Really, NEVER Forget It)


I thought to try to finish off the Strategy Pattern chapter in Patterns in Polymer tonight. Only when I loaded some “play” code in Dartium, I saw the following error in the console:
Exception: The "smoke" library has not been configured. Make sure you import and configure one of the implementations (package:smoke/mirrors.dart or package:smoke/static.dart).
#0      throwNotConfiguredError (package:smoke/src/implementation.dart:34:3)
#1      typeInspector (package:smoke/src/implementation.dart:26:5)
#2      query (package:smoke/smoke.dart:85:20)
#3      _getPublishedProperties (package:polymer/src/declaration.dart:409:31)
#4      PolymerDeclaration.publishAttributes (package:polymer/src/declaration.dart:175:39)
#5      PolymerDeclaration.buildType (package:polymer/src/declaration.dart:95:22)
#6      PolymerDeclaration.register (package:polymer/src/declaration.dart:72:14)
#7      _hookJsPolymer.registerDart.<anonymous closure> (package:polymer/src/loader.dart:100:75)
#8      _rootRun (dart:async/zone.dart:719)
#9      _ZoneDelegate.run (dart:async/zone.dart:453)
#10     _CustomizedZone.run (dart:async/zone.dart:663)
#11     _hookJsPolymer.registerDart (package:polymer/src/loader.dart:99:22)
Are. You. FREAKING. Kidding me?!

I specifically started tonight with writing so that I could get away from that stupid error. It is the same error that has plagued my testing efforts for the past two nights and now I am seeing it application code. Noooooo!

This was some relatively old Polymer.dart code that I am upgrading to the 0.10 version of the library. So I have already gone through it to tack on component=1 to the mime types so that the Dart VM will know to run all Polymer code in the same isolate:
<polymer-element name="store-changes-load">
  <template><!-- ... --></template>
  <script src="store_changes_load.dart"
          type="application/dart;component=1"></script>
</polymer-element>
I have already fixed the dependencies of my play application to use the appropriate bleeding-edge versions of the libraries in my pubspec.yaml file:
name: change_history
dependencies:
  polymer: ">0.10.0-pre"
  polymer_elements: ">0.2.0-pre"
dev_dependencies:
  unittest: any
So why, oh why am I still getting “smoke” package exceptions? Well, the title of this post pretty much gives it away: since this is old code, I have not specified a Polymer pub transformer in my Dart Pub configuration. If I add it to pubspec.yaml:
name: change_history
dependencies:
  polymer: ">0.10.0-pre"
  polymer_elements: ">0.2.0-pre"
dev_dependencies:
  unittest: any
transformers:
- polymer:
    entry_points: web/index.html
Then all of my Polymer code magically starts working.

And yup, if I go back to the pubspec.yaml from last night, add my test page to the list of files that are transformed by the Polymer transformer:
name: model_example
dependencies:
  polymer: ">=0.10.0-pre"
dev_dependencies:
  scheduled_test: any
transformers:
- polymer:
    entry_points:
    - web/index.html
    - test/index.html
Then my test magically passes.

Ah, life on the bleeding edge. Sometimes it does cut deep. But lesson learned: always include all pages using Polymer elements in the list of Polymer transformers—even test pages. I will never, NEVER forget that.


Day #36

6 comments:

  1. Hang on, not that I'm arguing with your conclusion... well I suppose I am. I managed to get my tests passing using the latest development version > 0.10.0 with no pub transformers whatsoever. Correct me if I'm wrong, but isn't the transformer only used when compiling to JS? Am I missing something. Anyway to illustrate I'm not using a transformer, as this is a library package, not an app.

    name: fun_components
    version: 0.2.1
    author: James Hurford
    description: Polymer components made for fun
    homepage: https://github.com/terrasea/fun_components
    environment:
    sdk: '>=1.0.0 <2.0.0'
    dependencies:
    credit_cat: '>=0.2.4 <0.3.0'
    gravatar: '>=1.2.3 <1.3.0'
    markdown: '>=0.6.0+1 <0.7.0'
    polymer: '>=0.10.0-pre.7 <0.11.0'
    roman_numerals: '>=1.0.2 <1.1.0'
    turkish_numbers: '>=0.1.0 <0.2.0'
    dev_dependencies:
    scheduled_test: any


    So I think there's something else going on here, which the transformer just happened to enact. Have you annotated the main method with @initMethod? I can't remember if you have said that at any point.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I grabbed your latest test from the polymer-patterns repository. I went to the model/dart/puspec.yaml and remove the polymer transformer, then ran the test to test my theory. I was right, it passed, I didn't even need

    return xPizza.flush();

    or

    schedule(()=> Polymer.onReady);

    As without them they still passed. Then I am using

    Dart Editor version 1.4.0.dev_02_02 (DEV)
    Dart SDK version 1.4.0-dev.2.2

    And I made one of the tests fail to make sure it would fail a test, and it did. This is without transformers, no async() use or use of Polymer.onReady. This is strange to me, as that would have not worked previously, with the older versions. I would still keep these async() and onReady around, but I think Polymer Dart is getting quicker at loading its elements.

    ReplyDelete
    Replies
    1. Ack. Sorry. I was doing something different. I finally had finally clicked the shiny 8081 link in:

      ➜ dart git:(master) ✗ pub serve
      Loading source assets...
      Loading smoke/src/default_transformer transformers... (3.5s)
      Loading observe transformers... (1.7s)
      Loading polymer/src/build/mirrors_remover transformers... (1.1s)
      Loading polymer transformers... (2.0s)
      Serving model_example web on http://localhost:8080
      Serving model_example test on http://localhost:8081

      I had caused a previously unrelated error in the tests and wound up wanting to run it in the browser. Initially the error message was the same. But, when I fixed the first message, I ran into the smoke & mirrors exception -- but ONLY because I was still running the test from 8081 without the transformer.

      I checked the test with content_shell and found the same as you -- when not running from 8081 the transformer is not needed. Bleh.

      Delete
    2. Ah that explains your problem. I didn't realise you were using pub serve and running the tests through localhost:8081. Yes you would need the transformer in this case I agree. What surprised me was I managed to get the tests to run without Polymer. onReady and async() to delay the actual tests till the element is ready. That is strange.

      Delete
    3. Oh and when they passed without Polymer.onReady and asynce() I was using the latest 1.4 development release, which may explain the results, if the Dart 1.4 is faster than 1.3, maybe

      Delete