react: Bug: using MessageChannel prevents node.js process from exiting


Edited: Here’s how to fix this: https://github.com/facebook/react/issues/20756#issuecomment-780927519.


React version: 17.0.1 (latest)

Steps To Reproduce

This code finishes properly in node.js 14, but holds the process open in node.js 15

global.window = global; // simulate JSDOM
require('scheduler');

Since node.js 15, there is a global MessageChannel object now, which prevents node event loop from exiting. To let the process shut down properly, it should either call port.close() or port.unref()

This becomes an issue when testing React code within JSDOM environment, as the test process cannot exit properly.

The current behavior

The process with JSDOM tests never finishes

The expected behavior

The process finishes properly

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 4
  • Comments: 15 (4 by maintainers)

Commits related to this issue

Most upvoted comments

How to fix this

If you can upgrade to React 17.1.0

When React 17.1.0 comes out, it will contain a fix for this. So upgrading would solve this problem.

(At the time this comment is written, it’s not out yet, but I expect it to be out soon.)

If you can’t upgrade to React 17.1.0

npm i react-16-node-hanging-test-fix 

and add this to your test setup file as THE VERY FIRST IMPORT:

import 'react-16-node-hanging-test-fix';

// All other imports go after it:
import React from 'react'
// ...

(For example, Create React App projects use src/setupTests.js as the test setup file, otherwise you’ll need to refer to your test runner’s documentation. In Jest, the option is called setupFiles).

This should fix the hanging on Node 15+ with jsdom on older versions of React. We don’t plan to be updating them because there’s too much risk of breaking something else, as this detection is subtle and there are many possible edge cases.

The package with the fix will print a warning asking you to remove it after you upgrade to React 17.1.0. This is because the fix itself is to disable Node’s MessageChannel implementation, which is not ideal in long term.


Let me know if you run into more problems! I’ll keep the issue for now until we release 17.1.0.

Brilliant fix 😃

delete global.MessageChannel;

Would it make sense to let Node.js devs know that this is happening? Perhaps, they could consider undoing the change in Node 16.

For now I’ve just kept using the temp fix package but patched it to adjust the version on which it applies the warning. I’m hoping we can update storybook soon and so won’t need to make any adjustments after that.

On Fri, Sep 9, 2022, 7:12 AM Andre Rosa @.***> wrote:

@jarredt https://github.com/jarredt did you manage to get around this issue? We are facing the same problem.

— Reply to this email directly, view it on GitHub https://github.com/facebook/react/issues/20756#issuecomment-1242025962, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD7LLP5KECNACCBT4WADX6DV5NATTANCNFSM4XHPUFZQ . You are receiving this because you were mentioned.Message ID: @.***>

@rickhanlonii – ah, so we’re using 20.0.2 for react-dom, but one of our storybook-related dependencies is bringing in 0.19.1 as a transitive of react-dom@16.14.0. I assume that may be the issue I’ll see if I can get that bumped or excluded from executing in our tests.

Also… it looks like maybe the fix actually didn’t land until React 18, so maybe needs to be changed to 18.0.0?

Ref: Mention of the fixing PR (#20834) in https://github.com/facebook/react/pull/24195.

@gaearon – I think the react-16-node-hanging-test-fix file may have a critical typo:

if (semverGt(version, '17.0.1')) {
  console.error(
    'The `react-16-node-hanging-test-fix` package is no longer needed ' +
    'with React ' + version + ' and may cause issues. Remove this import.'
  )
}

Shouldn’t the if be evaluating for “greater than or equal to 17.1.0”? Per your comment and the comment at the top of the package file, the issue is fixed starting with 17.1.0.

Right now it’s evaluating “greater than 17.0.1” – so I’m getting the warning for 17.0.2 even though the issue isn’t fixed there.

We’re going with https://github.com/facebook/react/pull/20834 as a likely fix in 17.1.0, but it will need more testing.