I’m using Rollup to bundle my custom npm react library, but I’m encountering multiple import statements for React and ReactDOM in the bundled output, and getting errors like cannot import (useContext | useState ...) of undefined
in my host app. Here is an example of the import statements in the bundle:
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import React__default, { useLayoutEffect, useEffect, forwardRef, useState, useRef, useCallback, useMemo, createContext, useContext, Fragment as Fragment$1, isValidElement, cloneElement, createElement, useId as useId$2, useReducer, useSyncExternalStore, createRef } from 'react';
import * as ReactDOM from 'react-dom';
import ReactDOM__default, { createPortal, flushSync } from 'react-dom';
This duplication is causing issues with context and is leading to a larger bundle size. Here is my current Rollup configuration:
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import autoprefixer from "autoprefixer";
import postcssImport from "postcss-import";
import { defineConfig } from "rollup";
import dts from "rollup-plugin-dts";
import external from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import tailwindcss from "tailwindcss";
import packageJson from "./package.json" assert { type: "json" };
export default defineConfig([
{
input: "src/index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
sourcemap: true,
},
{
file: packageJson.module,
format: "esm",
sourcemap: true,
},
],
onwarn(warning, warn) {
// https://github.com/TanStack/query/issues/5175
if (warning.code === "MODULE_LEVEL_DIRECTIVE") {
return;
}
warn(warning);
},
plugins: [
external(),
resolve({
skip: ["react", "react-dom"],
}),
commonjs(),
typescript({
tsconfig: "./tsconfig.json",
declaration: true,
declarationDir: "./dist",
exclude: ["**/*.stories.tsx", "**/*.test.ts", "**/*.test.tsx"],
}),
],
},
{
input: "src/styles/global.css",
output: [{ file: "dist/index.css", format: "es" }],
plugins: [
postcss({
extract: true,
minimize: true,
plugins: [postcssImport(), tailwindcss(), autoprefixer()],
}),
],
},
{
input: "src/index.ts",
output: [{ file: "dist/index.d.ts", format: "es" }],
plugins: [dts.default()],
},
]);
Questions:
Why are there multiple imports for React and ReactDOM in my bundled output?
How can I ensure that my bundle only includes a single import for each dependency to avoid context issues and reduce the bundle size?
What I’ve Tried:
I have listed react and react-dom as external dependencies in my Rollup config.
I have also ensured that my source code consistently imports React.
Despite these efforts, the problem persists. Any suggestions or guidance on how to resolve this would be greatly appreciated!
I have listed react and react-dom as external dependencies in my Rollup config.
I have also ensured that my source code consistently imports React.
What am i expecting
- To have a single import of react and react DOM in my build output
- To get rid of the error
cannot import (useContext | useState ...) of undefined
in my host app