plouc / nivo

nivo provides a rich set of dataviz components, built on top of the awesome d3 and React libraries
https://nivo.rocks
MIT License
13.22k stars 1.03k forks source link

v0.81.0 can lead to import issues #2310

Open plouc opened 1 year ago

plouc commented 1 year ago

Related to:

What's the issue?

Users of nivo are experiencing import issues since the release 0.81.0, this is due to a breaking change in d3-color, which was updated due to security issues.

Most D3 packages are now esm only and d3-color is one of them, other libraries depending on D3 experienced the same problem, victory even wrote a post about this explaining it in details, and visx has an opened issue about it.

Nivo provides esm/cjs/umd, but only esm can be supported now due to this change, and it also seems that sometimes people get the cjs version rather than the esm one, that's another thing that needs to be fixed.

What should I do?

Aeolun commented 1 year ago

It's a bit bizarre, but maybe it's possible to change the import for d3-scale/color to the victory-vendor package that transpiles the d3 dependencies to CJS if necessary?

leeuwd commented 1 year ago

Nivo 1.83.0:

Error: require() of ES Module [redacted]/node_modules/@nivo/colors/node_modules/d3-color/src/index.js from  [redacted]/node_modules/@nivo/colors/dist/nivo-colors.cjs.js not supported.
Instead change the require of index.js in  [redacted]/node_modules/@nivo/colors/dist/nivo-colors.cjs.js to a dynamic import() which is available in all CommonJS modules.
sroussey commented 1 year ago

Still on 0.80.0 because of this.

APIWT commented 1 year ago

I'm a little confused -- even after updating to 0.81.0, npm audit shows the high vunerability in d3-color:

npm audit
# npm audit report

