WordPress/gutenberg

`@wordpress/api-fetch` works weirdly with ES modules

Open

#59087 opened on Feb 15, 2024

View on GitHub
 (19 comments) (1 reaction) (2 assignees)JavaScript (9,607 stars) (3,893 forks)batch import
Good First Issue[Package] API fetch[Status] In Progress[Type] Bug

Description

When using @wordpress/api-fetch in a TypeScript library, tsc complains that apiFetch is not callable.

The problem being encountered here is described in depth at https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/CJSOnlyExportsDefault.md

Example

{
	"type": "module",
	"dependencies": {
		"@wordpress/api-fetch": "^6.48.0",
		"typescript": "^5.0.4"
	}
}
{
	"include": [ "./src/**/*" ],
	"compilerOptions": {
		"outDir": "./build/",
		// Per https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution-for-libraries
		"module": "nodenext",
		"moduleResolution": "nodenext"
	}
}
import apiFetch from '@wordpress/api-fetch';

apiFetch( { path: '/wp/v2/posts' } ).then( ( posts ) => {
	console.log( posts );
} );

Run npm install, then npm exec tsc to attempt to build the "library".

Expected results

Build succeeds

Actual results

src/index.ts:3:1 - error TS2349: This expression is not callable.
  Type 'typeof import("/tmp/test/node_modules/@wordpress/api-fetch/build-types/index")' has no call signatures.

3 apiFetch( { path: '/wp/v2/posts' } ).then( ( posts ) => {
  ~~~~~~~~


Found 1 error in src/index.ts:3

Notes

If we change the apiFetch() call to apiFetch.default(), tsc is happy but then the code won't work when the library is bundled and served to a browser.

To make things work in both environments, we needed to do something like this.

Contributor guide