Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.81.0 can lead to import issues #2310

Open
plouc opened this issue Apr 27, 2023 · 58 comments · May be fixed by #2643
Open

v0.81.0 can lead to import issues #2310

plouc opened this issue Apr 27, 2023 · 58 comments · May be fixed by #2643

Comments

@plouc
Copy link
Owner

plouc commented Apr 27, 2023

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?

  • You could stick to 0.80.0, as the D3 packages used in this version are not esm only, the drawback is that there are some critical security issues in those. Also 0.80.0 contains a regression for canvas based components 😓
  • Try the workarounds suggested in the issues mentioned above.
  • Help to find a proper fix :) Share workarounds, even if those are temporary fixes, it could help other users to upgrade.
@Aeolun
Copy link

Aeolun commented May 4, 2023

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
Copy link

leeuwd commented May 9, 2023

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
Copy link

sroussey commented May 9, 2023

Still on 0.80.0 because of this.

@APIWT
Copy link

APIWT commented May 14, 2023

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/[email protected], 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
Copy link
Owner Author

plouc commented May 14, 2023

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/[email protected] is pretty old.

@plouc
Copy link
Owner Author

plouc commented May 14, 2023

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

@APIWT
Copy link

APIWT commented May 14, 2023

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/[email protected] 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
Copy link

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
Copy link

kamimoo commented May 18, 2023

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
Copy link

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
Copy link

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
Copy link

elie222 commented Jun 5, 2023

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
Copy link

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

@AnnieTaylorCHEN
Copy link

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

@shehi
Copy link

shehi commented Jun 18, 2023

@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
Copy link

tnovas commented Jun 29, 2023

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
Copy link

stahlmanDesign commented Jul 4, 2023

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

@roger-tbg
Copy link

roger-tbg commented Feb 21, 2024

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
Copy link

justshiv commented Mar 7, 2024

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
Copy link
Owner Author

plouc commented Mar 11, 2024

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
Copy link

millsp commented Mar 11, 2024

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
Copy link

millsp commented Mar 12, 2024

@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
Copy link

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
Copy link
Owner Author

plouc commented Mar 13, 2024

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
Copy link

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
Copy link

anishLearnsToCode commented Mar 14, 2024

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
Copy link
Contributor

@anishLearnsToCode this has worked for me

ssr: {
    noExternal: ["@nivo/*"],
},

@OleksandrRakovets
Copy link
Contributor

@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
Copy link

tbolt commented Mar 18, 2024

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?

@plouc plouc mentioned this issue Mar 21, 2024
@sambowenhughes
Copy link

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
Copy link

prstn commented May 10, 2024

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
Copy link

aswinfrancis91 commented May 20, 2024

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

@tony-cocco
Copy link

tony-cocco commented May 23, 2024

There's been mention of discontinuing the cjs builds. One of my engineers came up a workaround that kind of does this...

"postinstall": "node ./scripts/delete-nivo-cjs.js",
const fs = require('fs');
const path = require('path');

// list used nivo packages
const nivoPackages = [
  'annotations',
  'arcs',
  'axes',
  'bar',
  'calendar',
  'colors',
  'core',
  'legends',
  'network',
  'pie',
  'polar-axes',
  'radial-bar',
  'recompose',
  'scales',
  'treemap',
  'tooltip',
];

nivoPackages.forEach((package) => {
  const filePath = path.join(__dirname, '../', 'node_modules', `@nivo/${package}`, 'dist', `nivo-${package}.cjs.js`);
  if (fs.existsSync(filePath)) {
    fs.unlinkSync(filePath, (err) => {
      if (err) throw err;
      console.log(`Deleted: ${filePath}`);
    });
  }
});

console.info('Nivo CJS files deleted: ', nivoPackages.join(', '));

I know there is some contention around the usage of postinstall, but we've been using this since a little after my May comment without issues (that we know of 😓 ).

@mikefogg
Copy link

There's been mention of discontinuing the cjs builds. One of my engineers came up a workaround that kind of does this...

"postinstall": "node ./scripts/delete-nivo-cjs.js",
const fs = require('fs');
const path = require('path');

// list used nivo packages
const nivoPackages = [
  'annotations',
  'arcs',
  'axes',
  'bar',
  'calendar',
  'colors',
  'core',
  'legends',
  'network',
  'pie',
  'polar-axes',
  'radial-bar',
  'recompose',
  'scales',
  'treemap',
  'tooltip',
];

nivoPackages.forEach((package) => {
  const filePath = path.join(__dirname, '../', 'node_modules', `@nivo/${package}`, 'dist', `nivo-${package}.cjs.js`);
  if (fs.existsSync(filePath)) {
    fs.unlinkSync(filePath, (err) => {
      if (err) throw err;
      console.log(`Deleted: ${filePath}`);
    });
  }
});

console.info('Nivo CJS files deleted: ', nivoPackages.join(', '));

