Skip to content

Commit fd6fded

Browse files
authored
fix: Fixed shimming for node-like environments (#1229)
Closes #1050 Some external test suites using tools like jest were failing with the message ``` TypeError: import_server_safe_globals.globalThis.ResizeObserver is not a constructor ``` This was happening because the resize observer shim was not being included for test environments like `jsdom`. Apparently `jsdom` adds an implementation for custom elements APIs, meaning that the old `isServer` check would evaluate as `false`, but no implementation for `ResizeObserver`, causing the issue. Initially the approach was to add missing shims to account for the missing functions. We decided to change this because if any shim is missing, we can't affirm that our code will work, so we fallback to all shims. Therefore, we change the way we detect if we are executing in a server environment. We check this by checking if the [global attribute](https://nodejs.org/api/globals.html#global) is present. Taking into account that this attribute is Legacy, but unlikely to be removed. ([Stability-3](https://nodejs.org/api/documentation.html#stability-index )). --- To test this I created a small project with `vite`, `vitest`, `jsdom`and `media-chrome`, and added this small test. It was mentioned that just by importing `MediaPlaybackRateButton` would cause the issue. ```js import { MediaPlaybackRateButton } from 'media-chrome/react'; import { render } from '@testing-library/react'; import '@testing-library/jest-dom' describe('Media Chrome React component test', () => { test('renders MediaPlaybackRateButton without crashing', () => { render(<MediaPlaybackRateButton />); }); }); ``` Before the changes I would get the same error message. After changing this, the test passes. Also tested this in different test environments `happy-dom`, `node` and `edge-runtime`. `node` and `edge-runtime` fail because they don't have a document, but it is expected since @testing-library/react doesn't use the shimmed document and these envs don't define it either. Also tested this in a simple project with jest, without react. In this case the non react version of media playback rate button does not use `ResizeObserver`, so we import `globalThis` directly. ```js import { globalThis } from 'media-chrome/dist/utils/server-safe-globals'; describe('Media Chrome ResizeObserver test', () => { test('ResizeObserver shim exists', () => { expect(globalThis.ResizeObserver).not.toBe(undefined) }); }); ```
1 parent 884f3ce commit fd6fded

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

src/js/utils/server-safe-globals.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ const globalThisShim = {
8484
} as unknown as typeof globalThis;
8585

8686
export const isServer =
87-
typeof window === 'undefined' || typeof window.customElements === 'undefined';
87+
'global' in globalThis && globalThis?.global === globalThis || // node or node-like environments, whether or not there are global polyfills like jsdom
88+
typeof window === 'undefined' || typeof window.customElements === 'undefined'; // generic check for global window object to account for non-node-like server environements
8889

8990
const isShimmed = Object.keys(globalThisShim).every((key) => key in globalThis);
9091

0 commit comments

Comments
 (0)