Saturday, January 4, 2014

Building Minified Polymer Libraries from Dart


There are debug statements in my build code. Why are there debug statements in my build code?

I was pleased with my progress at getting my “old” Polymer version of the ICE Code Editor back up and running—even to the point that I could build it for JavaScript-only browsers. Only... why is that debug code in the generated HTML?
<html><head><script src="packages/shadow_dom/shadow_dom.debug.js"></script>
<script src="packages/custom_element/custom-elements.debug.js"></script>
<script src="packages/browser/interop.js"></script>
  <script src="polymer.html_bootstrap.dart.js"></script>
</head>
<body><polymer-element name="ice-code-editor"><!-- ... -->
</body></html>
It actually takes me a fair bit of digging, but I eventually find the following in polymer/src/build/polyfill_injector.dart:
      // TODO(sigmund): enable using .min.js. This currently fails in checked
      // mode because of bugs in dart2js mirrors (dartbug.com/14720).
      // var suffix = options.releaseMode ? '.min.js' : '.debug.js';
      var suffix = '.debug.js';
I am not quite sure that I follow the bug, but it seems like only affects unit testing. That is, I think that code would still work if the “min.js” versions were used, but there is currently no way for Polymer.dart to verify that it works. To put that theory to the test, I manually change both of the debug <script> tags to use the min versions instead:
<html><head><script src="packages/shadow_dom/shadow_dom.min.js"></script>
<script src="packages/custom_element/custom-elements.min.js"></script>
<script src="packages/browser/interop.js"></script>
  <script src="polymer.html_bootstrap.dart.js"></script>
</head>
<body><polymer-element name="ice-code-editor">
<!-- ... -->
</body></html>
And that seems to do the trick. When I load my smoke test page, the Polymers still work and the Network tab confirms that the minified versions of the two libraries are being used:



The Polymers even work in Internet Explorer so I think I am good:



Hand editing code is never a useful thing to do. I could write a script that always does this for me, but I would still have to remember to run that every time I build my application. Actually, I know how to do this. I already wrote one pub transformer. I can do it again. I start by adding an application specific transformer to my pubspec.yaml:
name: ice_code_editor
version: 0.0.11
# ...
dependencies:
  crypto: any
  js: any
  ctrl_alt_foo: any
  json: any
  polymer: any
transformers:
- polymer:
    entry_points: web/polymer.html
- ice_code_editor:
    entry_points: web/polymer.html
The transformer is then more or less a copy and paste job from that other transformer. The overall structure is identical (which means that I probably ought to extract it out into a library). The only difference is the name of the transformer (ProductionMode) and the regular expression replacement performed by the transformer's apply() method:
class ProductionMode extends Transformer {
  // ...
  Future apply(Transform transform) {
    var input = transform.primaryInput;
    return transform.
      readInputAsString(input.id).
      then((html){
        var fixed = html.replaceAllMapped(
          new RegExp(r'\.debug\.js'),
          (m) => '.min.js'
        );
        transform.addOutput(new Asset.fromString(input.id, fixed));
      });
  }
}
And that does the trick. It does not speed up the build transformation by any stretch of the imagination, but whenever I do build my Polymer for deployment, it now includes the minified version of the JavaScript libraries instead of the debugging versions.

With that, I have a repeatable means of generating a minified version of my Polymer. At least until that bug is fixed.

Day #986

No comments:

Post a Comment