I know there is some contention around the usage of postinstall, but we've been using this since a little after my May comment without issues (that we know of 😓 ).

@tony-cocco when you're using this, how are you getting around the Cannot find module './node_modules/@nivo/core/dist/nivo-core.cjs.js'. Please verify that the package.json has a valid "main" entry error since that file is now deleted? Running into this issue trying to import linearGradientDef from @nivo/core and looking for some sort of work around :)

@tony-cocco
Copy link

tony-cocco commented May 27, 2024

@tony-cocco when you're using this, how are you getting around the Cannot find module './node_modules/@nivo/core/dist/nivo-core.cjs.js'. Please verify that the package.json has a valid "main" entry error since that file is now deleted? Running into this issue trying to import linearGradientDef from @nivo/core and looking for some sort of work around :)

We don't have this issue. Our build grabs the other dist file iirc. Here are some of our module configurations in our tsconfig file:

    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,

@mikefogg

I want to add, if you're using nextjs, you likely need to remove your build cache: rm -rf .next.

@gmferise
Copy link

Should probably move CJS imports to a different path or deprecate CJS entirely.

I wanted to upgrade from v0.80.0 to v0.87.0 to use the new totals feature on bar charts.
Using Next v12.3.2 / React v17.0.2, my codebase has the following packages from nivio:

"@nivo/core": "^0.87.0",
"@nivo/bar": "^0.87.0",
"@nivo/line": "^0.87.0",
"@nivo/pie": "^0.87.0",

The above postinstall script worked for me. Here is a tweak I made to make it automatically find which nivo packages you're using.

const packageLock = require('../package-lock.json');

const nivoPackages = Array.from(new Set(
  Array.from(
    JSON.stringify(packageLock).matchAll(/@nivo\/(?<pkg>[a-z0-9_-]+)/gi),
  ).map((result) => result.groups.pkg),
));

And, I did have to clear the build cache with rm -rf .next to get it working.

@hmatthews26
Copy link

Setup

  • React 18.3.1
  • Vite 5.2.9
  • Nivo 0.8.7

Overview

Several of my tests fail with the following error after upgrading from v0.8.0 to v0.8.7

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

After some extensive research, I stumbled upon this discussion under the Vitest repo. To quote sheremet-va, Vitest has to use Node.js resolution so you don't have multiple instances of the same package, and Node.js doesn't support the module field.

This is a problem because Nivo relies solely on the module field in its package.json.

"main": "./dist/nivo-bar.cjs.js",
"module": "./dist/nivo-bar.es.js",
"types": "./dist/types/index.d.ts",

Whereas the recommended approach is to define package entry points under exports.

"main": "./dist/nivo-bar.cjs.js",
"module": "./dist/nivo-bar.es.js",
"types": "./dist/types/index.d.ts",
"exports": {
  "require": "./dist/nivo-bar.cjs.js",
  "import": "./dist/nivo-bar.es.js",
  "types": "./dist/types/index.d.ts",
}

Workarounds

I've tried the following workarounds with success. Please refer to the Vitest discussion for step-by-step instructions.

1) Patch Nivo with exports

Use patch-package and postinstall, as suggested by mkarajohn in the Vitest discussion. I had to patch several Nivo packages with exports.

"scripts": {
  "patch-nivo": "patch-package @nivo/annotations @nivo/axes @nivo/bar @nivo/colors @nivo/core @nivo/legends @nivo/scales @nivo/tooltip -- exclude 'nothing'",
  "postinstall": "patch-package"
}

2) Create aliases in vite.config.js

Use aliases, as suggested by deleugpn in the Vitest discussion.

resolve: {
  alias: {
    '@nivo/annotations': '@nivo/annotations/dist/nivo-annotations.es.js',
    '@nivo/axes': '@nivo/axes/dist/nivo-axes.es.js',
    '@nivo/bar': '@nivo/bar/dist/nivo-bar.es.js',
    '@nivo/colors': '@nivo/colors/dist/nivo-colors.es.js',
    '@nivo/core': '@nivo/core/dist/nivo-core.es.js',
    '@nivo/legends': '@nivo/legends/dist/nivo-legends.es.js',
    '@nivo/scales': '@nivo/scales/dist/nivo-scales.es.js',
    '@nivo/tooltip': '@nivo/tooltip/dist/nivo-tooltip.es.js',
  }
}

@odanado odanado linked a pull request Aug 28, 2024 that will close this issue
@odanado
Copy link

odanado commented Aug 28, 2024

I have created a pull request that will allow the nivo package to be treated as an ESM.
#2643

If this pull request is merged, it will resolve the errors with the modern bundler.

@meza
Copy link

meza commented Oct 6, 2024

any movement on this?

@boryscastor
Copy link

Hey people, don't know if that's the same but I have a dependabot updating 0.84.0 to 0.87.0 and facing an issue.

Getting this error on webpack project while running jest:

node_modules/d3-scale/src/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export {
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

I checked the changelog but did not find any migration guide about dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.