Search code examples
javascriptpolymerpolymer-3.x

Is it possible to split a Polymer 3 component into separated JavaScript, HTML, and CSS files?


I am trying to split a Polymer 3 component into separated files so for example:

import { html, PolymerElement } from '@polymer/polymer/polymer-element';

export default class TestSplit extends PolymerElement {
  static get template() {
    return html`
      <style>
        p {
          color: blue;
        }
      </style>

      <p>Hello from component</p>
    `;
  }
}

customElements.define('test-split', TestSplit);

would look like something like:

index.js:

import { PolymerElement, html } from '@polymer/polymer/polymer-element';

import css from './style.css';
import template from './template.html';

export default class TestSplit extends PolymerElement {
  static get template() {
    return html`
      <style>${css}</style>
      ${template}
    `;
  }
}

customElements.define('test-split', TestSplit);

style.css:

p {         
  color: blue;          
}

template.html:

<p>Hello from component</p>

Edit1:

I tried out the following code with the same template.html and style.css files:

import-test.js:

import { html, PolymerElement } from '@polymer/polymer/polymer-element';
import CssHtmlLoader from './cssHtmlLoader';

export default class ImportTest extends PolymerElement {
  static get template() {
    let htmlTemplate = CssHtmlLoader.prototype.getHtmlTemplate('template.html');
      console.log(htmlTemplate)
      return htmlTemplate.then(function (file) {
        return html`
          <link rel="stylesheet" href="style.css"> 
          ${file}
        `;
      });  
    }
  }
}

customElements.define('import-test', ImportTest);

I am getting the right file from the promise: enter image description here

But I also get the following errors: enter image description here

Is there any idea what is wrong with the code?


Solution

  • So I tried the following component:

    import-test.js

    import { html, PolymerElement } from '@polymer/polymer/polymer-element';
    import {htmlLiteral} from '@polymer/polymer/lib/utils/html-tag.js';
    import CssHtmlLoader from './cssHtmlLoader';
    
    export default class ImportTest extends PolymerElement {
    
      static get properties() {
        return {
          htmlTemplate:{
            type:String,
            notify:true,
            reflectToAttribute: true
          },
          helloWorld:{
            type:String,
            notify:true,
            reflectToAttribute: true,
            value: 'auto'
          }
        }
      }
    
      constructor(){
        super();
        var that = this;
        this.attachShadow({mode: 'open'});
        console.log(this.shadowRoot);
        this.htmlTemplate = CssHtmlLoader.prototype.getHtmlTemplate('templaten.html');
        this.htmlTemplate.then((template) => {
          console.log(that);
          that.shadowRoot.innerHTML = template
        });
      }
    }
    
    customElements.define('import-test', ImportTest);
    

    with the following html and css template:

    style.css:

    p {
        color: blue;
    }
    

    template.html:

     link rel="stylesheet" href="style.css"> 
     <p>Hello from template [[helloWorld]]</p>
    

    and this was my output:

    Hello PolymerImportTest-app!
    Hello from template [[helloWorld]](this is blue so the css import works)
    

    so my problem was that I was not able to bind properties to the html template.

    And the solution for that was to put the html template into a separate javascript file and from there I was able to export it and use it in the custom component(with the propertie binding working).

    Here is my solution:

    import-test.js:

    import { html, PolymerElement } from '@polymer/polymer/polymer-element';
    import {template} from './template';
    
    export default class ImportTest extends PolymerElement {
    
      static get properties() {
        return {
          helloWorld:{
            type:String,
            notify:true,
            reflectToAttribute: true,
            value: 'auto'
          }
        }
      }
    
      constructor(){
        super();
      }
    
      static get template() {
        return template;
      }
    
    }
    
    customElements.define('import-test', ImportTest);
    

    template.js:

    import {html} from '@polymer/polymer/polymer-element';
    
    export const template=html`
    <link rel="stylesheet" href="/src/PolymerImportTest-app/style.css">
    <p>Hello from template [[helloWorld]]</p>
    `;
    

    style.css:

    p {
        color: blue;
    }
    

    And the output:

    Hello PolymerImportTest-app!
    Hello from template auto(blue and the property is correctly attached)