nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.69k stars 2.36k forks source link

Identifier 'React' has already been declared error when building npm package with nx:rollup #17769

Closed pavinduLakshan closed 7 months ago

pavinduLakshan commented 1 year ago

Current Behavior

We are trying to upgrade the nx version in our monorepo from v14 to v16.3.2. After running all the migrations, we are now facing a issue when building one of our projects.

The project has a directory of svg icons in modules/react-components/src/assets/images which is being used by other ts files in the module as follows.

modules/react-components/src/components/alert/alert.tsx

import ErrorIcon from "../../assets/images/error-icon.svg";
import InfoIcon from "../../assets/images/info-icon.svg";
import SuccessIcon from "../../assets/images/success-icon.svg";
import WarningIcon from "../../assets/images/warning-icon.svg";

The error thrown during the build is related to bundling these icons. I have added the error stack trace and the configs we use at https://stackoverflow.com/questions/76544765/identifier-react-has-already-been-declared-when-building-npm-package-with-nxr/76545003.

Expected Behavior

The module should be built without any errors.

GitHub Repo

https://github.com/pavinduLakshan/nx-svg-issue-repro

Steps to Reproduce

  1. Clone the repo.
  2. Run pnpm install in the project root.
  3. Run pnpm build from the project root.
  4. You will see the build error printed in the terminal.

Nx Report

Node   : 16.17.0
   OS     : darwin arm64
   pnpm   : 8.6.0
   Hasher : Native

   nx                 : 16.3.2
   lerna              : 7.0.2
   @nx/js             : 16.3.2
   @nx/jest           : 16.3.2
   @nx/linter         : 16.3.2
   @nx/workspace      : 16.3.2
   @nx/cypress        : 16.3.2
   @nx/devkit         : 16.3.2
   @nx/eslint-plugin  : 16.3.2
   @nx/plugin         : 16.3.2
   @nx/react          : 16.3.2
   @nx/rollup         : 16.3.2
   @nx/storybook      : 16.3.2
   @nrwl/tao          : 16.3.2
   @nx/web            : 16.3.2
   @nx/webpack        : 16.3.2
   typescript         : 5.1.3
   ---------------------------------------
   Local workspace plugins:
         @nms/react-components
         @nms/forms
         @nms/form

Failure Logs

