I have a Dart script to combine JavaScript generated from a Polymer.dart element. I would like to see if I can generalize it a bit.
I failed in my attempts to make a single JS file for Polymer.dart elements from a Dart Pub transformer. This means that I cannot generate a single JS file with a simple
pub build
. So instead, I aim for he next best thing: pub build; polymer-reduce
. Hopefully this will mostly involve removing hard-coded values. But first...I need to parse my project's
pubspec.yaml
:name: deployment_experiment dependencies: polymer: any dev_dependencies: scheduled_test: any transformers: - polymer: entry_points: web/index.htmlThe
polymer
transformer, which is part of Polymer.dart, uses the entry_points
setting to decide which pages to inspect for Polymer elements in need of transforming. Based on the name, I would guess that entry_points
can be more than one page.Anyhow, first things first, I need to be able to parse the YAML in
pubspec.yaml
, so I add the YAML library to… pubspec.yaml
:name: deployment_experiment dependencies: polymer: any dev_dependencies: scheduled_test: any yaml: any transformers: - polymer: entry_points: web/index.htmlI also need to add this to last night's
reduce.dart
script:#!/usr/bin/env dart import 'dart:io'; import 'package:yaml/yaml.dart'; main() { var pubspecYaml = new File('pubspec.yaml').readAsStringSync(); var pubspec = loadYaml(pubspecYaml); // ... }The
transformers
entry in pubspec.yaml
is an ugly beast. It is a list of single key maps, which means that I need to filter the transformers
list for entries where the single key is "polymer"
, then for each, I need to run last night's transform. It might be an ugly data structure, but Dart's built-in iterators take care of it nicely:main() { var pubspecYaml = new File('pubspec.yaml').readAsStringSync(); var pubspec = loadYaml(pubspecYaml); // var filename = 'web/index.html'; pubspec['transformers']. where((t) => t.keys.length == 1 && t.keys.first == 'polymer'). forEach((t){ var filename = t['polymer']['entry_points']; new PolymerScriptReducer(filename).reduce(); }); }The
PolymerScriptReducer
class is a simple reworking of last night's procedural code into a procedural class that can run against multiple entries. That turns out to be the most complex bit of the conversion. I rework last night's placement of reduced JavaScript and the HTML that uses it, which winds up simplifying things quite a bit. I had been creating the reduced files into a separate
deploy
sub-directory. Since this is meant to be part of pub build
, I place the reduced files directly in the build
directory generated by pub build
.The only other question that I would like answered is—what happens if multiple HTML files are listed as
entry_points
?name: deployment_experiment dependencies: polymer: any dev_dependencies: scheduled_test: any yaml: any transformers: - polymer: entry_points: - web/index.html - web/index2.htmlI make
web/index2.html
a copy of web/index.html
and run pub build
. That produces generated output for both HTML files:➜ dart git:(master) ✗ tree -L 2 build build └── web ├── assets ├── index2.html ├── index2.html_bootstrap.dart.js ├── index2.html_bootstrap.dart.js.map ├── index2.html_bootstrap.dart.precompiled.js ├── index.html ├── index.html_bootstrap.dart.js ├── index.html_bootstrap.dart.js.map ├── index.html_bootstrap.dart.precompiled.js └── packages 3 directories, 8 filesTo support either a single string entry or a list of strings, I need to inspect the runtime type of
entry_points
:main() { var pubspecYaml = new File('pubspec.yaml').readAsStringSync(); var pubspec = loadYaml(pubspecYaml); pubspec['transformers']. where((t) => t.keys.length == 1 && t.keys.first == 'polymer'). forEach((t){ var entry_points = t['polymer']['entry_points']; var filenames = entry_points.runtimeType == String ? [entry_points] : entry_points; filenames. forEach((filename) { new PolymerScriptReducer(filename).reduce(); }); }); }And that does the trick. I doubt that anyone would need to generate multiple entry points like that—especially if the goal is a single JavaScript source file for a Polymer.dart element. Still, I cannot ignore the plural nature of the name. I will likely rework this bit further as a package in case others might have need of it—or if I need to reference it in Patterns in Polymer. Tomorrow.
Day #24
No comments:
Post a Comment