Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught TypeError: Cannot redefine property: render #104

Closed
indapublic opened this issue Feb 21, 2023 · 9 comments · Fixed by #140
Closed

Uncaught TypeError: Cannot redefine property: render #104

indapublic opened this issue Feb 21, 2023 · 9 comments · Fixed by #140

Comments

@indapublic
Copy link

Uncaught TypeError: Cannot redefine property: render
    at Function.defineProperty (<anonymous>)
    at <unknown> (file:///..../app/node_modules/@uiw/react-color/cjs/index.js:188:10)

NextJS (tried to turn off SSR, checked for window variable etc) - no difference. Do you have any advises here? Thank you in advance

@jaywcjlove
Copy link
Member

@jaywcjlove
Copy link
Member

@victoriaSh
Copy link

I've attempted to use the 'next-remove-imports', but I'm still getting 'Cannot redefine property: render' error.
Am I doing something incorrectly?

My next.config.js:

const { withSentryConfig } = require('@sentry/nextjs');
const removeImports = require("next-remove-imports")();
const withPlugins = require('next-compose-plugins');

let config = {
  reactStrictMode: true,
  experimental: { esmExternals: true },
  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  },
};

module.exports = withPlugins([
    removeImports,
    [ withSentryConfig,
        { silent: true ,
        hideSourcemaps: true },
    ]
], config);

@jaywcjlove
Copy link
Member

@victoriaSh

// next.config.js
const removeImports = require('next-remove-imports')();

module.exports = (phase, { defaultConfig }) => {
  return removeImports({
    ...defaultConfig
  });
};
// next.config.js
const removeImports = require('next-remove-imports')({
  test: /node_modules([\s\S]*?)\.(tsx|ts|js|mjs|jsx)$/,
  matchImports: "\\.(less|css|scss|sass|styl)$"
});

module.exports = removeImports({
  webpack(config, options) {
    return config
  },
});
// next.config.js
const removeImports = require('next-remove-imports')()
module.exports = removeImports({
  webpack(config, options) {
    return config
  },
});

@fantoine
Copy link

Hi there, it looks like the same error occurs on Jest test suites ran on a pure React project (no NextJS involved here).

I use the commonJS bundle and tracked the error down to @uiw/react-color-colorful lib import.
In the built source (in @uiw/react-color/cjs/index.js file), it happens here (line 188):

image

I'm not sure that the next-remove-imports lib is a solution in this case. Do you have any other solution in mind ?

Thanks !

@fantoine
Copy link

fantoine commented Sep 20, 2023

OK, I found a solution by myself.

If other people get the same issue, that's what I did:

  • Import react-color classes from '@uiw/react-color/esm'
  • Add @uiw/.*, colors-named, and colors-named-hex patterns to your Jest configuration in transformIgnorePatterns value (eg: transformIgnorePatterns: ['/node_modules/(?!@uiw|colors-named|colors-named-hex)'],

@SimplySayHi
Copy link

SimplySayHi commented Dec 19, 2023

I have a NextJS project and faced the same issue.
Just found out that importing components from @uiw/react-color/src/index, solved the issue.

For example:
import { Circle } from "@uiw/react-color/src/index";

Importing components from @uiw/react-color/esm raised another error.

@clarkmcc
Copy link

Had this same issue when using Astro. Changing imports to @uiw/react-color/src/index worked

import { Sketch } from "@uiw/react-color/src/index";

@dangreaves
Copy link
Contributor

dangreaves commented Feb 16, 2024

Just to clarify, this problem is nothing to do with Next.js or Jest. The problem is that the CommonJS build is broken, so anything which imports the CommonJS build will get this error.

This can be confirmed by creating the following simple CommonJS file, and seeing the error.

const reactColor = require("@uiw/react-color");
console.log(reactColor);
// Uncaught TypeError: Cannot redefine property: render

The reason this breaks is because in the package export, every sub package is exported with export * from "foo". The problem with that is multiple packages define a render export.

When this compiles to CommonJS, it ends up like this. Each of these Object.keys blocks is looping over all the exports from the sub package, and attaching them to exports using Object.defineProperty.

var _reactColorSwatch = _interopRequireWildcard(require("@uiw/react-color-swatch"));
Object.keys(_reactColorSwatch).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
  if (key in exports && exports[key] === _reactColorSwatch[key]) return;
  Object.defineProperty(exports, key, {
    enumerable: true,
    get: function get() {
      return _reactColorSwatch[key];
    }
  });
});
var _reactColorWheel = _interopRequireWildcard(require("@uiw/react-color-wheel"));
Object.keys(_reactColorWheel).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
  if (key in exports && exports[key] === _reactColorWheel[key]) return;
  Object.defineProperty(exports, key, {
    enumerable: true,
    get: function get() {
      return _reactColorWheel[key];
    }
  });
});

You cannot use Object.defineProperty to redefine an existing property. So the first block defines a render property on exports, and then subsequent packages try to set the same property, causing the error.

The solution is to avoid exporting sub packages like this, or at least being careful that each sub package defines unique exports. I have added a PR (#140) which addresses this.

As a super hacky fix, I have added a patch to my project which adds the configurable option to each Object.defineProperty in the CommonJS file. This allows subsequent packages to overwrite the render export without the error, but it would be preferable if this package did not add duplicate exports at all.

var _reactColorWheel = _interopRequireWildcard(require("@uiw/react-color-wheel"));
Object.keys(_reactColorWheel).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
  if (key in exports && exports[key] === _reactColorWheel[key]) return;
  Object.defineProperty(exports, key, {
    enumerable: true,
+   configurable: true,
    get: function get() {
      return _reactColorWheel[key];
    }
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants