Patrick Cornelissen
Patrick Cornelissen

Reputation: 7958

Lazy load web-components from other services in polymer 3

I have a microservice based application and each service has a set of polymer based web-components. I want to load these at runtime in the application that is served by one of them at runtime, so that I can run, maintain and deploy the services seperately. I would like to avoid having a npm repo that serves the components for a central build and each new web component version would make it necessary to rebuild and redeploy the application.

Existing lazy loading examples all lazy load components of the same application, so it's built as a whole and just packaged in chunks.

The application is available under /app/ and the modules are under /mod/...

I can do this in to react to a route:

import('/mod/admindashboard/kw-admindashboard.js').then((module) => {
  // Put code in here that you want to run every time when
  // navigating to view1 after my-view1.js is loaded.
  console.log("Loaded admindashboard");
});

and then I can use the corresponding web component, but for this to work I need to hack the component like this:

import { PolymerElement, html } from '/app/node_modules/@polymer/polymer/polymer-element.js';
import '/app/node_modules/@polymer/iron-icon/iron-icon.js';
import '/app/node_modules/@polymer/iron-icons/iron-icons.js';

class KwAdmindashboard extends PolymerElement {
    static get template() {
...

But this approach prevents me completely to run tests, create static builds and IDE support is not available either in many areas, as it's not able to see what is available later at runtime. So as absolute fallback this would be possible. Isn't there a way to utilize the serviceWorkers to handle mapping?

Upvotes: 1

Views: 1288

Answers (2)

Patrick Cornelissen
Patrick Cornelissen

Reputation: 7958

It seems like Polymer 3 is not yet ready for distributed locations of webcomponents.

There are github issues at the W3C which may solve these problems:

For now I will switch my development model, so the microservices provide one or more webcomponents to my npm repo in nexus and the admin app has build time dependencies to them and builds the whole app in one go and there I can use the lazy loading approach that the shop demo also promotes/shows.

For a decent development experience with webcomponents from multiple sources, you should have a look at "npm link".

Feel free to add another solution for the problem or a real solution as soon as the technology and standards caught up.

Upvotes: 0

Cappittall
Cappittall

Reputation: 3441

Here below is I think a good example of your requirement. Modules will be loaded with page properties. As page property is depended on iron-page, selected='{{page}}' when page value has been changed with iron-page's name properties, its observer loads the that page's modules. :

static get properties() { return {
    page: {
      type: String,
      reflectToAttribute: true,
      observer: '_pageChanged'
    },
.......

_pageChanged(page, oldPage) {
    if (page != null) {
      let cb = this._pageLoaded.bind(this, Boolean(oldPage));

     // HERE BELOW YOUR PAGE NAMES
      switch (page) {
        case 'list':
          import('./shop-list.js').then(cb);
          break;
        case 'detail':
          import('./shop-detail.js').then(cb);
          break;
        case 'cart':
          import('./shop-cart.js').then(cb);
          break;
        case 'checkout':
          import('./shop-checkout.js').then(cb);
          break;
        default:
          this._pageLoaded(Boolean(oldPage));
      }

here above cb is a function which is loading lazy modules but needs to load immediately after the first render. Which is minimum required files.

_pageLoaded(shouldResetLayout) {
    this._ensureLazyLoaded();

}

Here the full code's link of the above. Hope this helps In case of any question I will try to reply. https://github.com/Polymer/shop/blob/master/src/shop-app.js

Upvotes: 1

Related Questions