LWC loadScript from static resource with export inside

javascriptlightning-web-componentsstatic-resources

I have a js library that I created static resource for it:

The js library content (the calc.js file for example) like

export default calculate = function(x,y){return x+y;}

In LWC, I import the static resource like:

import calcLib from "@salesforce/resourceUrl/calcLib";

and load it up with:

loadScript(this, calcLib+"/js/calc.js")
        .then(() => {
            debugger;
        })
        .catch((error) => {
          debugger;
          this.error = error;
        });

It's always failed loading the script with the message like:

WARNING: Failed to load script at /resource/165916882xxxx/calcLib/js/calc.js: export declarations may only appear at top level of a module [export declarations may only appear at top level of a module]

I have tried modified the library (the calc.js file) like removing export keyword and it load successfully.
I have many libraries in my system. Do I have to remove all export keyword to load them in LWC? It's really a nightmare. Is there another way to work around here?

Best Answer

Components are compiled using something like rollup or webpack; the files delivered to the browser aren't the same scripts you upload or see in your IDE, at least not directly.

If you're using a static resource, you must "export" any properties you want using the window global object:

window.calculate = function(x,y){return x+y;}

Which you can then load:

import calcLib from "@salesforce/resourceUrl/calcLib";
import { loadScript } from 'lightning/platformResourceLoader';

...

scriptsLoaded = false;
async connectedCallback()
  await loadScript(this, calcLib);
  this.scriptsLoaded = true;
}

Note that the functions won't be available until scriptsLoaded is true. If you don't want to wait for these functions to be available, you have an alternative; you can move your files to a Service Component.

By doing this, it can be bundled with everything else and loaded, and you can use your scripts verbatim without any modification; you'll just need to move your files into the lwc directory under a component folder.

First, create a new component, for example, utils:

sfdx force:lightning:component:create --type lwc -n utils -d force-app/main/default/lwc

Then, delete the HTML file, such that you only have two files left, utils.js and utils.js-meta.xml.

Now, you can copy paste your code, verbatim, into the utils.js file.

export default calculate = function(x,y){return x+y;}

Which you can then import:

import calcLib from 'c/utils';

You can also copy many files into this component, and then in your utils.js file, you can export those functions:

export * from './calc';
Related Topic