0

In a custom lightning aura component app, I have a component where I want to include a static resource.

I have successfully created the static resource (a JavaScript file) and included it in the component like so:

<!-- someComponent.cmp -->
<aura:component controller="SomeController" implements="..." access="global">
    <ltng:require scripts="{!$Resource.GlobalJs}" />
</aura:component>

Now there may be other static resources or components that I'd like to include in the future, for all components. I don't want to have to add each global entity to every component every time I realize I need a new global resource. So - is it possible to create a component solely for the purpose of including global static resources and other components?

I tried creating such a component like this...

<!-- globalIncludes.cmp -->
<aura:component>
    <ltng:require scripts="{!$Resource.GlobalJs}" />
</aura:component>

...and then including that inside the main component like this:

<!-- someComponent.cmp -->
<aura:component controller="SomeController" implements="..." access="global">
    <c:globalIncludes/>
</aura:component>

But this doesn't appear to be working - I'm getting a JavaScript error as if the JavaScript file wasn't included properly. Is it possible to do what I'm trying to do? Am I doing something wrong?

1 Answer 1

2

Imported scripts are isolated to the component in which they were imported in to. This is a security feature. Behind the scenes, each component gets its own window object instead of the global window that browsers use by default. You could choose to export a method that your component could use, I guess:

<aura:component>
    <ltng:require scripts="{!$Resource.GlobalJs}" afterScriptsLoaded="{!c.setGlobalValues}" />
    <aura:method name="getGlobalValue" action="{!c.getGlobalValue}">
      <aura:attribute name="name" type="Object" />
    </aura:method>          
</aura:component>

...

({ // controller
  setGlobalValues: function(c, e, h) {
    h.setGlobalValues(); // we can only store stuff on the helper
  },
  getGlobalValue: function(c, e, h) {
    return h.getGlobalValue(e.getParam('arguments').name);
  }
})

...

({ // helper
  setGlobalValues: function() {
    this.globals = { value1, value2, value3 }; // Assuming they were set in script.
  },
  getGlobalValue: function(name) {
    return this.globals[name];
  }
})

Even then, you'll have to reference them through the component:

<c:globalIncludes aura:id="globals"/>

...

component.find("globals").getGlobalValue("value1");

Would all this be worth it? Not directly as written, but perhaps a more elegant design could be to have an inheritable component:

<aura:component extends="c:globalIncludes">
</aura:component>

The c:globalIncludes component would load the globals as normal, and the helper would include a method to read those global values:

getGlobalValue: function(name) {
  return this.globals[name];
}

Then, in your other components, you could call a helper method:

this.getGlobalValue('value1');

Honestly, if you can get away with it, it's time to start using LWCs. You can easily import global values from a common source, and you don't even need a static JS file:

import globals from 'c/globalValues';

Where the globals are exported directly:

const globals = { value1: 5, value2: 10, value3: 15 }
export default globals;

As you can see, it ends up being a lot more simple when you can just directly import the values.

7
  • Great answer - thank you! I don't know if this effects your answer at all, but the global js I'm including is exposing a global object with methods that I can use. So far it's dealing with sessionStorage, so I'm doing something like window.MyNamespace = (function() { return { getSessionValue: function() {...}, setSessionValue(){...},... } }());, so then in the js of any component (like in the helper for example), I can just call const someObj = MyNamespace.getSessionValue(key);
    – jbyrd
    Apr 30, 2021 at 14:01
  • @jbyrd Yes, that should be possible. You can even use Proxy if you wanted to create a transparent object, like const someObj = session.key to avoid having methods to call.
    – sfdcfox
    Apr 30, 2021 at 14:18
  • One more question related to your answer - you mentioned it would be even better to use LWCs...I thought we were using lightning web components? What are we using, and what's the difference between that and LWC?
    – jbyrd
    Apr 30, 2021 at 15:32
  • 1
    @jbyrd There's two types of lightning components, Aura and LWC (Lightning Web Component). The former, and the one in this answer, is older and non-standards-compliant. It's got quite a few quirks. LWC, on the other hand, is compatible with the Web Components Standards, which treats components like a first-class DOM element, offering much better performance and scalability. FYI, wrote a quick Proxy example for you to take a look at.
    – sfdcfox
    Apr 30, 2021 at 15:37
  • 1
    @jbyrd Yes, but there's no "UI" way to create or edit LWCs. You need to use SFDX, and it's recommended to also use an IDE, such as VS Code. Everything you need to know is in the LWC Developer Guide.
    – sfdcfox
    Apr 30, 2021 at 16:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .