[bug]: one .d.ts serves both import and require outputs, so types masquerade as CJS for ESM consumers
Maintainers usually reply within 6 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript, vite
- Domain
- build-system, cli, tooling
Research direction
Start with the vite-plugin-dts setup in build, then trace the default exports map written by init and the export checks in verify. Reproduce the issue with src/__tests__/fixtures/typescript-plugin and @arethetypeswrong/cli. Done means import and require conditions point to declarations in matching formats, and verification accepts the nested exports map.
Written by the indexing model from the issue text.
Description
What version of @strapi/sdk-plugin are you using?
@strapi/sdk-plugin6.1.1 (also currentmain)- Node.js 24.21.0
- TypeScript 5.x (checked with
@arethetypeswrong/cli0.18.5)
What's Wrong?
strapi-plugin build emits a single declaration file per bundle (dist/admin/src/index.d.ts, dist/server/src/index.d.ts), and the exports map generated by init points one top-level types condition at it for both the import (index.mjs) and require (index.js) outputs:
"./strapi-server": {
"types": "./dist/server/src/index.d.ts",
"source": "./server/src/index.ts",
"import": "./dist/server/index.mjs",
"require": "./dist/server/index.js",
"default": "./dist/server/index.js"
}
TypeScript decides a .d.ts file's module format from the nearest package.json#type. In a "type": "commonjs" plugin (what init generates), that one .d.ts is read as CommonJS, so ESM consumers resolving under node16/nodenext get CommonJS types for an ES module. Are the Types Wrong reports this as 🎭 Masquerading as CJS for both ./strapi-admin and ./strapi-server.
In a "type": "module" plugin the same layout flips the problem: the .d.ts is read as ESM, so require consumers would get ESM types (Masquerading as ESM).
To Reproduce
Using the repo's own typescript-plugin test fixture:
- Copy
src/__tests__/fixtures/typescript-pluginsomewhere outside the repo. - Build it with
strapi-plugin build. - Run
npx @arethetypeswrong/cli --pack .in that directory.
Output:
│ node10 │ node16 (from CJS) │ node16 (from ESM) │ bundler
"@strapi/plugin-test/strapi-admin" │ 💀 Resolution failed │ 🟢 (CJS) │ 🎭 Masquerading as CJS │ 🟢
"@strapi/plugin-test/strapi-server" │ 💀 Resolution failed │ 🟢 (CJS) │ 🎭 Masquerading as CJS │ 🟢
(The node10 failure is expected for an exports-only package with no top-level main/types. This issue is about the node16 (from ESM) column.)
Expected Behaviour
Each output format gets declarations TypeScript reads in the matching format, and the exports map points to them per condition, for example:
"./strapi-server": {
"source": "./server/src/index.ts",
"import": {
"types": "./dist/server/src/index.d.mts",
"default": "./dist/server/index.mjs"
},
"require": {
"types": "./dist/server/src/index.d.ts",
"default": "./dist/server/index.js"
},
"default": "./dist/server/index.js"
}
i.e. .d.mts next to ESM output and .d.ts / .d.cts next to CommonJS output, chosen to match package.json#type. ESM-only or CJS-only plugins keep a single declaration file in the right format.
This would touch:
- the
vite-plugin-dtssetup inbuild(emit declarations per format), - the default exports map written by
init, verify's export checks, which currently expect a top-leveltypesfirst and flat stringimport/requirevalues.
- Dominant language
- TypeScript
- Stars
- 24
- Forks
- 13
- Avg merge
- 5d 3h
- Merged PRs (30d)
- 5
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from strapi/sdk-plugin
-
Difficulty 4/5 Half a day Newbie friendliness 15/100
strapi/sdk-plugin#244 ·
Maintainers usually reply within 6 days
-
[bug]: build ignores exports file names and package.json#type, breaking "type": "module" pluginsPossibly taken @unrevised6419 claimed this 43 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 45/100
strapi/sdk-plugin#242 ·
Maintainers usually reply within 6 days
-
[feat]: build a subset of bundles with --bundle, for per-bundle task cachingPossibly taken @unrevised6419 claimed this 51 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 35/100
strapi/sdk-plugin#238 ·
Maintainers usually reply within 6 days
-
[bug]: When building with latest sdk-plugin version, I loose sub folders typesMay be free again @jhoward1994 claimed this 247 days ago, and no pull request is open. Openissue: bug
strapi/sdk-plugin#115 · 2 comments · 1 assignee ·
Maintainers usually reply within 6 days
-
issue: bug
Difficulty 2/5 1-3 hours Newbie friendliness 58/100
strapi/sdk-plugin#111 · 2 comments ·
Maintainers usually reply within 6 days
All issues in strapi/sdk-plugin
Similar issues
-
Add: BOM CineOpenapproved check:passed streams:add
Difficulty 1/5 Under an hour Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
bug platform-android
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Termix-SSH/Mobile#146 · 1 comment ·
Maintainers usually reply within 2 days
-
MCP mcp-feedback-pattern
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
getsentry/toolkit#2276 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
devswha/herdr-web-ui#3875 ·