playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF

Home Page:https://playcanvas.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Not loading TypeScript types definitions due to problematic "exports" field in package.json

LubomirFedor opened this issue · comments

Description

PlayCanvas Engine version: 1.70.2 (lower versions might be affected as well)
TypeScript version: 5.4.5 (possible affected as low as 4.7)

Issue:

package.json in the current version of the PlayCanvas Engine appears to contain problematic export field:

  "main": "build/playcanvas.js",
  "module": "build/playcanvas/src/index.js",
  "types": "build/playcanvas.d.ts",
  "exports": {
    ".": {
      "import": "./build/playcanvas/src/index.js",
      "require": "./build/playcanvas.js"
    },
    "./build/*": "./build/*"
  }

If tsconfig.json is set, for instance, like this:

"compilerOptions": {
		"noImplicitAny": true,
		"module": "ES2022",
		"target": "ES2022",
		"strict": true,
		"allowJs": true,
		"moduleResolution": "Bundler"
	}

TypeScript refuses to load the types with the following error:

Could not find a declaration file for module 'playcanvas'.
There are types at '/node_modules/playcanvas/build/playcanvas.d.ts', but this result could not be resolved when respecting package.json "exports". The 'playcanvas' library may need to update its package.json or typings.ts(7016)

Possible resolution

The issue appears to be related to the following paragraph from the TypeScript 4.7 Release Notes:

It’s important to note that the CommonJS entrypoint and the ES module entrypoint each needs its own declaration file, even if the contents are the same between them. Every declaration file is interpreted either as a CommonJS module or as an ES module, based on its file extension and the "type" field of the package.json, and this detected module kind must match the module kind that Node will detect for the corresponding JavaScript file for type checking to be correct. Attempting to use a single .d.ts file to type both an ES module entrypoint and a CommonJS entrypoint will cause TypeScript to think only one of those entrypoints exists, causing compiler errors for users of the package.

Based on the example from the Release Notes, the correct form of the exports field in the package.json should look similar to this:

    "exports": {
        ".": {
            // Entry-point for `import "playcanvas"` in ESM
            "import": {
                // Where TypeScript will look.
                "types": "./build/playcanvas/src/index.d.mts",
                // Where Node.js will look.
                "default": "./build/playcanvas/src/index.mjs"
            },
            // Entry-point for `require("playcanvas") in CJS
            "require": {
                // Where TypeScript will look.
                "types": "build/playcanvas.d.cts",
                // Where Node.js will look.
                "default": "./build/playcanvas.cjs"
            },
        }
    }
commented

@LubomirFedor try building the engine from main and use that because I also had a types issue with ts-node that was resolved by adding types to the exports field.

@LubomirFedor try building the engine from main and use that because I also had a types issue with ts-node that was resolved by adding types to the exports field.

In truth, I didn't even have to build the PlayCanvas Engine library anew, just use the package.json from the main branch with v1.70.2 and it worked 👍