jackocnr / intl-tel-input

A JavaScript plugin for entering and validating international telephone numbers. React and Vue components are also included.
https://intl-tel-input.com
MIT License
7.59k stars 1.94k forks source link

Issue in Salesforce with dynamic import of utils.js #1680

Closed forceclihk closed 2 months ago

forceclihk commented 3 months ago

We have successfully been using int-tel-input in Salesforce for many years by uploading it into Salesforce. In v23.0.0, a significant change was made regarding the utils script:

**utilsScript option and loadUtils method now load the utils script using a dynamic import as opposed to injecting a new script tag. To make this work, the utils script (build/js/utils.js) is now an ES Module, which no longer uses any globals, like window.intlTelInputUtils (etc). This means it will no longer work to pre-load the utils script yourself, hence the new bundles (see next point).

For those who are not worried about file size, we now provide two bundles which include the utils script: build/js/intlTelInputWithUtils.js and react/build/IntlTelInputWithUtils.js. If you're using ES Modules, you can import these as "intl-tel-input/intlTelInputWithUtils" and "intl-tel-input/reactWithUtils" respectively (TypeScript types included in the regular declaration files).**

This is causing issues with Salesforce, even with the bundled version. Even though the bundled version never reaches the line in the code which does the dynamic import, Salesforce now does not load the javascript because of the mere presence of the 'import' statement. In the JS console, we see this error when we try and load the script:

Failed to load script at xxx: possible import expression rejected around line yyy

So our ask is this: can we get a version of the bundled file which does not have the 'import' statement at all?

jackocnr commented 3 months ago

So our ask is this: can we get a version of the bundled file which does not have the 'import' statement at all?

Dynamic imports are perfectly valid JavaScript, which will run in all modern browsers. I don't want to add the complexity of building a separate version of the plugin just because your build system doesn't like some valid JavaScript.

Can you tell me what bundler/version/config you're using? Maybe there will be an easy solution to make your build system accept/ignore this line?

forceclihk commented 3 months ago

Can you tell me what bundler/version/config you're using? Maybe there will be an easy solution to make your build system accept/ignore this line?

Sure, we are using V23.1.0. The bundler we are using is build/js/intlTelInputWithUtils.js. This article shows how 3rd party JS libraries can be used with Salesforce, specifically with LightningWebComponents, which is our use case: https://developer.salesforce.com/docs/platform/lwc/guide/js-third-party-library.html

forceclihk commented 3 months ago

So after a few Googles on that error message, the issue may be that webpack is not correctly removing the 'import' statement when the bundle is created.

jackocnr commented 3 months ago

Instead of build/js/intlTelInputWithUtils.js, can you try using build/js/intlTelInputWithUtils.min.js instead and see if that fixes the issue?

jackocnr commented 2 months ago

Closing due to inactivity.

jackocnr commented 2 months ago

@forceclihk I've just released v23.1.2 which removes the dynamic import in any build file that already includes utils. Can you give that a try and let me know if it fixes the issue for you?

forceclihk commented 2 months ago

@jackocnr We are in the process of testing this, and will let you know if it fixes the issue. In the meantime, we have come across another issue with the dynamic import change. Prior to this, we were able to use the variable intlTelInputUtils directly. We can no longer do this. We have a couple of places where we were using it directly because we did not have access to the input field itself as an HTML element, but only the value of what the user inputs(this is due to how certain Salesforce features work). So we need to modify our code to use an HTML element as a parameter to the intlTelInput constructor. Right now we are doing this by using document.createElement() to create a "dummy" element, which we then pass into the constructor. This seems to be working, but is rather kludgy. Do you have a better/best practice you can recommend for this?

jackocnr commented 2 months ago

Prior to this, we were able to use the variable intlTelInputUtils directly. We can no longer do this.

So previously, you would have loaded utils.js onto the page and then accessed it via window.intlTelInputUtils. Now, if you load intlTelInputWithUtils.js onto the page, you can then access the utils via window.intlTelInput.utils, or if you're importing the module into your code with something like this import intlTelInput from "intl-tel-input/intlTelInputWithUtils" then you can access utils via intlTelInput.utils. Does that make sense?

forceclihk commented 2 months ago

Yes it makes sense, will try it and let you know if it works.