Polymer + SystemJS (was: requirejs+polymer)

761 views
Skip to first unread message

Sébastien Cevey

unread,
Aug 20, 2014, 6:45:11 AM8/20/14
to a.cog...@samsung.com, polym...@googlegroups.com, gab...@loadin.com.br, Oliver Joseph Ash
(I've been wanting to post this for a while, but this thread on requirejs+polymer prompted me to give it a try, apologies for the Subject hijacking)

FYI, and as discussed with Eric & Addy at the recent Polymer event at the Google Campus in London, I've been experimenting with using Polymer in combination with SystemJS. In other words, I'm using <script>System.import('the-js');</script> inside the HTMLImport, instead of a static <script src="the-js.js"></script> definition.

The advantage of using SystemJS is that I can then write my JS definition using ES6 (or in fact anything I want, incl. AMD or CJS), using the ES6 module import syntax too. Makes the code a lot neater, and avoid faffing with the manual RequireJS config (I use jspm to generate and manage the System config). It is also the only sane way I can think of (besides RequireJS) to have an HTML import depend on a JS file that itself depends on another JS file.

The code is Open Source here if you want to take a look:

(apologies for the poor docs at the root, it's not yet 100% ready for prime time...)


One of the issues with using System.import (or RequireJS' require, for that matter) in the HTML import is that unlike the static <script>, it is asynchronous. I had issues when using composition of components, where Polymer was failing some template binding due to dependencies being defined in the wrong order. I had to resort to manually expliciting the dependencies of the JS files *on top of* the declarative dependencies in the HTML files.

For example, see the following JS dependency:

(ensure windsock-data Polymer element is defined before windsock-admin, because admin uses data)

which unfortunately has to mirror the corresponding HTML dependency:


This is rather annoying, but I wasn't able to find a way around it, seeing as mixing HTMLImport and SystemJS results in a mix of sync and async dependencies, while Polymer requires a strict order for elements to be defined (AFAIU)...


Another challenge was the bundling of elements for leaner distribution. Vulcanize is aware of static <script>s, but not System.import calls (or require() calls if using RequireJS), so no JS is pulled into the vulcanized output. On the other hand, jspm bundle is quite happy to bundle JS modules into one, but it obviously doesn't know about HTML imports.

My extremely hacky (but oddly functional) solution comes in the form of a build script that combines vulcanize and jspm bundle, prepending the SystemJS bundle to the vulcanize output:


Some of the hackery, esp the hack around the AMD define at the bottom, should hopefully go away as fixes are incorporated into SystemJS instead.

It's all still a bit rough, but I hope it proves it can all be done, albeit slightly more painfully than it ought to be...


Any insight or ideas for making this all better natively supported would be very much welcome. I know there are discussions about HTMLImport vs System loader on es-discuss at the moment, but it'd be great to start thinking of ways to get all of this working together without extra hassle!

Thanks for all the great work on Polymer!


-- 
Sébastien Cevey
The Guardian / Software Developer


On 20 August 2014 08:49, <a.cog...@samsung.com> wrote:
Hi,

is there any progress related to this topic?

BR,
Alessandro


On Wednesday, February 26, 2014 10:09:55 AM UTC+2, Eric Bidelman wrote:

Scott, don't you have a new HTML import + JS module loader POC or brain dump somewhere? Am I making that up?

On Feb 25, 2014 4:21 PM, "Gabriel Gartz" <gab...@loadin.com.br> wrote:
I like the idea of using requirejs and polymer project together, some points:

* Requirejs system migration: you just can't re-develop everything to work with only polymer from one day to another.
* Using logical libs for a custom element: Some custom elements can be very complex, using the require js allow you to easier coding with namespace and modules dependence.

Other points, it's possible to create a Custom Element to trigger and manipulate requirejs, but you need to load polymer project before the requirejs.
And finally the problem with requirejs loading before polymer project it's in the way that requirejs create and use script elements to append on the head from the DOM, where the ShadowDOM from Polymer decorate the elements and if isn't decorated it throw a assert exception, so if require is loaded before to load polymer it wont work.

Em quinta-feira, 25 de julho de 2013 09h26min45s UTC-3, Joern Turner escreveu:
sorry, if that's a recurring question having answered elsewhere already. After searching the discussions i only found some remarks on that but no defnitive answer.

We're also very interested to load polymer with requirejs or at least use them in conjunction. Anybody found a solution to that? Any pragmatic approach would be welcome.

Second: after reading for a while i haven't found answers to the questions what polymer does to the global objects (window, document ...) and how/if it changes the javascript language.

Thanks,

Joern

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/5d9ab14d-8f23-4708-a387-e7cf67326823%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.





Visit theguardian.com. On your mobile and tablet, download the Guardian iPhone and Android apps theguardian.com/guardianapp and our tablet editions theguardian.com/editions.  Save up to 57% by subscribing to the Guardian and Observer - choose the papers you want and get full digital access.  Visit subscribe.theguardian.com

This e-mail and all attachments are confidential and may also be privileged. If you are not the named recipient, please notify the sender and delete the e-mail and all attachments immediately. Do not disclose the contents to another person. You may not use the information for any purpose, or store, or copy, it in any way.  Guardian News & Media Limited is not liable for any computer viruses or other material transmitted with or as part of this e-mail. You should employ virus checking software.
 
Guardian News & Media Limited is a member of Guardian Media Group plc. Registered Office: PO Box 68164, Kings Place, 90 York Way, London, N1P 2AP.  Registered in England Number 908396


Steve Orvell

unread,
Aug 20, 2014, 3:26:38 PM8/20/14
to Sébastien Cevey, a.cog...@samsung.com, polym...@googlegroups.com, gab...@loadin.com.br, Oliver Joseph Ash
Thanks for the detailed feedback.

It seems like you have a handle on the build issues. There a lot of options here but if you can think of a specific feature vulcanize should have, please feel free to post an issue. Maybe you already did this, but note that Vulcanize can concat scripts in imports. If that output needs further processing for SystemJS, perhaps Vulcanizer's output is the input for the SystemJS compressor.

For the ordering issues, the Polymer requirement is that dependencies are registered in the order in which they are used. For example, if x-bar extends x-foo, x-foo must be registered first. Polymer 0.3.5 improved support for async scripts. Polymer now waits to register elements until all `<polymer-element>` declarations have their accompanying scripts before registering elements. If you used this version, I don't expect to need to specifically order things other than the noted requirement.




Guy Bedford

unread,
Sep 11, 2014, 8:04:52 AM9/11/14
to Steve Orvell, Sébastien Cevey, a.cog...@samsung.com, polym...@googlegroups.com, gab...@loadin.com.br, Oliver Joseph Ash
Thanks so much Sebastien for posting this feedback. I think the methods you have here really are the best way to combine SystemJS with web components. It would be great to take the lessons you have learnt here and be able to turn them into something we can share more widely.

In terms of the build, it sounds like exactly the right way to do it as well.

The issue you had with needing to import a web component dependency could be avoided if we had support for the <module> tag in web components.

<link rel="import" href="../bower_components/polymer/polymer.html">

<module name="windsock:elements/windsock-data">

<polymer-element name="windsock-data" attributes="src refresh sink-notices">
</polymer-element>

If we could propose that the <module> tag loads, but doesn't execute (System.load provides this functionality) until the modules in the sub-imports have executed first, we may have a unified solution for that.

I'd be very interested to hear from the web component team if something along these lines could be possible between the module loader and HTML import specifications in due course.


Guy Bedford

unread,
Sep 11, 2014, 8:41:30 AM9/11/14
to Steve Orvell, Sébastien Cevey, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
Note that this same concept can apply to anonymous modules so that we get identical execution order to what we would expect from scripts:

<link rel="import" href="../bower_components/polymer/polymer.html">

<!-- jquery is loaded immediately through a System.define call -->
<!-- execution only happens when ready, through HTML imports trigger - System.get call -->
<module>
  import $ from 'jquery';

  Polymer('windsock-data', ...);
</module>


<polymer-element name="windsock-data" attributes="src refresh sink-notices">
</polymer-element>

Sébastien Cevey

unread,
Sep 12, 2014, 11:28:13 AM9/12/14
to Guy Bedford, Steve Orvell, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
Ah yeah that'd be nice. Where is the work on <module> being done? Has it been polyfilled by any library yet?
--
Sébastien Cevey
Software Developer

Guy Bedford

unread,
Sep 12, 2014, 11:47:19 AM9/12/14
to Sébastien Cevey, Steve Orvell, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
We do have a PR on this for the module loader ready to go (https://github.com/ModuleLoader/es6-module-loader/pull/156). We could generalise it to apply in a hookable way so that the HTML imports polyfill could call out to this as well potentially.

Sébastien Cevey

unread,
Sep 12, 2014, 11:55:09 AM9/12/14
to Guy Bedford, Steve Orvell, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
Oh nice! Yeah that would be really helpful.

John Barton

unread,
Sep 12, 2014, 12:02:52 PM9/12/14
to Guy Bedford, Sébastien Cevey, Steve Orvell, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
Is there any difference between <script type='module'> and <module> other than spelling?
jjb


Guy Bedford

unread,
Sep 12, 2014, 5:20:32 PM9/12/14
to John Barton, Sébastien Cevey, Steve Orvell, a.cogliati, polym...@googlegroups.com, gabriel, Oliver Joseph Ash
On 12 September 2014 18:02, John Barton <johnj...@google.com> wrote:
Is there any difference between <script type='module'> and <module> other than spelling?

Good point - <script type=module> is exactly the same and already implemented in the module loader and Traceur. Perhaps it is a better focus for polyfilling in this scenario.

Gabriel Reitz Giannattasio

unread,
Sep 12, 2014, 5:28:35 PM9/12/14
to Guy Bedford, John Barton, Sébastien Cevey, Steve Orvell, a.cogliati, polym...@googlegroups.com, Oliver Joseph Ash
I think it should console warn when you try to create a CustomElement that hasn't `-` on the name, but not throw exception for that.

Because in the browser implementations of web-components you can do it. That way we could add new official components to old browsers that doesn't have it implemented just creating the components when they doesn't exist.
Reply all
Reply to author
Forward
0 new messages