Repository navigation
@rollup/plugin-typescript should error on TypeScript import of missing .json file (bundled with a different name by @rollup/plugin-json) #2008
Description
- Rollup Plugin Name:
@rollup/plugin-typescript - Rollup Plugin Version: 12.3.0
Feature Use Case
Careless use of @rollup/plugin-typescript and @rollup/plugin-json together results in broken TypeScript declarations, in a way that’s difficult to detect until after the package is published. A real example of this regression happening twice in the same package:
- [3.0.0 regression] error TS7016: Could not find a declaration file for module './adjacencyGraphs.json' zxcvbn-ts/zxcvbn#200
- [4.1.0 regression] error TS2307: Cannot find module './adjacencyGraphs.json' or its corresponding type declarations. zxcvbn-ts/zxcvbn#319
Here’s a minimal reproducible example:
package.json, tsconfig.json, src/data.json
package.json
{
"name": "rollup-typescript-json-test",
"version": "0.0.0",
"private": true,
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"devDependencies": {
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-typescript": "^12.3.0",
"rollup": "^4.61.1",
"typescript": "^6.0.3"
}
}tsconfig.json
{
"compilerOptions": {
"declaration": true,
"module": "nodenext",
"noEmit": true,
"outDir": "dist",
"rootDir": "src"
}
}src/data.json
[0, 1, 2]rollup.config.js
import json from "@rollup/plugin-json";
import typescript from "@rollup/plugin-typescript";
export default {
input: "src/index.ts",
plugins: [json(), typescript({ rootDir: "src" })],
output: { dir: "dist", preserveModules: true },
};src/index.ts
import data from "./data.json" with { type: "json" };
export { data };It passes tsc and seemingly builds cleanly with rollup -c, but the resulting type declarations are broken in a way that’s difficult to notice until after publication.
$ npm i
$ npx tsc
$ npx rollup -c
src/index.ts → dist...
created dist in 315ms
$ npx tsc --ignoreConfig --noEmit --module nodenext dist/index.d.ts
dist/index.d.ts:1:18 - error TS2307: Cannot find module './data.json' or its corresponding type declarations.
1 import data from "./data.json";
~~~~~~~~~~~~~
Found 1 error in dist/index.d.ts:1
$ npx tsc --ignoreConfig --noEmit dist/index.d.ts
dist/index.d.ts:1:18 - error TS7016: Could not find a declaration file for module './data.json'. '/home/anders/zulip/test/plugin-typescript-dts-json-repro/dist/data.json.js' implicitly has an 'any' type.
1 import data from "./data.json";
~~~~~~~~~~~~~
Found 1 error in dist/index.d.ts:1dist/data.json.js, dist/index.d.ts, dist/index.js
dist/data.json.js
var data = [
0,
1,
2
];
export { data as default };dist/index.d.ts
import data from "./data.json";
export { data };dist/index.js
export { default as data } from './data.json.js';The emitted declarations point to a nonexistent dist/data.json. The problem is that @rollup/plugin-json has emitted dist/data.json.js rather than dist/data.json, but TypeScript has no way to know this and couldn’t use dist/data.json.js even if it knew.
One way to discover this problem is using @arethetypeswrong/cli:
$ npx @arethetypeswrong/cli --pack .
rollup-typescript-json-test v0.0.0
Build tools:
- typescript@^6.0.3
- rollup@^4.61.1
- @rollup/plugin-typescript@^12.3.0
⚠️ A require call resolved to an ESM JavaScript file, which is an error in Node and some bundlers. CommonJS consumers will need to use a dynamic import. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/CJSResolvesToESM.md
🥴 Import found in a type declaration file failed to resolve. Either this indicates that runtime resolution errors will occur, or (more likely) the types misrepresent the contents of the JavaScript files. Use -f json to see the imports that failed to resolve. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/InternalResolutionError.md
┌───────────────────┬───────────────────────────────┐
│ │ "rollup-typescript-json-test" │
├───────────────────┼───────────────────────────────┤
│ node10 │ 🟢 │
├───────────────────┼───────────────────────────────┤
│ node16 (from CJS) │ ⚠️ ESM (dynamic import only) │
│ │ 🥴 Internal resolution error │
├───────────────────┼───────────────────────────────┤
│ node16 (from ESM) │ 🥴 Internal resolution error │
├───────────────────┼───────────────────────────────┤
│ bundler │ 🟢 │
└───────────────────┴───────────────────────────────┘But @arethetypeswrong/cli isn’t used nearly as widely as it should be, so it would be better if @rollup/plugin-typescript could somehow detect this problem before it happens.
Feature Proposal
@rollup/plugin-typescript could try to resolve relative imports and re-exports within the emitted declarations against the set of emitted files, and complain if any are missing.
Activity