d3-color  <3.1.0
Severity: high
d3-color vulnerable to ReDoS - https://github.com/advisories/GHSA-36jr-mh4h-2g58
fix available via `npm audit fix --force`
Will install @nivo/bar@0.55.0, which is a breaking change
node_modules/d3-interpolate/node_modules/d3-color
node_modules/d3-scale-chromatic/node_modules/d3-color
  d3-interpolate  0.1.3 - 2.0.1
  Depends on vulnerable versions of d3-color
  node_modules/d3-interpolate
    @nivo/core  *
    Depends on vulnerable versions of @nivo/tooltip
    Depends on vulnerable versions of d3-interpolate
    Depends on vulnerable versions of d3-scale
    Depends on vulnerable versions of d3-scale-chromatic
    node_modules/@nivo/core
      @nivo/axes  *
      Depends on vulnerable versions of @nivo/core
      Depends on vulnerable versions of @nivo/scales
      node_modules/@nivo/axes
        @nivo/bar  *
        Depends on vulnerable versions of @nivo/annotations
        Depends on vulnerable versions of @nivo/axes
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/scales
        Depends on vulnerable versions of @nivo/tooltip
        Depends on vulnerable versions of d3-scale
        node_modules/@nivo/bar
        @nivo/line  0.33.1-0.34.0-0.0 - 0.34.0-1 || >=0.47.0
        Depends on vulnerable versions of @nivo/annotations
        Depends on vulnerable versions of @nivo/axes
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/scales
        Depends on vulnerable versions of @nivo/tooltip
        Depends on vulnerable versions of @nivo/voronoi
        node_modules/@nivo/line
      @nivo/colors  *
      Depends on vulnerable versions of @nivo/core
      Depends on vulnerable versions of d3-scale
      Depends on vulnerable versions of d3-scale-chromatic
      node_modules/@nivo/colors
        @nivo/annotations  *
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        node_modules/@nivo/annotations
          @nivo/scatterplot  *
          Depends on vulnerable versions of @nivo/annotations
          Depends on vulnerable versions of @nivo/axes
          Depends on vulnerable versions of @nivo/colors
          Depends on vulnerable versions of @nivo/core
          Depends on vulnerable versions of @nivo/legends
          Depends on vulnerable versions of @nivo/scales
          Depends on vulnerable versions of @nivo/tooltip
          Depends on vulnerable versions of @nivo/voronoi
          Depends on vulnerable versions of d3-scale
          node_modules/@nivo/scatterplot
        @nivo/arcs  *
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        node_modules/@nivo/arcs
        @nivo/radar  *
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/tooltip
        Depends on vulnerable versions of d3-scale
        node_modules/@nivo/radar
        @nivo/radial-bar  *
        Depends on vulnerable versions of @nivo/arcs
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/polar-axes
        Depends on vulnerable versions of @nivo/scales
        Depends on vulnerable versions of @nivo/tooltip
        Depends on vulnerable versions of d3-scale
        node_modules/@nivo/radial-bar
        @nivo/sankey  >=0.47.0
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/tooltip
        node_modules/@nivo/sankey
        @nivo/swarmplot  *
        Depends on vulnerable versions of @nivo/annotations
        Depends on vulnerable versions of @nivo/axes
        Depends on vulnerable versions of @nivo/colors
        Depends on vulnerable versions of @nivo/core
        Depends on vulnerable versions of @nivo/legends
        Depends on vulnerable versions of @nivo/scales
        Depends on vulnerable versions of @nivo/tooltip
        Depends on vulnerable versions of @nivo/voronoi
        Depends on vulnerable versions of d3-scale
        node_modules/@nivo/swarmplot
      @nivo/legends  >=0.56.0
      Depends on vulnerable versions of @nivo/core
      node_modules/@nivo/legends
      @nivo/polar-axes  *
      Depends on vulnerable versions of @nivo/arcs
      Depends on vulnerable versions of @nivo/core
      Depends on vulnerable versions of @nivo/scales
      node_modules/@nivo/polar-axes
      @nivo/tooltip  *
      Depends on vulnerable versions of @nivo/core
      node_modules/@nivo/tooltip
      @nivo/voronoi  >=0.47.0
      Depends on vulnerable versions of @nivo/core
      Depends on vulnerable versions of d3-scale
      node_modules/@nivo/voronoi
    d3-scale  0.1.5 - 3.3.0
    Depends on vulnerable versions of d3-interpolate
    node_modules/@nivo/bar/node_modules/d3-scale
    node_modules/@nivo/colors/node_modules/d3-scale
    node_modules/@nivo/core/node_modules/d3-scale
    node_modules/@nivo/radar/node_modules/d3-scale
    node_modules/@nivo/radial-bar/node_modules/d3-scale
    node_modules/@nivo/scales/node_modules/d3-scale
    node_modules/@nivo/scatterplot/node_modules/d3-scale
    node_modules/@nivo/swarmplot/node_modules/d3-scale
    node_modules/@nivo/voronoi/node_modules/d3-scale
      @nivo/scales  *
      Depends on vulnerable versions of d3-scale
      node_modules/@nivo/scales
    d3-scale-chromatic  0.1.0 - 2.0.0
    Depends on vulnerable versions of d3-color
    Depends on vulnerable versions of d3-interpolate
    node_modules/d3-scale-chromatic

21 high severity vulnerabilitie

Am I needing to pin all the d3-* packages to the latest manually? I only take these on as a transient dependency via @nivo packages.

Thanks!

plouc commented 1 year ago

It seems like some other d3 packages are installing a different version, but you shouldn't pin all d3 packages to the latest version manually (or at your own risk 😅), there might be some incompatibilities with the current codebase.

Also the nivo versions I see in your report are a bit weird, all versions should be aligned, and @nivo/bar@0.55.0 is pretty old.

plouc commented 1 year ago

@APIWT, I'm upgrading d3-scale, d3-scale-chromatic and d3-interpolate in #2337.

APIWT commented 1 year ago

It seems like some other d3 packages are installing a different version, but you shouldn't pin all d3 packages to the latest version manually (or at your own risk 😅), there might be some incompatibilities with the current codebase.

Also the nivo versions I see in your report are a bit weird, all versions should be aligned, and @nivo/bar@0.55.0 is pretty old.

You know what is strange? My package.json doesn't even reference such an old version:

    "@nivo/bar": "0.81.0",
    "@nivo/core": "0.81.0",
    "@nivo/line": "0.81.0",
    "@nivo/radar": "0.81.0",
    "@nivo/radial-bar": "0.81.0",
    "@nivo/sankey": "0.81.0",
    "@nivo/scatterplot": "0.81.0",
    "@nivo/swarmplot": "0.81.0",

