The package @wordpress/preferences attempts to use @wordpress/element from build/components/preference-toggle-menu-item/index.js and build-module/components/preference-toggle-menu-item/index.js, but does not declare a dependency or peer dependency on that package.
This happens to work with npm's hoisting due to other dependencies pulling that package in, but will fail with yarn's p'n'p or pnpm with hoisting disabled.
Reproduction
With yarn:
- Create a temporary directory, and cd into it.
echo '{}' > package.json
yarn set version stable
yarn add @wordpress/preferences react@^17 react-dom@^17 @babel/core jsdom global-jsdom
- Run either of the following:
yarn node -e 'require( "global-jsdom/register" ); const x = require( "@wordpress/preferences" ); console.log( x.PreferenceToggleMenuItem );'
yarn node --input-type=module -e 'import "global-jsdom/register"; import x from "@wordpress/preferences"; console.log( x.PreferenceToggleMenuItem );'
With pnpm:
- Create a temporary directory, and cd into it.
echo 'hoist-pattern=[]' > .npmrc
pnpm add @wordpress/preferences react@^17 react-dom@^17 @babel/core jsdom global-jsdom
- Run either of the following:
node -e 'require( "global-jsdom/register" ); const x = require( "@wordpress/preferences" ); console.log( x.PreferenceToggleMenuItem );'
node --input-type=module -e 'import "global-jsdom/register"; import x from "@wordpress/preferences"; console.log( x.PreferenceToggleMenuItem );'
Expected behavior
Output along the lines of
[Function: PreferenceToggleMenuItem]
Actual behavior
With yarn:
Error: @wordpress/preferences tried to access @wordpress/element, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.
Required package: @wordpress/element
Required by: @wordpress/preferences@virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.0 (via /tmp/test/.yarn/__virtual__/@wordpress-preferences-virtual-777cc2d26f/0/cache/@wordpress-preferences-npm-2.1.0-bb58ebd633-a834d729d6.zip/node_modules/@wordpress/preferences/build/components/preference-toggle-menu-item/)
With pnpm:
Error: Cannot find module '@wordpress/element'
Require stack:
- /tmp/test/node_modules/.pnpm/@wordpress+preferences@2.1.0_noz7egsnsfdcs6s6px6pthieke/node_modules/@wordpress/preferences/build/components/preference-toggle-menu-item/index.js
- /tmp/test/node_modules/.pnpm/@wordpress+preferences@2.1.0_noz7egsnsfdcs6s6px6pthieke/node_modules/@wordpress/preferences/build/components/index.js
The package
@wordpress/preferencesattempts to use@wordpress/elementfrombuild/components/preference-toggle-menu-item/index.jsandbuild-module/components/preference-toggle-menu-item/index.js, but does not declare a dependency or peer dependency on that package.This happens to work with
npm's hoisting due to other dependencies pulling that package in, but will fail with yarn's p'n'p or pnpm with hoisting disabled.Reproduction
With yarn:
echo '{}' > package.jsonyarn set version stableyarn add @wordpress/preferences react@^17 react-dom@^17 @babel/core jsdom global-jsdomyarn node -e 'require( "global-jsdom/register" ); const x = require( "@wordpress/preferences" ); console.log( x.PreferenceToggleMenuItem );'yarn node --input-type=module -e 'import "global-jsdom/register"; import x from "@wordpress/preferences"; console.log( x.PreferenceToggleMenuItem );'With pnpm:
echo 'hoist-pattern=[]' > .npmrcpnpm add @wordpress/preferences react@^17 react-dom@^17 @babel/core jsdom global-jsdomnode -e 'require( "global-jsdom/register" ); const x = require( "@wordpress/preferences" ); console.log( x.PreferenceToggleMenuItem );'node --input-type=module -e 'import "global-jsdom/register"; import x from "@wordpress/preferences"; console.log( x.PreferenceToggleMenuItem );'Expected behavior
Output along the lines of
Actual behavior
With yarn:
With pnpm: