Rollup Error: 'isValidElementType' is not exported by node_modules/react-is/index.js
Asked Answered
R

6

23

I'm building a bundle with rollUp using styled-components.

My rollup.config.js looks like:

import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'cjs'
  },
  external: [
    'react',
    'react-proptypes'
  ],
  plugins: [
    resolve({
      extensions: [ '.js', '.json', '.jsx' ]
    }),
    commonjs({
      include: 'node_modules/**'
    }),
    babel({
      exclude: 'node_modules/**'
    })
  ]
}

And I'm receiving

[!] Error: 'isValidElementType' is not exported by node_modules/react-is/index.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
node_modules/styled-components/dist/styled-components.es.js (7:9)
5: import stream from 'stream';
6: import PropTypes from 'prop-types';
7: import { isValidElementType } from 'react-is';
            ^
8: import hoistStatics from 'hoist-non-react-statics';

Checking on the node_modules itself react-is is a commonjs module as it can be checked out here as well.

Shouldn't the commonjs plugin take care of it since it is inside node_modules/** ?

Thanks.

Rising answered 28/4, 2018 at 20:43 Comment(0)
S
39

I resolved this by using the rollup-plugin-commonjs

and defining the export manually in the rollup config as below

export default {
  input: 'src/index.js',
  output: [
    {
      file: pkg.main,
      format: 'cjs',
      sourcemap: true
    },
    {
      file: pkg.module,
      format: 'es',
      sourcemap: true
    }
  ],
  plugins: [
    external(),
    postcss({
      modules: true
    }),
    url(),
    babel({
      exclude: 'node_modules/**'
    }),
    resolve(),
    commonjs({
      include: 'node_modules/**',
      namedExports: {
        'node_modules/react-is/index.js': ['isValidElementType']
      }
    })
  ]
}

After this everything worked fine.

and for the info, my initial setup was done through https://github.com/transitive-bullshit/react-modern-library-boilerplate

Hope it works for you

Sword answered 30/4, 2018 at 10:23 Comment(2)
Worked for me. Thanks!Gayomart
Worked for me, though I had to use ['isValidElementType', 'isContextConsumer'] for my array.Loft
S
17

The fix above didn't work for me. However, adding styled-components to the rollup.config.js list of externals and globals worked for me.

    export default {
      ...
      external: ['styled-components'],
      ...
      globals: { 'styled-components': 'styled' },
    };

I'm using the typescript create-react-library cli, which comes bundled with rollup.

https://github.com/styled-components/styled-components/issues/930

Skeg answered 22/10, 2018 at 18:13 Comment(2)
Just to update, it looks like globals is now part of output. So it should now be: ` ... external: ['styled-components'] ... output: { globals: { 'styled-components': 'styled' } }`Incarnation
Another update for create-react-library - as it's using (a fork of) microbundle passing --external styled-components through the command-line build command worksEpanaphora
T
7

The solution posted by FrostyDog worked for me so +1 for that, HOWEVER...

I immediately got the same error when trying to import hooks from react, I could follow the above solution and do

    export default {
      ...
      external: ['styled-components', 'react'],
      ...
    };

in rollup.config.js but I wanted a solution that handled this for all libraries, so this wasn't a recurring issue in the future.

So did this instead...

import external from "rollup-plugin-peer-deps-external";
...
export default {
    ...
    plugins: [
        external({
            includeDependencies: true
        }),
        ...
    ]
};

solved it for me and everyone adding to the project after.

Tumor answered 22/4, 2020 at 7:45 Comment(1)
This solves my problem(2023)Percale
R
7

Here is an updated answer for 2022.

I ran into this error using vitejs, which uses rollup for its production builds/bundling.

I have included a solution for rollup and vite projects.


A note on old answers and documentation

In docs and forums on the internet there are still a lot of old comments referring to rollup-plugin-commonjs and namedExports.

  • The last release of rollup-plugin-commonjs was v10.1.0 in 2019-08-27
  • rollup-plugin-commonjs was renamed to @rollup/plugin-commonjs with v11.0.0 in 2019-12-21
  • namedExports was removed from @rollup/[email protected] in 2020-06-05

So anything that refers to rollup-plugin-commonjs or namedExports is outdated and not relevant to the current version of rollup or @rollup/plugin-commonjs.


Why we get this error

This error happens with a lot of React libs because they use dynamic require(...) statements to choose between dev and production source files.

I'm using react for this example, but it's the same idea in react-dom and react-is.

// node_modules/react/index.js

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

When rollup processes this file it can't work out that the exports come from another file, so it rollup thinks the exports are empty, and that is why we get an error like 'useState' is not exported by 'node_modules/react/index.js'.


Solutions

Option 1: Make libraries external

Use this option if you don't want to include the dependency inside your bundle at all.

