Freewind
Freewind

Reputation: 198388

'rollup-plugin-node-resolve' can't work with `useState` of react, how to fix it?

In a typescript project, I use typescript + rollup + rollup-plugin-node-resolve + React's useState together, but when run rollup -c, it throws error:

1: import {useState} from "react";
           ^
2: 
Error: 'useState' is not exported by node_modules/react/index.js

My code is quite simple:

import {useState} from "react";

console.log(useState);

And the rollup.config.js is:

import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';

export default {
  input: 'index.ts',
  output: [
    {
      file: 'bundle.js',
      format: 'cjs',
    }
  ],
  plugins: [
    resolve(),
    commonjs(),
    typescript(),
  ]
};

package.json is:

{
  "scripts": {
    "demo": "rollup -c && node bundle.js"
  },
  "dependencies": {
    "react": "16.8.4"
  },
  "devDependencies": {
    "@types/react": "16.8.8",
    "rollup": "1.6.0",
    "rollup-plugin-commonjs": "9.2.1",
    "rollup-plugin-node-resolve": "4.0.1",
    "rollup-plugin-typescript2": "0.20.1",
    "typescript": "3.3.3333"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "target": "es6",
    "module": "esnext",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "jsx": "react",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

If I remove resolve() from rollup.config.js, rollup will bundle it correctly. But I need to use resolve() in my real project.

Where is wrong and how to fix it?

PS: Complete code demo is here: https://github.com/freewind-demos/typescript-react-rollup-use-state-demo

Upvotes: 2

Views: 2645

Answers (3)

carlo818
carlo818

Reputation: 298

I found out I needed to add peerDependencies in my package.json:

"peerDependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }

Upvotes: 0

bFunc
bFunc

Reputation: 1465

This setup configuration works for me

// rollup config 
plugins: [
   commonjs({
      // ... other commonjs config options
      namedExports: {
         // https://github.com/rollup/rollup-plugin-commonjs#custom-named-exports
         'node_modules/react/index.js': ['useState', 'useRef', 'useEffect'],
       },
     }),
],

Upvotes: 0

Freewind
Freewind

Reputation: 198388

As the answer link provided by @Tholle, the problem is rollup-plugin-commonjs is not able to find the setState export from react, since react declare it like:

const React = {
    setState
}
module.exports = React

rollup-plugin-commonjs can't handle such form of exports, so we have to define some named exports in rollup.config.js, like:

plugins: [
   'react': ['useState']
]

Upvotes: 3

Related Questions