Cross-referencing JS Module References?

Hello,

This might be more of a JavaScript/platform question than a true front-end question.

I am creating panels using custom strategies, because using the UI and/or YAML is too unwieldy given how many edits are needed when hardware configuration changes or when I want to redesign a panel or view that references many different kinds of entities.

I am doing fine with this project so long as everything that is needed in a registered JavaScript module reference is all in that single file.

But Iā€™d like to have classes that are available to multiple resources. When I try to reference a class in one registered module from another registered module, the browser behaves as though itā€™s not a defined class.

Google searching suggests that this is fairly platform-specific and I donā€™t know how to accomplish this with the Lovelace front-end because I donā€™t understand it well enough yet.

Does anyone have any suggestions? Thank you.

Searching Google in the context of ā€œweb componentsā€ led me to something that works.

In short, in the file where I define the class I want to use in another file, I use

export { ClassName }

And then in the file that wants to ā€˜referenceā€™ ClassName, I have

import { ClassName } from "<file where ClassName is defined>";

That gives me enough to look at docs to figure out the most efficient way to do things. Thanks to all who read and considered!

1 Like

While that is great, what if you need them referenced in a custom-card?
This method would require (I believe) to change the custom-card JS code everytime you add a class.

Or am I wrong.

I have been asking this similar question in flex-table where I would like to have a library of functions without significantly modifying the core card JS so that updates do not break things.

See [Feature Request] Add ability to define "personal" Cellformatters Ā· Issue #125 Ā· custom-cards/flex-table-card Ā· GitHub

Or maybe this is the solution if I create a class that contains all the functions, then just import that one class?

That was my first worry. You can use the following approach to grab everything from a file, I believe; but it requires you to use a namespace with each reference (which is a good thing to do anyway, since you donā€™t want the addition of a symbol in an external file to suddenly cause a clash with the same symbol in the file thatā€™s doing the importing).


import * as NamespaceName from "<file>";

Iā€™ve tested and it at least works for classes.

Exciting. I need to test this and see how it will work!!!

FYI, I got this working perfectly. Given some card that uses JS, developerā€™s could easily add something like this at the top:

import * as plugin from "./flex-table-card-plugins.js";

Then in the same directory as the JS for the card, include that file on new installation and never overwrite it for updates. That file can just have your collection of functions and mark them with keyword ā€œexportā€:

export function foo() {...}
export function bar() {...}

Then you use it in the JS part of card, you would call:

plugin.foo();

This is a perfect solution for flex-data-table.js