floating-ui / react-popper

🍿⚛Official React library to use Popper, the positioning library
https://popper.js.org/react-popper/
MIT License
2.5k stars 226 forks source link

Rollup bundling error: "Error: 'default' is not exported by node_modules/react-fast-compare/index.js" #437

Closed distinctdan closed 2 years ago

distinctdan commented 2 years ago

Steps to reproduce the problem

  1. Hi, I'm trying to import react-popper into my components library like this:
    import { usePopper } from 'react-popper'; 
  2. However, when I try to build my library using rollup, I'm getting the following error:
    [!] Error: 'default' is not exported by node_modules/react-fast-compare/index.js, imported by node_modules/react-popper/lib/esm/usePopper.js
    https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module

This looks similar to this previous issue: https://github.com/floating-ui/react-popper/issues/345, except that the previous fix doesn't seem to be working. I can include the rollup plugin commonjs(), which does make the error go away, but it causes a duplicate import of React in my bundled output. It's also possible this could be a bug in rollup itself.

I'd rather bundle react-popper with my library if possible instead of making it a peer dependency that consumers have to add. Anyone know of a way to get this to work?

What is the expected behavior?

Importing popper should work with rollup

What went wrong?

Importing produces an error

Any other comments?

Here's my rollup and typescript configs:

Rollup Config ```javascript import commonjs from '@rollup/plugin-commonjs'; import { defineConfig } from 'rollup'; import del from 'rollup-plugin-delete' import peerDepsExternal from 'rollup-plugin-peer-deps-external'; import postcss from 'rollup-plugin-postcss'; import postcssURL from 'postcss-url'; import resolve from '@rollup/plugin-node-resolve'; import svgr from '@svgr/rollup'; import { terser } from 'rollup-plugin-terser'; import typescript from '@rollup/plugin-typescript'; const devMode = (process.env.NODE_ENV === 'development'); const prodMode = (process.env.NODE_ENV === 'production'); if (!devMode && !prodMode) throw 'Invalid NODE_ENV: ' + process.env.NODE_ENV; export default defineConfig({ input: [ 'src/index.ts', ], output: [ { dir: 'dist', // All modern browsers now support es modules. We're also assuming our consumers // are using webpack and can downlevel if needed. It's worth noting that next.js // now also supports es modules. format: 'es', sourcemap: true, }, ], plugins: [ // Clean the dist directory. del({ targets: 'dist/*' }), // Make sure we don't bundle peer dependencies like "react". peerDepsExternal(), // Use node path resolution algorithm. resolve(), // The commonjs plugin is needed to support popperjs, which imports a commonjs dependency. // See: https://github.com/floating-ui/react-popper/issues/345 commonjs(), // Convert svg imports into react components svgr({ svgoConfig: { removeViewBox: false, // need viewbox for responsive } }), // Process our scss files. We're using postcss instead of rollup-plugin-scss // because rollup-plugin-scss doesn't support copying assets, which we need for fonts. postcss({ extract: 'styles.min.css', minimize: prodMode, sourceMap: true, plugins: [ postcssURL({ // When we encounter a url in css, copy the asset. This is needed to include fonts. url: 'copy', // For some reason postcss thinks the base url is "src", so we have to go up a level. assetsPath: '../dist', }) ] }), typescript({ tsconfig: 'tsconfig.rollup.json', }), // Minification prodMode && terser(), ], }); ```
tsconfig.json ```json { "compilerOptions": { "baseUrl": "./src", "rootDir": "./src", "declaration": true, "declarationDir": "./dist/types", "module": "esnext", "target": "esnext", "jsx": "react", "moduleResolution": "node", "esModuleInterop": true, "strictBindCallApply": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true } } ```

Packages versions

distinctdan commented 2 years ago

Ok, I got this figured out. As it turns out, the react duplicate was caused by a separate issue. I'm developing the components library locally and importing it into another project to test. As it turns out, webpack doesn't resolve peer dependencies correctly in that case and will cause duplicate imports. See: https://blog.maximeheckel.com/posts/duplicate-dependencies-npm-link/

I was able to solve the react-popper issue with the commonjs() plugin.

abdumanas-plutoflume commented 6 months ago

@distinctdan would you be able to share the working config ? I'm facing similar issue right now with vite and rollup.