geodesy icon indicating copy to clipboard operation
geodesy copied to clipboard

"Must use import to load ES Module" problem

Open karianpour opened this issue 5 years ago • 9 comments
trafficstars

With node 12 , when I tries the sample I got the following error. It looks like it cannot import the module. Does it support node 12?

$> node -r esm
Welcome to Node.js v12.16.1.
> import LatLon from 'geodesy/latlon-spherical.js';
.../node_modules/geodesy/latlon-spherical.js:1
Uncaught:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: .../node_modules/geodesy/latlon-spherical.js
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1174:13) {
  code: 'ERR_REQUIRE_ESM'
}

karianpour avatar Apr 01 '20 13:04 karianpour

Similar issue here.

long1eu avatar Apr 02 '20 17:04 long1eu

Some very strange behaviour going on here.

I can replicate this issue on a fresh npm install using e.g. Node.js v12.16.1 – but if I switch to an earlier version (v12.15.0 or earlier), then switch back to v12.16.1, it works correctly.

$ npm install geodesy esm

Using 12.16.1 fails:

$ nvm use 12.16.1
$ node -r esm
> import LatLon from 'geodesy/latlon-spherical.js';
/tmp/node_modules/geodesy/latlon-spherical.js:1
Uncaught:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /tmp/node_modules/geodesy/latlon-spherical.js
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1174:13) {
  code: 'ERR_REQUIRE_ESM'
}
>

Switching to an earlier version works:

$ nvm use 12.15.0
$ node -r esm
> import LatLon from 'geodesy/latlon-spherical.js';
> new LatLon(51, 1)
LatLonSpherical { _lat: 51, _lon: 1 }
> 

Switching back to 12.16.1 then works:

$ nvm use 12.16.1
$ node -r esm
> import LatLon from 'geodesy/latlon-spherical.js';
> new LatLon(51, 1)
LatLonSpherical { _lat: 51, _lon: 1 }
> 

I have already logged an issue on the esm repository relating to this.

Versions prior to 12.16.0 appear to work ok (though 12.14.0 & 12.15.0 thow out an error message).

If you are able to upgrade to Node.js v13.2.0+, esm is no longer required (though import is not available in the REPL).

$ nvm use 13.2.0
$ cat test.js
import LatLon from 'geodesy/latlon-spherical.js';
console.log(new LatLon(51, 1));
$ node test.js
(node:26167) ExperimentalWarning: The ESM module loader is experimental.
LatLonSpherical { _lat: 51, _lon: 1 }
$ 

chrisveness avatar Apr 10 '20 13:04 chrisveness

It appears that ES modules can be loaded using the esm package in Node.js v8.0.0–v12.15.0, and natively in Node.js v13.2.0+. I'm not sure if the gap between those two options will ever get fixed.

chrisveness avatar May 22 '20 16:05 chrisveness

@chrisveness Is there a workaround for this issue? We are currently using it in lambda function and it is breaking with the same error? We are using node version 12.x in lambda function

montumodi avatar Jun 01 '20 07:06 montumodi

@montumodi Use v1 branch. ;) It's ES5.

jomel avatar Jun 01 '20 09:06 jomel

Thanks @jomel. We downgraded it to v1 for this but was wondering if there is any other fix or workaround available.

montumodi avatar Jun 01 '20 09:06 montumodi

Node.js is having a slightly difficult time in migrating from CJS to ESM, I think.

This library was originally ES5 for browser only. At some point I added module.export statements for it to work with Node.js. Version 2 was a major enhancement, which was only possible with ES modules (I didn't want to get involved with Babel build steps).

In Node.js, CJS & ESM have fundamental differences, which the node team are slowly reconciling.

As far as I am aware, current options for using the geodesy library are:

chrisveness avatar Jun 03 '20 10:06 chrisveness

I get the same error with node v15.3.0 and with the recommended flags enabled.

node --experimental-modules -r esm test.js
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: [...]/node_modules/geodesy/latlon-ellipsoidal-vincenty.js
    at new NodeError (node:internal/errors:278:15)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1119:13) {
  code: 'ERR_REQUIRE_ESM'
}

strarsis avatar Nov 25 '20 03:11 strarsis

Hi,

I got the same error message when trying to use V2 on CommonJs modules. Thus, I migrated to using v2 with some code changes as examples below. Basically, in recent Node versions > v12.x, you can use dynamic module loading directly. Note that dynamic ES modules loading works asynchronously.

async function Func() {
  // Dynamically load ES geodesy v2 modules.
  const llsMod = await import('geodesy2/latlon-spherical.js');
  LatLonSP = llsMod.default;
  const utmMod = await import('geodesy2/utm.js');
  Utm = utmMod.default;
  LatLon = utmMod.LatLon;

 // Then use as:
  const utm1 = new Utm(..);
  const latlng = new LatLon();
  ... 
}

mickeyjohn avatar Jul 05 '21 13:07 mickeyjohn