visgl/react-map-gl

[Bug] Release ESM compliant package (was: Does not build with AstroJS)

tordans opened this issue · 8 comments

Description

Using ReactMapGL within an AstroJS Project (https://docs.astro.build/) does work great in Dev mode but fails on build npm run build.

It looks like #2268 is partial solution but the *.mjs part that was mentioned in this PR is still required to get it working.


Test 1: import ReactMapGl, { NavigationControl } from 'react-map-gl/maplibre'

Using the standard import does result is errors like this:

CODE: https://github.com/tordans/berlin-bikenetwork-monitoring/blob/0704fe8a517e75669154e1bf2a9e5ec0ca810da8/src/components/Map/Map.tsx

generating static routes 
 error   Directory import '/home/runner/work/berlin-bikenetwork-monitoring/berlin-bikenetwork-monitoring/node_modules/react-map-gl/maplibre' is not supported resolving ES modules imported from /home/runner/work/berlin-bikenetwork-monitoring/berlin-bikenetwork-monitoring/dist/chunks/pages/index.astro.40918a6a.mjs
  Did you mean to import react-map-gl/dist/es5/exports-maplibre.js?
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/home/runner/work/berlin-bikenetwork-monitoring/berlin-bikenetwork-monitoring/node_modules/react-map-gl/maplibre' is not supported resolving ES modules imported from /home/runner/work/berlin-bikenetwork-monitoring/berlin-bikenetwork-monitoring/dist/chunks/pages/index.astro.40918a6a.mjs
Did you mean to import react-map-gl/dist/es5/exports-maplibre.js?
    at new NodeError (node:internal/errors:405:5)
    at finalizeResolution (node:internal/modules/esm/resolve:317:17)
    at moduleResolve (node:internal/modules/esm/resolve:943:10)
    at defaultResolve (node:internal/modules/esm/resolve:1129:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:835:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:[76](https://github.com/tordans/berlin-bikenetwork-monitoring/actions/runs/6063858792/job/16451685579#step:3:80):36)

Test 2: import ReactMapGl, { NavigationControl } from 'react-map-gl/dist/es5/exports-maplibre.js'

Following the advice of the error output from test 1 …

CODE: tordans/berlin-bikenetwork-monitoring@d390bbf

This fails with:

% npm run build

> astro@0.0.1 build
> astro build

21:32:55 [content] No content directory found. Skipping type generation.
21:32:55 [build] output target: static
21:32:55 [build] Collecting build info...
21:32:55 [build] Completed in 75ms.
21:32:55 [build] Building static entrypoints...
[commonjs--resolver] Missing "./dist/es5/exports-maplibre.js" specifier in "react-map-gl" package
 error   Missing "./dist/es5/exports-maplibre.js" specifier in "react-map-gl" package
  File:
    /Users/foo/berlin-bikenetwork-monitoring/node_modules/vite/dist/node/chunks/dep-df561101.js:21420:25
  Code:
    > 21420 | function e(e,n,r){throw new Error(r?`No known conditions for "${n}" specifier in "${e}" package`:`Missing "${n}" specifier in "${e}" package`)}function n(n,i,o,f){let s,u,l=r(n,o),c=function(e){let n=new Set(["default",...e.conditions||[]]);return e.unsafe||n.add(e.require?"require":"import"),e.unsafe||n.add(e.browser?"browser":"node"),n}(f||{}),a=i[l];if(void 0===a){let e,n,r,t;for(t in i)n&&t.length<n.length||("/"===t[t.length-1]&&l.startsWith(t)?(u=l.substring(t.length),n=t):t.length>1&&(r=t.indexOf("*",1),~r&&(e=RegExp("^"+t.substring(0,r)+"(.*)"+t.substring(1+r)).exec(l),e&&e[1]&&(u=e[1],n=t))));a=i[n];}return a||e(n,l),s=t(a,c),s||e(n,l,1),u&&function(e,n){let r,t=0,i=e.length,o=/[*]/g,f=/[/]$/;for(;t<i;t++)e[t]=o.test(r=e[t])?r.replace(o,n):f.test(r)?r+n:r;}(s,u),s}function r(e,n,r){if(e===n||"."===n)return ".";let t=e+"/",i=t.length,o=n.slice(0,i)===t,f=o?n.slice(i):n;return "#"===f[0]?f:o||!r?"./"===f.slice(0,2)?f:"./"+f:f}function t(e,n,r){if(e){if("string"==typeof e)return r&&r.add(e),[e];let i,o;if(Array.isArray(e)){for(o=r||new Set,i=0;i<e.length;i++)t(e[i],n,o);if(!r&&o.size)return [...o]}else for(i in e)if(n.has(i))return t(e[i],n,r)}}function o(e,r,t){let i,o=e.exports;if(o){if("string"==typeof o)o={".":o};else for(i in o){"."!==i[0]&&(o={".":o});break}return n(e.name,o,r||".",t)}}function f(e,r,t){if(e.imports)return n(e.name,e.imports,r,t)}
            |                         ^
      21422 | // This file was generated. Do not modify manually!
      21423 | var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
  Stacktrace:…

Test 3 Modify package and `import * as reactmapgl``

I overwrote my node_modules/react-map-gl/package.json based on https://github.com/visgl/react-map-gl/pull/2268/files and updated the imports.

CODE: tordans/berlin-bikenetwork-monitoring@e54fb18

% npm run build

> astro@0.0.1 build
> astro build

21:24:31 [content] No content directory found. Skipping type generation.
21:24:31 [build] output target: static
21:24:31 [build] Collecting build info...
21:24:31 [build] Completed in 68ms.
21:24:31 [build] Building static entrypoints...
21:24:32 [build] Completed in 709ms.

 building client

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
Completed in 1.44s.


 generating static routes
(node:35348) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/dist/esm/exports-maplibre.js:1
import * as React from 'react';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1178:20)
    at Module._compile (node:internal/modules/cjs/loader:1220:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Node.js v18.16.1

Example of the change

--- a/src/components/Map/Map.tsx
+++ b/src/components/Map/Map.tsx
@@ -2,7 +2,7 @@ import maplibregl from 'maplibre-gl'
 import 'maplibre-gl/dist/maplibre-gl.css'
 import * as pmtiles from 'pmtiles'
 import { useEffect } from 'react'
-import ReactMapGl, { NavigationControl } from 'react-map-gl/dist/es5/exports-maplibre.js'
+import * as reactmapgl from 'react-map-gl/maplibre'
 import { $mapLoaded } from '../store'
 import { MapSourceBoundaries } from './MapSourceBoundaries'
 import { MapSourceMonitoring } from './MapSourceMonitoring'
@@ -17,7 +17,7 @@ export const Map = () => {
   }, [])

   return (
-    <ReactMapGl
+    <reactmapgl.Map
       initialViewState={{
         longitude: 13.390386527027175,
         latitude: 52.5180225850377,
@@ -31,8 +31,8 @@ export const Map = () => {
     >
       <MapSourceBoundaries />
       <MapSourceMonitoring />
-      <NavigationControl showCompass={false} position="top-right" />
+      <reactmapgl.NavigationControl showCompass={false} position="top-right" />
       {/* <MapData /> */}
-    </ReactMapGl>
+    </reactmapgl.Map>

Expected Behavior

No response

Steps to Reproduce

Environment

"maplibre-gl": "^3.3.1",
"@astrojs/react": "^3.0.0",
"react-map-gl": "^7.1.5",

Logs

No response

I also experienced the same issue trying to run yarn build with my wepback prod config when trying to upgrade to v7.1. Worked great with the dev config.

FYI, "bun" does not work as a workaround for the AstroJS case.

Longer FYI: After reading https://youtu.be/dWqNgzZwVJQ?si=rK9KsaYgIw74BU1Q&t=140 which claims that bun is super smart about resolving commonJs <> ES Modules issues, I wanted to try if it would resolve the given issue. It was super easy to switch to bun (Docs https://docs.astro.build/de/recipes/bun/) however, I still get the same error messages:

bun run build

Error output

berlin-bikenetwork-monitoring % bun run build
$ astro build
05:55:49 [content] No content directory found. Skipping type generation.
05:55:49 [build] output target: static
05:55:49 [build] Collecting build info...
05:55:49 [build] Completed in 64ms.
05:55:49 [build] Building static entrypoints...
05:55:50 [build] Completed in 634ms.

building client
generating static routes
(node:43081) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use node --trace-warnings ... to show where the warning was created)
/Users/fmc/Development/OSM/berlin-bikenetwork-monitoring/node_modules/react-map-gl/dist/esm/exports-maplibre.js:1
import * as React from 'react';
^^^^^^

SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:73:18)
at wrapSafe (node:internal/modules/cjs/loader:1178:20)
at Module._compile (node:internal/modules/cjs/loader:1220:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at ModuleWrap. (node:internal/modules/esm/translators:169:29)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Node.js v18.16.1
error: script "build" exited with code 1 (SIGHUP)

However, one positive thing is, I get the same error on bun run start which at least makes the dev env broken the same ways as the build :-).

I found a workaround for my Issue in AstroJS using "bun":

(Sorry, I commented previously that this did not work, but it does…)

After "reading" https://youtu.be/dWqNgzZwVJQ?si=rK9KsaYgIw74BU1Q&t=140 which claims that bun is super smart about resolving commonJs <> ES Modules issues, I wanted to try if it would resolve the given issue.

One can use https://docs.astro.build/de/recipes/bun/ as a guide to switch to bun. However, you also need to delete your package-lock and your /node_modules in order to get the full usage of bun.

I then get the same error as before …

error   Directory import '/Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/maplibre' is not supported resolving ES modules imported from /Users/foo/berlin-bikenetwork-monitoring/dist/chunks/pages/index_3ae0f0cd.mjs
  Did you mean to import react-map-gl/dist/es5/exports-maplibre.js?
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/maplibre' is not supported resolving ES modules imported from /Users/foo/berlin-bikenetwork-monitoring/dist/chunks/pages/index_3ae0f0cd.mjs
Did you mean to import react-map-gl/dist/es5/exports-maplibre.js?
    at new NodeError (node:internal/errors:399:5)
    at finalizeResolution (node:internal/modules/esm/resolve:319:17)
    at moduleResolve (node:internal/modules/esm/resolve:945:10)
    at defaultResolve (node:internal/modules/esm/resolve:1153:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36)
error: script "build" exited with code 1 (SIGHUP)

However, this time following the suggestion is a valid work around, so after applying…

-import * as reactmapgl from 'react-map-gl/maplibre'
+import * as reactmapgl from 'react-map-gl/dist/es5/exports-maplibre.js'

on all files, the build works 🥳 .


FYI with this setup, the error message when using the "regular" import like import { Layer, Source } from 'react-map-gl' is

Error message
▶ src/pages/index.astro
node:internal/modules/cjs/loader:1077
  const err = new Error(message);
              ^

Error: Cannot find module 'mapbox-gl'
Require stack:
- /Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/dist/es5/exports-mapbox.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at /Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/dist/es5/exports-mapbox.js:30:58 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/foo/berlin-bikenetwork-monitoring/node_modules/react-map-gl/dist/es5/exports-mapbox.js'
  ]
}

Node.js v18.16.1
error: script "build" exited with code 1 (SIGHUP

We will need to build the source differently if we want to switch to a proper ESM module, not just modify package.json. I can get a 7.2.0-beta release for testing. There are so many bundlers and build environments now it's hard to test them all.

@csdiehl I'd appreciate a repo that reproduces your issue with webpack.

Try 7.2.0-beta.1

@Pessimistress it looks like this solves all issues! I was able to build and deploy using bun in https://github.com/tordans/berlin-bikenetwork-monitoring

Thanks a lot!

@Pessimistress a quick update on my testing of beta.1: I found no issues.

However, I just watched https://www.youtube.com/watch?v=jmNuEEtwkD4 and the docs made me aware of those testing pages … which still show some errors…

The publint.dev looks most helpfull.

Tool Official Beta.1
arethetypeswrong.github.io Link – one generic error Link – 4 errors
publint.dev Link – a few things Link – this one looks the most useful. Three errors with clear instructions on how to fix them.

@tordans Thanks for the pointers. They are quite useful indeed.