Skip to content

Commit 4591603

Browse files
authored
Try aliasing preact typescript declaration to fix ts errors (#11088)
Right now the feedback PR fails ts3.8 e2e tests. This is because of TS issues, preact types do not work well with older TS types: ``` > @sentry-internal/ts3.8-test@ type-check /home/runner/work/sentry-javascript/sentry-javascript/dev-packages/e2e-tests/test-applications/generic-ts3.8 > tsc --project tsconfig.json ##[debug]Dropping file value '/home/runner/work/sentry-javascript/sentry-javascript/node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts'. Path does not exist Error: node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts(1462,3): error TS2304: Cannot find name 'SubmitEvent'. ##[debug]Dropping file value '/home/runner/work/sentry-javascript/sentry-javascript/node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts'. Path does not exist Error: node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts(1479,25): error TS2304: Cannot find name 'PictureInPictureEvent'. ##[debug]Dropping file value '/home/runner/work/sentry-javascript/sentry-javascript/node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts'. Path does not exist Error: node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts(2549,65): error TS2304: Cannot find name 'MathMLElement'. ##[debug]Dropping file value '/home/runner/work/sentry-javascript/sentry-javascript/node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts'. Path does not exist Error: node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts(2565,49): error TS2304: Cannot find name 'MathMLElement'. ##[debug]Dropping file value '/home/runner/work/sentry-javascript/sentry-javascript/node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts'. Path does not exist Error: node_modules/.pnpm/[email protected]/node_modules/preact/src/jsx.d.ts(2571,52): error TS2304: Cannot find name 'MathMLElement'. ``` Essentially these types don't work on older versions and because the feedback package is depended on by the browser package, we will break a certain set of our users. We have to fix this before we can ship because of the browser package dependency. To get around this, we do a workaround with `packages/feedback/scripts/shim-preact-export.js`. Essentially we shim the preact type in our exports, which should change what the declaration files themselves point to. So something like the following: ```ts import type { ComponentChildren, VNode } from 'preact'; ``` turns into ```ts // no preact to be seen! type ComponentChildren: any; type VNode: any; ```
1 parent c0ec628 commit 4591603

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

packages/feedback/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"build:dev": "run-p build:transpile build:types",
5555
"build:types": "run-s build:types:core build:types:downlevel",
5656
"build:types:core": "tsc -p tsconfig.types.json",
57-
"build:types:downlevel": "yarn downlevel-dts build/npm/types build/npm/types-ts3.8 --to ts3.8",
57+
"build:types:downlevel": "yarn downlevel-dts build/npm/types build/npm/types-ts3.8 --to ts3.8 && yarn node ./scripts/shim-preact-export.js",
5858
"build:watch": "run-p build:transpile:watch build:bundle:watch build:types:watch",
5959
"build:dev:watch": "run-p build:transpile:watch build:types:watch",
6060
"build:transpile:watch": "yarn build:transpile --watch",
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// preact does not support more modern TypeScript versions, which breaks our users that depend on older
2+
// TypeScript versions. To fix this, we shim the types from preact to be any and remove the dependency on preact
3+
// for types directly. This script is meant to be run after the build/npm/types-ts3.8 directory is created.
4+
5+
// Path: build/npm/types-ts3.8/global.d.ts
6+
7+
const fs = require('fs');
8+
const path = require('path');
9+
10+
/**
11+
* This regex looks for preact imports we can replace and shim out.
12+
*
13+
* Example:
14+
* import { ComponentChildren, VNode } from 'preact';
15+
*/
16+
const preactImportRegex = /import\s*{\s*([\w\s,]+)\s*}\s*from\s*'preact'\s*;?/;
17+
18+
function walk(dir) {
19+
const files = fs.readdirSync(dir);
20+
files.forEach(file => {
21+
const filePath = path.join(dir, file);
22+
const stat = fs.lstatSync(filePath);
23+
if (stat.isDirectory()) {
24+
walk(filePath);
25+
} else {
26+
if (filePath.endsWith('.d.ts')) {
27+
const content = fs.readFileSync(filePath, 'utf8');
28+
const capture = preactImportRegex.exec(content);
29+
if (capture) {
30+
const groups = capture[1].split(',').map(s => s.trim());
31+
32+
// This generates a shim snippet to replace the type imports from preact
33+
// It generates a snippet based on the capture groups of preactImportRegex.
34+
//
35+
// Example:
36+
//
37+
// import type { ComponentChildren, VNode } from 'preact';
38+
// becomes
39+
// type ComponentChildren: any;
40+
// type VNode: any;
41+
const snippet = groups.reduce((acc, curr) => {
42+
const searchableValue = curr.includes(' as ') ? curr.split(' as ')[1] : curr;
43+
44+
// look to see if imported as value, then we have to use declare const
45+
if (content.includes(`typeof ${searchableValue}`)) {
46+
return `${acc}declare const ${searchableValue}: any;\n`;
47+
}
48+
49+
// look to see if generic type like Foo<T>
50+
if (content.includes(`${searchableValue}<`)) {
51+
return `${acc}type ${searchableValue}<T> = any;\n`;
52+
}
53+
54+
// otherwise we can just leave as type
55+
return `${acc}type ${searchableValue} = any;\n`;
56+
}, '');
57+
58+
// we then can remove the import from preact
59+
const newContent = content.replace(preactImportRegex, '// replaced import from preact');
60+
61+
// and write the new content to the file
62+
fs.writeFileSync(filePath, snippet + newContent, 'utf8');
63+
}
64+
}
65+
}
66+
});
67+
}
68+
69+
function run() {
70+
// recurse through build/npm/types-ts3.8 directory
71+
const dir = path.join('build', 'npm', 'types-ts3.8');
72+
walk(dir);
73+
}
74+
75+
run();

0 commit comments

Comments
 (0)