I can share the rest privately if it helps, but really my stuff is mostly up to date, and my package-lock does not reference 0.55 of @nivo/bar anywhere

tony-cocco commented 1 year ago

Also hitting this issue. The temporary fix from the next.js documentation relating to esmExternals did not resolve this issue for us.

Attempting to update to nivo*:0.83.0 using next:13.3.1.

kamimoo commented 1 year ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

From

import { ResponsiveLine } from "@nivo/line";

to

import dynamic from "next/dynamic";

const ResponsiveLine = dynamic(() => import("@nivo/line").then(m => m.ResponsiveLine), { ssr: false });

In my case, I'm using next/dynamic to import custom components that use nivo, and it works fine.

robsonmvieira commented 1 year ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

From

import { ResponsiveLine } from "@nivo/line";

to

import dynamic from "next/dynamic";

const ResponsiveLine = dynamic(() => import("@nivo/line").then(m => m.ResponsiveLine), { ssr: false });

In my case, I'm using next/dynamic to import custom components that use nivo, and it works fine.

Amazing my friend. This is save my time. I spended my time looking for solutions.

Thanks man!

unblockgames commented 1 year ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

From

import { ResponsiveLine } from "@nivo/line";

to

import dynamic from "next/dynamic";

const ResponsiveLine = dynamic(() => import("@nivo/line").then(m => m.ResponsiveLine), { ssr: false });

In my case, I'm using next/dynamic to import custom components that use nivo, and it works fine.

OMG OMG OMG. You are a KING.

elie222 commented 1 year ago

That worked for me too:

import { BarDatum } from '@nivo/bar';
import dynamic from 'next/dynamic';

const ResponsiveBar = dynamic(() => import('@nivo/bar').then(m => m.ResponsiveBar), { ssr: false });
ryanovas commented 1 year ago

Is there anything in the works to fix this? Cause this is a big problem..

AnnieTaylorCHEN commented 1 year ago

Any fix for us who doesn't use Next but just plain React 18?

shehi commented 1 year ago

@plouc , any hope for this to be fixed? Even dynamically importing the package in NextJs requires compromises (e.g. disabling SSR) which is something undesired. My landing pages shouldn't be having loading stages in them - SSR is very valuable.

tnovas commented 1 year ago

