Skip to content

@wordpress/dataviews 4.10.0 esm/commonjs confusion #67897

@anomiex

Description

@anomiex

CommonJS

If we're running in a CommonJS environment, the package cannot be required:

$ node -e 'require( "@wordpress/dataviews" );'
node:internal/modules/cjs/loader:647
      throw e;
      ^

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /tmp/test/node_modules/@wordpress/dataviews/package.json

This is particularly problematic when trying to test with jest, e.g.

const x = require( '@wordpress/dataviews' );

it( 'passes', () => {
    expect( true ).toBe( true );
} );

This fails with the following error:

    Cannot find module '@wordpress/dataviews' from 'foo.test.js'

    > 1 | const x = require( '@wordpress/dataviews' );
        |                                            ^
      2 |
      3 | it( 'passes', () => {
      4 |     expect( true ).toBe( true );

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at Object.<anonymous> (foo.test.js:1:44)

All this is because there is no commonjs export anymore after #66825, only types and import.

"exports": {
".": {
"types": "./build-types/index.d.ts",
"import": "./build-module/index.js"
},

Adding a "require": "./build/index.js" or "default": "./build/index.js" at the end of the object makes it work.

ESM

Let's look at Jest first, running the following test with --experimental-vm-modules as documented at https://jestjs.io/docs/ecmascript-modules.

import * as x from '@wordpress/dataviews';

it( 'passes', () => {
    expect( true ).toBe( true );
} );

This fails with the following error: (with some irrelevant text snipped)

  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    [...]

    Details:

    /tmp/test/node_modules/@wordpress/dataviews/build-module/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as DataViews } from './components/dataviews';
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1505:14)

This is because the file at node_modules/@wordpress/dataviews/build-module/index.js is supposedly in CommonJS format, not ESM, but actually contains ESM code. There are two different ways you might fix this:

  • Rename all the files under build-module/ to .mjs so they're parsed as ESM.
    • Also build-wp/index.js, since that contains ESM code too.
  • Add "type": "module" to the package.json so all .js files default to being interpreted as ESM.
    • And then rename all the files under build/ to .cjs so they're parsed as CommonJS.

Trying to import it with node --input-type=module -e 'import * as dataviews from "@wordpress/dataviews";' has additional problems due to the stricter ECMAScript loader:

  • It does not support folders as modules, directory indexes (e.g. './startup/index.js') must be fully specified.
  • It does no extension searching. A file extension must be provided when the specifier is a relative or absolute file URL.

so even after applying the fixes above we still get failures like

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/tmp/test/node_modules/@wordpress/dataviews/build-module/components/dataviews' is not supported resolving ES modules imported from /tmp/test/node_modules/@wordpress/dataviews/build-module/index.mjs

But since this package is probably not intended to be used that way (and it works with webpack and jest), it's probably safe to ignore that.

Metadata

Metadata

Assignees

Labels

[Package] DataViews/packages/dataviews[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions