deck.gl icon indicating copy to clipboard operation
deck.gl copied to clipboard

SSR Error After Upgrading from 8.8 to 8.9

Open aemonm opened this issue 1 year ago • 30 comments

Description

After upgrading from 8.8 to 8.9 via npm update, I receive the following error when trying to build my NextJS App:

Instead change the require of index.js in /Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js:17:39)
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/text-layer/text-layer.js:32:49)
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/geojson-layer/sub-layer-map.js:16:41)
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/geojson-layer/geojson-layer.js:32:20)
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/node_modules/@deck.gl/layers/dist/es5/index.js:119:44)
    at 9801 (/Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1391:18)
    at __webpack_require__ (/Users/aemon/Worky/cerulean-ui/.next/server/webpack-runtime.js:25:42)
    at 5297 (/Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:134:79)
    at __webpack_require__ (/Users/aemon/Worky/cerulean-ui/.next/server/webpack-runtime.js:25:42)
    at /Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1093:79
    at __webpack_require__.a (/Users/aemon/Worky/cerulean-ui/.next/server/webpack-runtime.js:89:13)
    at 5075 (/Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1066:21)
    at __webpack_require__ (/Users/aemon/Worky/cerulean-ui/.next/server/webpack-runtime.js:25:42)
    at __webpack_exec__ (/Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1499:39)
    at /Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1500:28
    at Object.<anonymous> (/Users/aemon/Worky/cerulean-ui/.next/server/pages/index.js:1503:3)
    at Object.requirePage (/Users/aemon/Worky/cerulean-ui/node_modules/next/dist/server/require.js:88:12)
    at /Users/aemon/Worky/cerulean-ui/node_modules/next/dist/server/load-components.js:49:73
    at async Object.loadComponentsImpl [as loadComponents] (/Users/aemon/Worky/cerulean-ui/node_modules/next/dist/server/load-components.js:49:26)
    at async /Users/aemon/Worky/cerulean-ui/node_modules/next/dist/build/utils.js:858:32
    at async Span.traceAsyncFn (/Users/aemon/Worky/cerulean-ui/node_modules/next/dist/trace/trace.js:79:20) {
  code: 'ERR_REQUIRE_ESM'

Flavors

  • [X] React
  • [ ] Python/Jupyter notebook
  • [ ] MapboxLayer
  • [X] GoogleMapsOverlay
  • [ ] CartoLayer
  • [ ] DeckLayer/DeckRenderer for ArcGIS

Expected Behavior

After reading the Upgrade Guide, I didn't notice any breaking changes that should affect my code as it is. I should still be able to build my app.

Steps to Reproduce

I will try and supply this, but judging from the stack trace I supplied something seems to be amiss

Environment

  • Framework version: 8.9
  • Browser:
  • OS: macOS 13.2.1

Logs

No response

aemonm avatar Mar 10 '23 00:03 aemonm

+1

yosephha avatar Mar 10 '23 03:03 yosephha

Tried a few tricks to see if I could get this to work on Next v13.x.x but unfortunately none of them worked:

next.config.js

transpilePackages: ['@deck.gl/layers', '@mapbox/tiny-sdf'],
experimental: {
  esmExternals: 'loose',
},

brandonjpierce avatar Mar 10 '23 17:03 brandonjpierce

In 8.9 a few upstream dependencies are updated to their latest version, including @mapbox/tiny-sdf and d3-*. They are pure ESM modules and cannot be imported by require() from the commonjs entry point.

You may want to look into next.js config that lets you control the module resolution for server-side bundle - @deck.gl/*/dist/esm is the entry point using import/export syntax. (i.e. module instead of main in package.json)

Whatever the solution is, we cannot go backward on these dependencies. Security vulnerabilities in those libraries are not fixed in the old versions.

Edit: I spent a little time poking around and it doesn't seem easy to override next's webpack configs. At this point I would recommend isolating your deck.gl-related imports and exclude it from SSR:

/// components/deck-map.js
import DeckGL, {TextLayer} from 'deck.gl';

export default function DeckMap() {
  return <DeckGL ... />
}

/// pages/index.js
import dynamic from 'next/dynamic';
const DeckMap = dynamic(() => import('../components/deck-map'), {
  ssr: false
});

export default function Home() {
  return <DeckMap />;
}

deck.gl renders into a WebGLContext so it wouldn't benefit from SSR anyways.

Pessimistress avatar Mar 10 '23 18:03 Pessimistress

@Pessimistress: I'm loading DeckGL (v8.9.2) and NebulaGL with a dynamic import (ssr: false), but I still get this issue when I build next build (v13.2.4)

DonovanCharpin avatar Mar 15 '23 15:03 DonovanCharpin

@DonovanCharpin The problem is not the DeckGL component. You cannot import any layer that reference the above mentioned modules (e.g. TextLayer, GeoJsonLayer, MVTLayer) on the server side.

Pessimistress avatar Mar 15 '23 17:03 Pessimistress

@Pessimistress my component contains a map and is loaded dynamically (not ssr)

const MyMap = dynamic(
  () => import("../../components/react-map-gl/static-react-map-gl.component"),
  {
    ssr: false,
  }
);

This component imports BitmapLayer, GeoJsonLayer, IconLayer and TextLayer from @deck.gl/layers. At build time, it still breaks. I'm not able to build the nextjs app that I'm able to do with next13 and deck v8.8.

DonovanCharpin avatar Mar 15 '23 18:03 DonovanCharpin

@DonovanCharpin Look at the trace stack of the error and it will tell you which component is doing the problematic import. Sorry I can't be of more assistance because I can only speculate based on your description.

Pessimistress avatar Mar 15 '23 18:03 Pessimistress

@Pessimistress The stack was mainly the same as the one shared above. I will post my stack here as well if it can help. But basically, I don't use deckGL outside of this component and this component is not loaded on SSR, so I'm not sure what would be wrong.

DonovanCharpin avatar Mar 15 '23 18:03 DonovanCharpin

I was able to confirm the fix proposed by @Pessimistress worked for us. We have a similar sounding setup @DonovanCharpin

src/pages/index.tsx --> where we do the dynamic import
src/app.tsx --> where deck.gl and layer imports live, no dynamic imports
src/layers/thing.ts --> imported in the above file

brandonjpierce avatar Mar 15 '23 22:03 brandonjpierce

I ran into this with vitest as well due to https://github.com/vitest-dev/vitest/issues/2834. Adding alias: [{ find: /^@deck.gl\/layers$/, replacement: "@deck.gl/layers/dist/esm" }], to vite.config resolved it.

asdfjkalsdfla avatar Mar 24 '23 21:03 asdfjkalsdfla

You're awesome! This has solved my deployment issue! <3

x17Andrew71x avatar Mar 31 '23 15:03 x17Andrew71x

I've tried,seems to be working. "@deck.gl/layers": "^8.9.7" "next": "^13.3.0"

fromwhite avatar Apr 15 '23 10:04 fromwhite

None of the above works for me !

mapsgeek avatar Apr 15 '23 11:04 mapsgeek

@fromwhite can you share your component and config setup?

mapsgeek avatar Apr 15 '23 11:04 mapsgeek

It doesn't work for me

xap5xap avatar Apr 15 '23 15:04 xap5xap

INDEX: image

MAP: image

x17Andrew71x avatar Apr 15 '23 17:04 x17Andrew71x

@fromwhite can you share your component and config setup?

I have disabled SSR now. next.config.js

fromwhite avatar Apr 16 '23 02:04 fromwhite

This is quite niche but I also encountered this issue using rakkas framework. I've tried to do what's described here but nothing helped, until I moved the piece of code that was using useServerSideQuery in the component to the separate file. So now deck.gl won't get imported on the server-side. It took me quite some time to figure out why it was having the issue in the first place, since I replaced all the imports of the component in question with the ClientSuspense and React.lazy.

sliterok avatar Apr 16 '23 09:04 sliterok

@x17Andrew71x this weird because i tried it before and it didn't work but made a new project and worked for some reason!!

mapsgeek avatar Apr 16 '23 11:04 mapsgeek

@x17Andrew71x this weird because i tried it before and it didn't work but made a new project and worked for some reason!!

That's great that you got it, my guess would be there's a version difference somewhere in the installed packages.

x17Andrew71x avatar Apr 16 '23 11:04 x17Andrew71x

Hello, I have created a repo to reproduce the problem and how to fix this thanks to @Pessimistress  This repo was created with latest code (by the time it was written) NextJS 13.3.0 and DeckGL 8.9.8

There are 2 pages: index and working

The index page throws the error described in this issue:

Error: require() of ES Module /project/deckgl-error/node_modules/@mapbox/tiny-sdf/index.js from /project/deckgl-error/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js not supported.

The page working is refactored in order to move the deckgl code to a component and dynamically import that component with ssr:false

I hope there is a better way to do this. We have a big app and the refactoring will take some time.

PS: If you want to see the map, you have to enter your mapbox token in the MAPBOX_ACCESS_TOKEN variable

Github: https://github.com/xap5xap/deckgl-error

codeSandbox: code

xap5xap avatar Apr 20 '23 19:04 xap5xap

Hey guys,

I still have the issue with the latest version. I'm importing the map dynamically (ssr:false) and I'm using these imports in the map component:

import DeckGL from "@deck.gl/react";
import { BitmapLayer, IconLayer, TextLayer } from "@deck.gl/layers";

Could this be linked? Here is the stack I get when I run a next build. Also, I'm using pnpm

require() of ES Module /xxx/node_modules/.pnpm/@[email protected]/node_modules/@mapbox/tiny-sdf/index.js from /xxx/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js not supported.
Instead change the require of index.js in /xxx/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js to a dynamic import() which is available in all CommonJS modules.

DonovanCharpin avatar Apr 24 '23 20:04 DonovanCharpin

@DonovanCharpin Be sure you are dynamically importing everywhere in your code. Probably theres is a "component" that is importing deckgl packages without the ssr

xap5xap avatar Apr 24 '23 20:04 xap5xap

@xap5xap I found the issue... You are right, there was a constant export.

export const META_TOOLTIP_TYPES = [...]

that was used in another part of the code and created the issue shared previously! This is a good catch because I will check all my dynamic imports now!

DonovanCharpin avatar Apr 24 '23 20:04 DonovanCharpin

Seems it might still be an issue with aggregation layers.

The above fix works but as soon as I try and use the HexagonLayer import { HexagonLayer } from '@deck.gl/aggregation-layers/typed' It'll break

theonlydaleking avatar Jun 04 '23 02:06 theonlydaleking

For people with a vitest issue about an ESM import, if alias failed then you can try this in your vitest.setup.tsx file in order to mock it (this solution works only if you do not need to test rendering things):

beforeAll(() => {
  vitest.mock('@deck.gl/layers/typed', () => {
    return {
      default: () => {},
      GeoJsonLayer: class GeoJsonLayer{},
      PathLayer: class PathLayer{},
      TextLayer: class TextLayer{},
      // ... whatever layers you are using
    }
  })
})

Hope it helps :)

erwanlfrt avatar Jun 06 '23 08:06 erwanlfrt

For a NextJS setup, adding 'use client' at the top of the file importing deck.gl (components/deck-map.js in this example) solved the problem for me.

See https://nextjs.org/docs/app/building-your-application/rendering/client-components

danielzohar avatar Sep 20 '23 12:09 danielzohar

I still have the issue, and as @theonlydaleking said, there might be an issue with aggregation layers. Here is my stack with next 14.0

✓ Ready in 2.6s
○ Compiling /[spaceDomain]/book-a-room/[[...entity]] ...
⨯ ./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js:17:0
Module not found: ESM packages (@mapbox/tiny-sdf) need to be imported. Use 'import' to reference the package instead. https://nextjs.org/docs/messages/import-esm-externals

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/text-layer.js
./node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/index.js
./src/components/react-map-gl/static-react-map-gl.component.js
./pages/[spaceDomain]/book-a-room/[[...entity]].js

My files are all imported dynamically with dynamic, and I even tested "use client"; with no luck. I did not upgrade deck.gl to 8.9.32, I just upgraded next.js to v14. Everything works fine with next.js 13.4.19 (I think it starts not working with 13.5.x btw) and deck 8.9.26.

Also, the stack above specifies deck gl 8.9.32 which is different from the version I have in local.

I tried also the other solutions above with transpile etc.

UPDATE

Nevermind, I had to install @deck.gl/layers, it was working with just deck.gl before.

DonovanCharpin avatar Oct 27 '23 02:10 DonovanCharpin

I struggled with this issue for a quite a while with none of the solutions here working for me. Eventually I stumbled into this section of the docs for anyone also having issues.

// src/components/map.js
import DeckGL, {TextLayer} from 'deck.gl';

export default function Map() {
  return <DeckGL ... />
}
//src/pages/app.js
import dynamic from 'next/dynamic';
const Map = dynamic(() => import('../components/map'), {ssr: false});

export default function App() {
  return <Map />;
}

Filimoa avatar Nov 18 '23 19:11 Filimoa

I ran into this with vitest as well due to vitest-dev/vitest#2834. Adding alias: [{ find: /^@deck.gl\/layers$/, replacement: "@deck.gl/layers/dist/esm" }], to vite.config resolved it.

this does not work for me Error: require() of ES Module /Users/alejandromorales/Documents/orix/pa-monorepo/node_modules/.pnpm/@[email protected]/node_modules/@mapbox/tiny-sdf/index.js from /Users/alejandromorales/Documents/orix/pa-monorepo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js not supported. Instead change the require of index.js in /Users/alejandromorales/Documents/orix/pa-monorepo/node_modules/.pnpm/@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]/node_modules/@deck.gl/layers/dist/es5/text-layer/font-atlas-manager.js to a dynamic import() which is available in all CommonJS modules. is what get any ideas?

alemor10 avatar Jan 10 '24 21:01 alemor10