Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@wordpress/api-fetch works weirdly with ES modules #59087

Open
anomiex opened this issue Feb 15, 2024 · 4 comments
Open

@wordpress/api-fetch works weirdly with ES modules #59087

anomiex opened this issue Feb 15, 2024 · 4 comments
Labels
Good First Issue An issue that's suitable for someone looking to contribute for the first time [Package] API fetch /packages/api-fetch [Type] Bug An existing feature does not function as intended

Comments

@anomiex
Copy link
Contributor

anomiex commented Feb 15, 2024

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

package.json
{
	"type": "module",
	"dependencies": {
		"@wordpress/api-fetch": "^6.48.0",
		"typescript": "^5.0.4"
	}
}
tsconfig.json
{
	"include": [ "./src/**/*" ],
	"compilerOptions": {
		"outDir": "./build/",
		// Per https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution-for-libraries
		"module": "nodenext",
		"moduleResolution": "nodenext"
	}
}
src/index.ts
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.

@jordesign jordesign added [Type] Bug An existing feature does not function as intended [Package] API fetch /packages/api-fetch labels Feb 16, 2024
@gziolo gziolo added the Good First Issue An issue that's suitable for someone looking to contribute for the first time label Mar 8, 2024
@alexsanford
Copy link
Contributor

I don't think it makes sense to use nodenext for the module and moduleResolution options since apiFetch doesn't work outside of a browser context. Using "module": "esnext" and "moduleResolution": "bundler" seems like it would make more sense, and in my testing, TypeScript compiles fine with these options.

As for the issue with .default, this also seems to be a problem in the node context (which doesn't work with apiFetch anyway) whereas using a supported build process like wp-scripts should be fine.

@anomiex
Copy link
Contributor Author

anomiex commented Jul 11, 2024

If you compile your TypeScript-based library with "bundler", then anyone using your library has to also be using "bundler". That's annoying if your library is supposed to be usable in both browsers and node. Even if @wordpress/api-fetch is only used by the library in browser-related code paths, the code still needs to compile.

whereas using a supported build process like wp-scripts should be fine.

I don't think that limiting the package to only working with a single build process is a good idea. Should everyone else in the world really be locked out of using it?

@alexsanford
Copy link
Contributor

It makes sense in theory, but I'm not really clear on the practical implications. Seems like the api-fetch library is specifically built for a browser context within the WordPress environment, and more work would need to be done anyway to make it usable outside of that. Is there a specific use-case driving this issue?

@anomiex
Copy link
Contributor Author

anomiex commented Jul 12, 2024

Is there a specific use-case driving this issue?

We had to work around this bug in https://www.npmjs.com/package/@automattic/jetpack-ai-client, after others trying to use the package ran into the issue about moduleResolution: "bundler" being infectious.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue An issue that's suitable for someone looking to contribute for the first time [Package] API fetch /packages/api-fetch [Type] Bug An existing feature does not function as intended
4 participants