The only way I get was install victory-vendor dependency and with npm 8 use overrides, like this:

  "dependencies": {
   ...
    "victory-vendor": "36.6.11"
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

But this is workaround, we need an internal solution.

stahlmanDesign commented 1 year ago

In NextJS 13.4.8 using the app router, the problem went away when I specified 'use client' at the top of the component

coderdix24 commented 1 year ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

From

import { ResponsiveLine } from "@nivo/line";

to

import dynamic from "next/dynamic";

const ResponsiveLine = dynamic(() => import("@nivo/line").then(m => m.ResponsiveLine), { ssr: false });

In my case, I'm using next/dynamic to import custom components that use nivo, and it works fine.

legend

shahdivyank commented 1 year ago

In NextJS 13.4.8 using the app router, the problem went away when I specified 'use client' at the top of the component

This works for me! Using NextJS v13.4.9 and Nico v0.83.0

murenkot commented 1 year ago

I rolled back to 0.80.0 and it seems to work. But I hope for a better solution 🙏🏻

Jule- commented 1 year ago

@plouc could you update d3-scale-chromatic and d3-interpolate in order to have proper dependencies aligned for d3-color?

  └─┬ @nivo/line@0.83.0
    ├─┬ @nivo/colors@0.83.0
    │ ├── d3-color@3.1.0
    │ └─┬ d3-scale-chromatic@2.0.0
    │   └── d3-color@2.0.0
    └─┬ @nivo/core@0.83.0
      ├── d3-color@3.1.0 deduped
      └─┬ d3-interpolate@2.0.1
        └── d3-color@2.0.0

EDIT: Sorry found the comment mentioning #2337 as the PR for this update... How are things going?

yubarajshrestha commented 1 year ago

Still today I am having issues similar to @APIWT in react/vite/typescript application.

My solution for time being is using overrides in package.json:

"overrides": {
    "d3-scale": "^3.3.0",
    "d3-interpolate": "^3.0.1",
    "d3-scale-chromatic": "^3.0.0"
  },
wheresvic commented 1 year ago

The only way I get was install victory-vendor dependency and with npm 8 use overrides, like this:

  "dependencies": {
   ...
    "victory-vendor": "36.6.11"
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

But this is workaround, we need an internal solution.

This worked for me with a Remix.run application as well. Many thanks for the workaround!

seanmoghadam commented 11 months ago

still an issue in 0.84.0 - reverted to 0.80.0 which has security vulnerabilities and some bugs on ResponsiveCanvasBar.

0.84.0 works with the correct loader (development) but is incompatible with the ESM production build.

kevinreber commented 11 months ago

The only way I get was install victory-vendor dependency and with npm 8 use overrides, like this:

  "dependencies": {
   ...
    "victory-vendor": "36.6.11"
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

But this is workaround, we need an internal solution.

This worked for me with a Remix.run application as well. Many thanks for the workaround!

@wheresvic What version of Remix are you using? I'm the on the latest and haven't been able to get it running 😞 https://stackblitz.com/~/github.com/kevinreber/remix-nivo-template

marklai1998 commented 11 months ago

push

wheresvic commented 10 months ago

The only way I get was install victory-vendor dependency and with npm 8 use overrides, like this:

  "dependencies": {
   ...
    "victory-vendor": "36.6.11"
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

But this is workaround, we need an internal solution.

This worked for me with a Remix.run application as well. Many thanks for the workaround!

@wheresvic What version of Remix are you using? I'm the on the latest and haven't been able to get it running 😞 https://stackblitz.com/~/github.com/kevinreber/remix-nivo-template

@kevinreber I'm on the latest remix 2.4.1 and this is what my package.json looks like (the relevant parts):

  "dependencies": {
    "@nivo/api": "0.74.1",
    "@nivo/core": "0.83.0",
    "@nivo/line": "0.83.0",
    "victory-vendor": "36.7.0",
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

You a missing both the victory-vendor and the overrides in your stackblitz example.

anishLearnsToCode commented 9 months ago

@plouc when trying to use the following nivo packages

// package.json
{
...
        "@nivo/bar": "0.84.0",
        "@nivo/core": "0.84.0",
        "@nivo/line": "0.84.0",
...
}

i am getting the following error:

require() of ES Module /Users/anish/projects/.../node_modules/d3-interpolate/src/index.js from /Users/anish/projects/.../node_modules/@nivo/tooltip/node_modules/@nivo/core/dist/nivo-core.cjs.js not supported.
Instead change the require of index.js in /Users/anish/projects/.../node_modules/@nivo/tooltip/node_modules/@nivo/core/dist/nivo-core.cjs.js to a dynamic import() which is available in all CommonJS modules.

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/anish/projects/.../node_modules/d3-interpolate/src/index.js from /Users/anish/projects/.../node_modules/@nivo/tooltip/node_modules/@nivo/core/dist/nivo-core.cjs.js not supported.

Is there any open mr to resolve this issue? We just need to migrate the nivo packages to use the esm module imports instead of commonJS.

wheresvic commented 9 months ago

@anishLearnsToCode did you try upgrading all nivo dependencies to the same version 0.84.0?

anishLearnsToCode commented 9 months ago

@anishLearnsToCode did you try upgrading all nivo dependencies to the same version 0.84.0?

Yes, i did that. All my nivo dependencies are 0.84.0. and then i am getting the d3-interpolate error while importing esm module from commonjs.

MarinePicaut commented 9 months ago

@anishLearnsToCode did you try upgrading all nivo dependencies to the same version 0.84.0?

Yes, i did that. All my nivo dependencies are 0.84.0. and then i am getting the d3-interpolate error while importing esm module from commonjs.

Hi @anishLearnsToCode, I have exactly the same problem as you and all my nivo dependencies are also 0.84.0. Did you find a trick since last week ?

anishLearnsToCode commented 9 months ago

@anishLearnsToCode did you try upgrading all nivo dependencies to the same version 0.84.0?

Yes, i did that. All my nivo dependencies are 0.84.0. and then i am getting the d3-interpolate error while importing esm module from commonjs.

Hi @anishLearnsToCode, I have exactly the same problem as you and all my nivo dependencies are also 0.84.0. Did you find a trick since last week ?

Hey @MarinePicaut I have not yet found a workaround. I think this needs to be resolved internally in nivo. The d3 modules should be imported using the nextJS pattern and not common js (require) as d3 doesn't support commonJS imports anymore.

Of course if someone else finds some other workaround do let me know.

jamesarosen commented 9 months ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

That works great for components like <Line> and <SymbolCircle>. It doesn't work for all the utilities in @nivo/core since dynamic can only be applied to a React.ComponentType.

dbudwin commented 9 months ago

For some added context, my unit tests started failing after upgrading to 0.84.0:

Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /redacted/node_modules/@nivo/core/node_modules/d3-interpolate/src/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export {default as interpolate} from "./value.js";
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

I can work around this by modifying my Jest config to include the following:

"transformIgnorePatterns": [
  "<rootDir>/node_modules/(?!((@nivo\/(\\S+)))/)"
],

That RegEx just ignores everything in node_modules that begins with @nivo/

jkrrish-ac commented 9 months ago

Adding the following to Jest Config fixed my issue moduleNameMapper: [ "d3-interpolate": "<rootDir>/node_modules/@nivo/core/node_modules/d3-interpolate/dist/d3-interpolate.min.js", "d3-color": "<rootDir>/node_modules/@nivo/core/node_modules/d3-color/dist/d3-color.min.js", "d3-scale-chromatic": "<rootDir>/node_modules/@nivo/core/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.min.js" ]

roger-tbg commented 9 months ago

The only way I get was install victory-vendor dependency and with npm 8 use overrides, like this:

  "dependencies": {
   ...
    "victory-vendor": "36.6.11"
  },
  "overrides": {
    "d3-color": "file:../../victory-vendor/lib/d3-color.js"
  },

But this is workaround, we need an internal solution.

This worked for me with a Remix.run application as well. Many thanks for the workaround!

@wheresvic What version of Remix are you using? I'm the on the latest and haven't been able to get it running 😞 https://stackblitz.com/~/github.com/kevinreber/remix-nivo-template

Have you tried adding this to your remix.config.js


    serverDependenciesToBundle: [
        /@nivo\/.+/,
    ],
justshiv commented 8 months ago

Since upgrading to the recent nivo v0.85.0 release I've been able to reliably use the experimental esmExternals loose mode workaround to resolve this issue for us in our Next.js project.

plouc commented 8 months ago

Since upgrading to the recent nivo v0.85.0 release I've been able to reliably use the experimental esmExternals loose mode workaround to resolve this issue for us in our Next.js project.

@justshiv, I'm glad to read this! Would you happen to have a small example/public repo available using this config? It seems like it still doesn't solve the issue for some users :(

millsp commented 8 months ago

For people using vite, this might help:

export default defineConfig({
  ssr: {
    noExternal: [/^d3.*$/, /^@nivo.*$/],
  },
});

It basically works around the issue by bundling the packages.

My current understanding is that for vite, there shouldn't be a reason why it prefers the cjs entry above the esm one. Currently that is what happens, and thus leads to require of d3's ESM code.

millsp commented 8 months ago

@plouc I think going forward you'd have two possible choices.

  1. You could discontinue the cjs build of nivo.

This means that it won't be possible for any nivo cjs code to load d3 esm code, and hence gets rid of the issue at the same time. In other words, because your direct dependency is esm you also have to be. The downside is that this is a breaking change in itself, although I don't think this currently works anyways?

  1. You could bundle and transpile d3 esm code into nivo directly.

While is more work for you, I think could be the path of least resistance. By bundling d3 directly into nivo, you could then produce both pure esm and pure cjs bundles (the translation from esm to cjs is then handled by the bundler). The downside if d3 is bundled into nivo is that you'll be bound to also release when d3 emits a release.

At Prisma, we've used the second option (bundling) to overcome the differences between CJS and ESM but still be able to produce both. Not sure if this is an option for your lib though.

wheresvic commented 8 months ago

While I would personally really appreciate option 2 (bundle and transpile d3 into nivo directly), I think option 1 is what most other libraries are now doing, i.e. discontinue cjs.

It is a bit of a pain at the moment but the faster we move towards esm the quicker the community can move forward.

plouc commented 8 months ago

I also lean towards the first option, it seems like the community is (slowly 😅) moving forward, and I really don't want to add more complexity to the project. I expect some complains though.

anishLearnsToCode commented 8 months ago

For people using vite, this might help:

export default defineConfig({
  ssr: {
    noExternal: [/^d3.*$/, /^@nivo.*$/],
  },
});

It basically works around the issue by bundling the packages.

My current understanding is that for vite, there shouldn't be a reason why it prefers the cjs entry above the esm one. Currently that is what happens, and thus leads to require of d3's ESM code.

I have tried this modification in my vite.config file, but this doesn't work for me. I am currently using:

  "@nivo/bar": "0.85.1",
  "@nivo/core": "0.85.1",
  "@nivo/line": "0.85.1",

in my package.json file and i am still getting the following error:

Error: require() of ES Module /Users/..../node_modules/d3-interpolate/src/index.js from /Users/...../node_modules/@nivo/core/dist/nivo-core.cjs.js not supported.

Instead change the require of index.js in /Users/..../node_modules/@nivo/core/dist/nivo-core.cjs.js to a dynamic import() which is available in all CommonJS modules.

Am I missing something? Any suggestions?

anishLearnsToCode commented 8 months ago

I also lean towards the first option, it seems like the community is (slowly 😅) moving forward, and I really don't want to add more complexity to the project. I expect some complains though.

Yes, moving towards an esm future will be the optimal solution imo 👍 Any timeline/ETA 🙃 ??

OleksandrRakovets commented 8 months ago

@anishLearnsToCode this has worked for me

ssr: {
    noExternal: ["@nivo/*"],
},
OleksandrRakovets commented 8 months ago

@plouc Faced this issue today in the project that renders Nivo components on a Node.js Lambda.

I suspect the issue is with file extensions:

// current package.json
"main": "./dist/nivo-core.cjs.js",
"module": "./dist/nivo-core.es.js",

// desired package.json
"main": "./dist/nivo-core.cjs",
"module": "./dist/nivo-core.mjs",

Per Node documentation:

Files ending with .mjs are always loaded as ES modules regardless of the nearest parent package.json. Files ending with .cjs are always loaded as CommonJS regardless of the nearest parent package.json.

They confirm in the subsequent heading that only bundlers make a distinction based on "module" field.

In my setup vite was outputting index.mjs with import { Bar } from '@nivo/bar'. Node started to run it in module context, but after finding .js extension in bar's package.json, fell back to commonjs, which lead to requireing d3 packages and an error.

I am not 100% sure this is the case and could not manually update 15 packages to make sure.

How hard would be to build a branch with such extensions?

tbolt commented 8 months ago

I am running into this issue but only when running jest testing. I have tried adding the vite workarounds but that didn't resolve the issue. Any suggestions for a workaround with jest tests?

sambowenhughes commented 7 months ago

If you're using Next.js, you may be able to resolve this by using next/dynamic.

From

import { ResponsiveLine } from "@nivo/line";

to

import dynamic from "next/dynamic";

const ResponsiveLine = dynamic(() => import("@nivo/line").then(m => m.ResponsiveLine), { ssr: false });

In my case, I'm using next/dynamic to import custom components that use nivo, and it works fine.

Legend 🕺

prstn commented 6 months ago

This is what fixed it for me (vite only)

vite.config.ts

export default defineConfig({
  resolve: {
    mainFields: ["module", "browser", "jsnext:main", "jsnext"],
  },
});

As I understand it, this is telling vite to prefer es modules over cjs, when compiling.

aswinfrancis91 commented 6 months ago

Having the same problem with react app created with CRA. None of the solution have worked. I am on 0.87.0.

    D:\Development\Repos\ProjectName\node_modules\d3-interpolate\src\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export {default as interpolate} from "./value.js";
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      4 | import { useEffect, useRef, useState } from 'react';
      5 | import { AxisTickProps } from '@nivo/axes';
    > 6 | import { useTheme } from '@nivo/core';

I tried adding overrides and transformIgnorePatterns