✖  nx run react-components:build
       Bundling react-components...
       Error during bundle: Error: unknown: Identifier 'React' has already been declared. (48:12)

         46 |   return target;
         47 | }
       > 48 | import * as React from "react";
            |             ^
         49 | import { forwardRef } from "react";
         50 | var SvgCodeIcon = function SvgCodeIcon(_ref, ref) {
         51 |   var title = _ref.title,
       Error during bundle: Error: unknown: Identifier 'React' has already been declared. (48:12)

         46 |   return target;
         47 | }
       > 48 | import * as React from "react";
            |             ^
         49 | import { forwardRef } from "react";
         50 | var SvgInfoIcon = function SvgInfoIcon(_ref, ref) {
         51 |   var title = _ref.title,
       Bundle failed: react-components

 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Ran target build for 12 projects (15s)

    ✔    8/9 succeeded [8 read from cache]

    ✖    1/9 targets failed, including the following:
         - nx run react-components:build

 ELIFECYCLE  Command failed with exit code 1.

Operating System

Additional Information

N/A

GuskiS commented 1 year ago

Having same issue. Removing @svgr/rollup plugin fixed problem for me 🤔 See repro rollup config.

pavinduLakshan commented 1 year ago

Having same issue. Removing @svgr/rollup plugin fixed problem for me 🤔 See repro rollup config.

@GuskiS yes, removing that indeed does resolve the issue, but not entirely. When that is removed, svg files are not properly bundled and the other packages that use this module start throwing errors 😢

pavinduLakshan commented 1 year ago

Hi all, any update on this? we cannot upgrade to nx16 due to this issue. Appreciate it if you can attend to this at ur earliest convenience. 🙌

github-actions[bot] commented 10 months ago

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

pavinduLakshan commented 10 months ago

Please keep this issue open. We are still facing this issue and upgrading nx is blocked due to this.

hrafnkellb-advania commented 9 months ago

I had this error and was able to fix it just now for me.

I don't know if this fixes the error for you, but I had to make sure that I had @svgr/rollup and @rollup/plugin-url installed as a dev dependency in my project. I assumed that the @nx/react would already have it installed.

I'm using NX version 17.2.3 at the moment, and installed @rollup/plugin-url": "^8.0.2" and "@svgr/rollup": "^8.1.0". I'm also not using a custom rollup config, just the default one from @nx/react/plugins/bundle-rollup

image

One thing I see that is different from the reproduction custom rollup config, is the order of the plugins. In the reproduction repo, the url and svgr plugins are added after the default nx plugins.

// Reproduction rollup config /modules/react-components/rollup.config.cjs
const nrwlConfig = require("@nx/react/plugins/bundle-rollup");
const url = require("@rollup/plugin-url");
const svgr = require("@svgr/rollup");

module.exports = (config) => {
    const nxConfig = nrwlConfig(config);

    return {
        ...nxConfig,
        plugins: [
           ...nxConfig.plugins, 
          // Plugins are being added after the nx config default plugins
            url(), 
            svgr({native: true}) ],
    };
};

But in the default react rollup config ( @nx/react/plugins/bundle-rollup), the plugins are added before the default nx plugins:

// \node_modules\@nx\react\plugins\bundle-rollup.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getRollupOptions(options) {
    const extraGlobals = {
        react: 'React',
        'react-dom': 'ReactDOM',
        'styled-components': 'styled',
        '@emotion/react': 'emotionReact',
        '@emotion/styled': 'emotionStyled',
    };
    if (Array.isArray(options.output)) {
        options.output.forEach((o) => {
            o.globals = { ...o.globals, ...extraGlobals };
        });
    }
    else {
        options.output = {
            ...options.output,
            globals: {
                ...options.output.globals,
                ...extraGlobals,
            },
        };
    }
    // React buildable libs support SVGR, but not for React Native.
    // If imports fail, ignore it.
    try {
        const url = require('@rollup/plugin-url');
        const svg = require('@svgr/rollup');
        options.plugins = [
            // Here the plugins are being prepended to the plugins array
            svg({
                svgo: false,
                titleProp: true,
                ref: true,
            }),
            url({
                limit: 10000, // 10kB
            }),
            ...options.plugins,
        ];
    }
    catch {
        // Ignored for React Native
    }
    return options;
}
module.exports = getRollupOptions;

You could try to see if the order is the issue, by doing the following changes, but it was enough for me to use the default bundle-rollup from the @nx/react package, but making sure that @rollup/plugin-url and @svgr/rollup were installed in my project

const nrwlConfig = require("@nx/react/plugins/bundle-rollup");
const url = require("@rollup/plugin-url");
const svgr = require("@svgr/rollup");

module.exports = (config) => {
    const nxConfig = nrwlConfig(config);

    return {
        ...nxConfig,
        plugins: [
             svgr({native: true}) ],
             url(), 
            ...nxConfig.plugins, 
    };
};
jaysoo commented 7 months ago

The issue is a conflict between the SVGR plugin that @nx/react/plugins/bundle-rollup provides and your own. I would filter it out before adding your own.

This is the updated config that would work:

const nrwlConfig = require("@nx/react/plugins/bundle-rollup");
const url = require("@rollup/plugin-url");
const svgr = require("@svgr/rollup");

module.exports = (config) => {
    const nxConfig = nrwlConfig(config);
  console.log(config, nxConfig);

  const plugins = nxConfig.plugins.filter(p => {
    // Remove SVGR from Nx
    return p.name !=='svgr'
  });
    return {
        ...nxConfig,
        plugins: [ ...plugins,
            url(),
            svgr({native: true}) ],
    };
};
pavinduLakshan commented 7 months ago

Thanks for the response @jaysoo , but there is a different error now, when building that package.

Bundling react-components...
Error during bundle: Error: Could not resolve './components' from src/index.ts
Error during bundle: Error: Could not resolve './layouts' from src/index.ts
Bundle failed: react-components

The import paths are correct and have been set a long time ago. thereforce, I believe it's due to. removing svgr from nx.

Do you have any idea on the RC?

github-actions[bot] commented 6 months ago

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.