In this case, mark these libraries as external, meaning they won't be processed by rollup or included in the bundle. This can also reduce the size of your bundle and avoid accidentally bundling these libraries multiple times.

Any libraries marked as external will need to be made available in the runtime environment (i.e. they're available on the page at runtime, or you have another build step that can resolve the externals and provide them to your library).


Option 2: Use aliases to manually resolve the files

Use this option if you your dependencies should be included inside your bundle - i.e. you want React to be included inside your library bundle.

  1. Install @rollup/plugin-alias
$ npm install @rollup/plugin-alias --save-dev
  1. Configure aliases in your rollup.config.js.
// rollup.config.js
import alias from '@rollup/plugin-alias';
import * as _path from 'path';

const isProduction = process.env.NODE_ENV === 'production';

/*
Define any path here that triggers the "is not exported" error

This is not needed if the react libraries are marked as `externals` and excluded from the bundle.
This is only an needed because we **want** react to be included in the bundle.
*/
let pathReact = 'umd/react.production.min.js';
let pathReactDom = 'umd/react-dom.production.min.js';
let pathReactJsx = 'cjs/react-jsx-runtime.production.min.js';
if (!isProduction){
  pathReact = 'umd/react.development.js';
  pathReactDom = 'umd/react-dom.development.js';
  pathReactJsx = 'cjs/react-jsx-dev-runtime.development.js';
}

module.exports = {
  input: 'src/index.js',
  output: {
    dir: 'output',
    format: 'cjs'
  },
  plugins: [
    alias({
      entries: [
        {
          find: /^react$/,
          replacement: require.resolve(_path.join('react', pathReact)),
        },
        {
          find: /^react-dom$/,
          replacement: require.resolve(_path.join('react-dom', pathReactDom)),
        },
        {
          /*
          2022-03-11
          https://github.com/vitejs/vite/issues/6215#issuecomment-1064247764
          */
          find: /react\/jsx-runtime/,
          replacement: require.resolve(_path.join('react', pathReactJsx)),
        },
      ]
    })
  ]
};

NOTE:

  • This assumes you are using NODE_ENV environment variable to control production/development builds
  • I'm aliasing to the umd react files; if you need to point to the cjs build then adjust the alias path as necessary

Vitejs version

Here is the equivalent configuration for a vitejs project:

// vite.config.ts
import * as _path from "path";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig((env) => {
  // mode: 'production' | 'development'
  const mode = env.mode;

  /**
   * Fix build messages/errors like: `'useState' is not exported by 'node_modules/react/index.js'`
   */
  let pathReact = "umd/react.production.min.js";
  let pathReactDom = "umd/react-dom.production.min.js";
  let pathReactJsx = "cjs/react-jsx-runtime.production.min.js";
  if (mode === "development") {
    pathReact = "umd/react.development.js";
    pathReactDom = "umd/react-dom.development.js";
    pathReactJsx = "cjs/react-jsx-dev-runtime.development.js";
  }

  return {
    resolve: {
      alias: [
        // react alias fix
        {
          find: /^react$/,
          replacement: require.resolve(_path.join("react", pathReact)),
        },
        {
          find: /^react-dom$/,
          replacement: require.resolve(_path.join("react-dom", pathReactDom)),
        },
        {
          /*
          2022-03-11
          https://github.com/vitejs/vite/issues/6215#issuecomment-1064247764
          */
          find: /react\/jsx-runtime/,
          replacement: require.resolve(_path.join("react", pathReactJsx)),
        },
        // End react alias fix
      ],
    },
    plugins: [react()],
  };
});
Reconcilable answered 10/4, 2022 at 2:8 Comment(1)
TypeError: __require.resolve is not a functionCorrida
A
1

I have this problem when build:

    Error: 'typeOf' is not exported by ../../node_modules/react-is/index.js, imported by ../../node_modules/styled-components/dist/styled-components.esm.js
1: import { typeOf as e, isElement as t, isValidElementType as n } from "react-is";

you can use this code in rollup commonjs config:

plugins: [
...
...
...    
commonjs({
      ignoreGlobal: true,
      include: /\/node_modules\//,
      namedExports: {
        react: Object.keys(require("react")),
        "react-is": Object.keys(require("react-is")),
      },
    }),
...
]

this code resolves react-is import error when building your project. reference for read more: https://github.com/styled-components/styled-components/issues/3256#issuecomment-694144760

Alla answered 17/7, 2022 at 7:14 Comment(0)
W
1
export default {
    ...
    external: ['react', 'react-dom', 'styled-components'],
    globals: { 'styled-components': 'styled' },
    plugins: [
        external({
            includeDependencies: true
        }),
        ...
    ]
};
Weingarten answered 14/10, 2022 at 13:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.