jackocnr / intl-tel-input

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

Export issue for upgraded version. SyntaxError: Unexpected token 'export' #1835

Closed Ryan-Boustany closed 1 month ago

Ryan-Boustany commented 1 month ago

Plugin version

v24.5.1

Description

I was running v17 of intl-tel-input library on my repo I needed the latest version of libphonenumber so I updgraded my intl-tel-input to v24. I am now receiving these bugs in my test cases that have something to do with export. Does anyone have any idea why this might be occurring.

Any assistance on this would be greatly appreciated thank you!

Expected behaviour

My tests should be running without an export issue

Actual behaviour

My tests are failing due to an export issue

Initialisation options

I am using these versions in my devDependecies: "babel": "^6.23.0", "babel-core": "^6.26.3", "babel-eslint": "^8.2.6", "babel-jest": "^23.6.0", "babel-loader": "^7.1.5", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-lodash": "^3.3.4", "babel-plugin-react-css-modules": "^3.4.2", "babel-plugin-transform-inline-imports-commonjs": "^1.2.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "@babel/core": "^7.25.2" "@babel/preset-env": "^7.25.4"

"jest": "^23.6.0", "jest-enzyme": "^6.1.2", "jest-html-reporter": "^3.10.2", "jest-slow-test-reporter": "^1.0.0" "ts-jest": "^23.0.0",

Screenshot 2024-10-03 at 10 54 32 AM
Ozberg commented 1 month ago

I'm getting the same from 24.5.0 (updating from 18.1.6)

rashadmehtab commented 1 month ago

You are currently importing intl-tel-input/build/js/utils.js, which is no longer supported. Please switch to one of the following options:

  1. intl-tel-input/build/js/intlTelInputWithUtils.js
  2. import intlTelInput from 'intl-tel-input/intlTelInputWithUtils';

For a detailed explanation on how to import the utilities correctly, please refer to this link: Loading the Utilities Script.

jackocnr commented 1 month ago

Thanks @rashadmehtab!

@Ryan-Boustany yes, as @rashadmehtab says, the problem is that you have the following line somewhere in your tests/code:

import 'intl-tel-input/build/js/utils';

Which file is that in? And what are you hoping to achieve with this? Utils has now changed so it no longer sets a global, so this approach to loading the utils will no longer work. It's now an ES module, which needs to be loaded in a particular way - again see the readme link that @rashadmehtab kindly shared 🙏🏻

Ryan-Boustany commented 1 month ago

Ive switch to importing my library to the format stated above.

Screenshot 2024-10-09 at 12 58 23 PM Screenshot 2024-10-09 at 2 05 23 PM Screenshot 2024-10-09 at 2 06 19 PM

When I run my test I see errors that appear like this:

Screenshot 2024-10-09 at 2 03 59 PM

Any suggestions?

Mr0grog commented 1 month ago

@Ryan-Boustany I’ve recently done some contributions in this area, and specifically with Jest. 😃

A few things:


The above should just work, but the downside is that it comes with the utilities module pre-loaded, which is pretty big!

If you want to load utilities asynchronously later on, making it work in Jest is unfortunately a little complicated (the async utilities script is a proper JS module, and Jest’s module support is still experimental). You’ll need to do two things to get async loading working in Jest:

  1. Run your tests with the --experimental-vm-modules node option. If you use npm run ... or npx jest ... to run your tests, the easiest way to do that is to add a line to your .npmrc file. You can see how we do that for the test here: https://github.com/jackocnr/intl-tel-input/blob/05badcaeb4ecbc4e5d7a6bec508cdb868ed4b7c5/.npmrc#L1-L3

  2. Tell jest to transform the utils.js file into CommonJS when loading it. You can see how we configure that in this repo: https://github.com/jackocnr/intl-tel-input/blob/05badcaeb4ecbc4e5d7a6bec508cdb868ed4b7c5/jest.config.js#L7-L23

    Note you’ll need to install the @babel/plugin-transform-modules-commonjs and babel-plugin-add-module-exports packages.

    You’ll probably also want to make the path that is getting transformed more specific, e.g. "intl-tel-input/build/js/utils.js$" instead of "utils.js$" (I have not tested to make sure that’s exactly right).

Then use the React module that loads async instead of preloading utils: import IntlTelInput from 'intl-tel-input/react'.

To just load the utils module directly if you don’t need the whole library, you can also do the following (pretty sure you’ll need the above Jest fixes for this, though):

import libphonenumber from 'intl-tel-input/utils';

libphonenumber.isValidNumber(...); // or whatever you want to do with it

Be careful to make sure you aren’t loading the utils twice in your bundle if you are doing this alongside the React component, though!


Side note on changes to the package that would make this easier:

@jackocnr Seeing how this affects users of this package in their tests tells me you have a better point than I thought about removing the string option for loadUtilsOnInit/loadUtils(). 😅

Another good way to make this easier for users might be to:

  1. Build 3 versions of utils.js: utils.js (same as today), utils.cjs (using UMD syntax), utils.mjs (same as utils.js). People can reference the .mjs or cjs version in tests and Jest won’t need the fancy transform; it will just do the right thing.

  2. Make loadUtils() use Promise.resolve((r) => r(require(source))) instead of import(source) if dynamic import is not available or if require is defined or something along those lines.

That way folks shouldn’t need any special Jest config for the async loading utils.

Ryan-Boustany commented 1 month ago

Thanks for the suggestions!

In another file I am importing it as such:

Screenshot 2024-10-10 at 12 10 46 PM

How would I need to change the imports for this file? @Mr0grog

Mr0grog commented 1 month ago

So, assuming you don’t want to do all the wacky stuff to get async utils working in Jest, you want to import <x> from 'intl-tel-input/<whatever>WithUtils'.

Ryan-Boustany commented 1 month ago

Thank you @Mr0grog @jackocnr and @rashadmehtab for the assistance :)