Search code examples
web-componentcdnrollupjslit

lit element CDN rollup bundle file: accessing a function contained in the cdn bundle file from an external jsp file


I have created a simple lit element bundle file using rollup.config.js. This bundle file is uploaded in Netstorage. This is what my lit element looks like:

import {customElement} from "lit/decorators.js";
import {LitElement} from "lit";

@customElement('my-lit-element')
export class MyLitElement extends LitElement {

  constructor() {
    super();
    console.log('this is test log');
  }

  /**
   * invoked when a component is added to the document's DOM
   */
  connectedCallback() {
    super.connectedCallback();
  }

    testMethod() {
      console.log('Hi from testMethod()');
    }

}

declare global {
  interface HTMLElementTagNameMap {
    'my-lit-element': MyLitElement;
  }
}

my rollup.config.json:

import merge from 'deepmerge';
import { createSpaConfig } from '@open-wc/building-rollup';
import json from "@rollup/plugin-json"

// import copy from 'rollup-plugin-copy'
import pkg from './package.json'
 
const baseConfig = createSpaConfig({
  developmentMode: process.env.ROLLUP_WATCH === 'true',
  injectServiceWorker: false
});
 
export default merge(baseConfig, {
  // any <script type="module"> inside will be bundled by rollup
  input: './index.html',
  plugins: [
    // ... other rollup plugins
    json()
  ]
});

index.html points to MyLitElement.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Single Page Application</title>
</head>
<body>
    <script type="module" src="./out-tsc/src/MyLitElement.js"></script>
</body>
</html>

I have embedded the bundle file in an external jsp/html file and include the tags to execute the lit element:

The bundle file has a public function testMethod(console.log('this is test')). I want to access the testMethod() from the jsp.

This is what I have tried so far

//jsp file:

 <script type="module" src="https:path_to_my-lit-element-cdn_bundleFile.js"></script>
 <my-lit-element></my-lit-element>
<script>
var dcfVar = document.querySelector("my-lit-element");
console.log("dcfvar", dcfVar) 
dcfVar.testMethod();
</script>

It fails at dcfVar.testMethod(); ==> says Uncaught TypeError: dcfVar.testMethod is not a function

Could anyone help with this error. Is accessing the methods externally possible ?

Trying to call testMethod() from external jsp

expected ==> see the console log: 'Hi from testMethod'


Solution

  • The <script> where you're calling the test method is running synchronously before the custom element can be registered as the <script type="module"> is deferred.

    To make sure the test method is called when the component is available, you can take advantage of whenDefined.

    <script type="module" src="https:path_to_my-lit-element-cdn_bundleFile.js"></script>
    <my-lit-element></my-lit-element>
    <script>
      customElements.whenDefined('my-lit-element').then(() => {
        const el = document.querySelector('my-lit-element');
        el.testMethod();
      });
    </script>