I'm looking to modularize my LWC without having to embed them in the template. Ideally, would this kind of pattern be feasible? I'm not sure if it's my lack of ES6 knowledge (modules) or that LWC blocks this but this is what I'm attempting:
UtilityLWC.js
import { LightningElement, api } from 'lwc';
export default class UtilityLWC extends LightningElement {
@api
foo() {
console.log('foo from UtilityLWC');
}
@api
bar() {
console.log('bar from UtilityLWC');
}
}
ConsumerLWC.js
import { LightningElement, api, track, wire } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import UtilityLWC from 'c/UtilityLWC'; // doesn't work
// import * as util from c/UtilityLWC; // also doesn't work
// import { foo, bar } from c/UtilityLWC; // nope
export default class ConsumerLWC extends NavigationMixin(LightningElement) {
connectedCallback() {
// None of these work
UtilityLWC.foo();
UtilityLWC.bar();
// util.foo();
// util.bar();
// foo();
// bar();
}
}
So the easy way out is to add <c:utilityLWC>
inside ConsumerLWC.html
and use standard querySelector to reach inside an call foo() / bar()
but is that the only way to do this?
Edit: I am aware of the general JS code re-use patterns (example in my lwc-utils repo). This is more a question of, is it possible to have that kind of pattern but also, for example, have reusable wires?
Best Answer
I am not ES6+ or JS expert, but there's a section for this on the documentation - Share JavaScript Code and also there are examples on lwc-recipe for this. In general, the export works as documented for ES6 module.
From LWC documentation:
So it doesn't seem that you can actually export the whole class. You will need to modify your shared JS based on the approach as mentioned in the documentation, i.e., you will need to export the functions as named functions. For further details, refer to the links mentioned above.
As a quick example, below is an approach for exporting and using a named function.
Let's say I have a shared JS as below:
sharedJS.js
And that I want to use this on another component, I will go doing as below in the component.
helloWorldJS.js
helloWorld.html