Skip to content

Commit 291174d

Browse files
bluwysapphi-red
andauthoredSep 30, 2022
refactor(types): simplify type exports (#10243)
Co-authored-by: 翠 / green <green@sapphi.red>
1 parent 931d69b commit 291174d

40 files changed

+386
-510
lines changed
 

‎.eslintignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
dist
22
playground-temp
33
temp
4-
packages/vite/client/types.d.ts

‎.eslintrc.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ module.exports = defineConfig({
131131
}
132132
},
133133
{
134-
files: ['packages/vite/src/dep-types/**', '*.spec.ts'],
134+
files: ['packages/vite/src/types/**', '*.spec.ts'],
135135
rules: {
136136
'node/no-extraneous-import': 'off'
137137
}

‎.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*.local
66
*.log
77
/.vscode/
8-
/packages/vite/client/types.d.ts
98
/packages/vite/LICENSE
109
dist
1110
dist-ssr

‎.prettierignore

-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ playground/tsconfig-json-load-error/has-error/tsconfig.json
99
playground/html/invalid.html
1010
playground/html/valid.html
1111
playground/worker/classic-worker.js
12-
packages/vite/client/types.d.ts

‎CONTRIBUTING.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,12 @@ Avoid deps with large transitive dependencies that result in bloated size compar
218218

219219
Vite aims to be fully usable as a dependency in a TypeScript project (e.g. it should provide proper typings for VitePress), and also in `vite.config.ts`. This means technically a dependency whose types are exposed needs to be part of `dependencies` instead of `devDependencies`. However, this also means we won't be able to bundle it.
220220

221-
To get around this, we inline some of these dependencies' types in `packages/vite/src/dep-types`. This way, we can still expose the typing but bundle the dependency's source code.
221+
To get around this, we inline some of these dependencies' types in `packages/vite/src/types`. This way, we can still expose the typing but bundle the dependency's source code.
222222

223223
Use `pnpm run check-dist-types` to check that the bundled types do not rely on types in `devDependencies`. If you are adding `dependencies`, make sure to configure `tsconfig.check.json`.
224224

225+
For types shared between client and node, they should be added into `packages/vite/types`. These types are not bundled and are published as is (though they are still considered internal). Dependency types within this directory (e.g. `packages/vite/types/chokidar.d.ts`) are deprecated and should be added to `packages/vite/src/types` instead.
226+
225227
### Think Before Adding Yet Another Option
226228

227229
We already have many config options, and we should avoid fixing an issue by adding yet another one. Before adding an option, consider whether the problem:

‎docs/guide/api-plugin.md

+6-15
Original file line numberDiff line numberDiff line change
@@ -595,21 +595,12 @@ It is possible to type custom events by extending the `CustomEventMap` interface
595595

596596
```ts
597597
// events.d.ts
598-
import 'vite'
599-
import 'vite/client/types'
598+
import 'vite/types/customEvent'
600599
601-
interface MyCustomEventMap {
602-
'custom:foo': { msg: string }
603-
// 'event-key': payload
604-
}
605-
606-
// extend interface for server-side
607-
declare module 'vite' {
608-
interface CustomEventMap extends MyCustomEventMap {}
609-
}
610-
611-
// extend interface for client-side
612-
declare module 'vite/client/types' {
613-
interface CustomEventMap extends MyCustomEventMap {}
600+
declare module 'vite/types/customEvent' {
601+
interface CustomEventMap {
602+
'custom:foo': { msg: string }
603+
// 'event-key': payload
604+
}
614605
}
615606
```

‎packages/vite/api-extractor.client.json

-54
This file was deleted.

‎packages/vite/client.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// <reference path="./import-meta.d.ts" />
1+
/// <reference path="./types/importMeta.d.ts" />
22

33
// CSS modules
44
type CSSModuleClasses = { readonly [key: string]: string }

‎packages/vite/import-meta.d.ts

-10
This file was deleted.

‎packages/vite/package.json

+9-18
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,16 @@
2020
"./client": {
2121
"types": "./client.d.ts"
2222
},
23-
"./import-meta": {
24-
"types": "./import-meta.d.ts"
25-
},
26-
"./client/types": {
27-
"types": "./client/types.d.ts"
28-
},
2923
"./dist/client/*": "./dist/client/*",
3024
"./package.json": "./package.json"
3125
},
3226
"files": [
3327
"bin",
3428
"dist",
3529
"client.d.ts",
36-
"import-meta.d.ts",
3730
"index.cjs",
3831
"src/client",
39-
"types",
40-
"client/types.d.ts"
32+
"types"
4133
],
4234
"engines": {
4335
"node": "^14.18.0 || >=16.0.0"
@@ -55,13 +47,12 @@
5547
"dev": "rimraf dist && pnpm run build-bundle -w",
5648
"build": "rimraf dist && run-s build-bundle build-types",
5749
"build-bundle": "rollup --config rollup.config.ts --configPlugin typescript",
58-
"build-types": "run-p build-node-types build-client-types",
59-
"build-node-types": "run-s build-node-types-temp build-node-types-patch build-node-types-roll build-node-types-check",
60-
"build-node-types-temp": "tsc --emitDeclarationOnly --outDir temp/node -p src/node",
61-
"build-node-types-patch": "tsx scripts/patchTypes.ts",
62-
"build-node-types-roll": "api-extractor run && rimraf temp",
63-
"build-node-types-check": "tsc --project tsconfig.check.json",
64-
"build-client-types": "api-extractor run -c api-extractor.client.json",
50+
"build-types": "run-s build-types-temp build-types-pre-patch build-types-roll build-types-post-patch build-types-check",
51+
"build-types-temp": "tsc --emitDeclarationOnly --outDir temp/node -p src/node",
52+
"build-types-pre-patch": "tsx scripts/prePatchTypes.ts",
53+
"build-types-roll": "api-extractor run && rimraf temp",
54+
"build-types-post-patch": "tsx scripts/postPatchTypes.ts",
55+
"build-types-check": "tsc --project tsconfig.check.json",
6556
"lint": "eslint --cache --ext .ts src/**",
6657
"format": "prettier --write --cache --parser typescript \"src/**/*.ts\"",
6758
"prepublishOnly": "npm run build"
@@ -127,8 +118,8 @@
127118
"strip-literal": "^0.4.2",
128119
"tsconfck": "^2.0.1",
129120
"tslib": "^2.4.0",
130-
"dep-types": "link:./src/dep-types",
131-
"types": "link:./src/types",
121+
"dep-types": "link:./src/types",
122+
"types": "link:./types",
132123
"ufo": "^0.8.5",
133124
"ws": "^8.9.0"
134125
},

‎packages/vite/scripts/patchTypes.ts

-83
This file was deleted.
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { dirname, resolve } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import colors from 'picocolors'
4+
import { rewriteImports } from './util'
5+
6+
const dir = dirname(fileURLToPath(import.meta.url))
7+
const nodeDts = resolve(dir, '../dist/node/index.d.ts')
8+
9+
// rewrite `types/*` import to relative import
10+
rewriteImports(nodeDts, (importPath) => {
11+
if (importPath.startsWith('types/')) {
12+
return '../../' + importPath
13+
}
14+
})
15+
16+
console.log(colors.green(colors.bold(`patched types/* imports`)))
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { dirname, relative, resolve } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import colors from 'picocolors'
4+
import { rewriteImports, slash } from './util'
5+
6+
const dir = dirname(fileURLToPath(import.meta.url))
7+
const tempDir = resolve(dir, '../temp/node')
8+
const depTypesDir = resolve(dir, '../src/types')
9+
10+
// walk through the temp dts dir, find all import/export of, deps-types/*
11+
// and rewrite them into relative imports - so that api-extractor actually
12+
// includes them in the rolled-up final d.ts file.
13+
rewriteImports(tempDir, (importPath, currentFile) => {
14+
if (importPath.startsWith('dep-types/')) {
15+
const absoluteTypePath = resolve(
16+
depTypesDir,
17+
importPath.slice('dep-types/'.length)
18+
)
19+
return slash(relative(dirname(currentFile), absoluteTypePath))
20+
}
21+
})
22+
23+
console.log(colors.green(colors.bold(`patched deps-types/* imports`)))

‎packages/vite/scripts/util.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs'
2+
import { resolve } from 'node:path'
3+
import type { ParseResult } from '@babel/parser'
4+
import { parse } from '@babel/parser'
5+
import type { File } from '@babel/types'
6+
import colors from 'picocolors'
7+
import MagicString from 'magic-string'
8+
9+
export function rewriteImports(
10+
fileOrDir: string,
11+
rewrite: (importPath: string, currentFile: string) => string | void
12+
): void {
13+
walkDir(fileOrDir, (file) => {
14+
rewriteFileImports(file, (importPath) => {
15+
return rewrite(importPath, file)
16+
})
17+
})
18+
}
19+
20+
export function slash(p: string): string {
21+
return p.replace(/\\/g, '/')
22+
}
23+
24+
function walkDir(dir: string, handleFile: (file: string) => void): void {
25+
if (statSync(dir).isDirectory()) {
26+
const files = readdirSync(dir)
27+
for (const file of files) {
28+
const resolved = resolve(dir, file)
29+
walkDir(resolved, handleFile)
30+
}
31+
} else {
32+
handleFile(dir)
33+
}
34+
}
35+
36+
function rewriteFileImports(
37+
file: string,
38+
rewrite: (importPath: string) => string | void
39+
): void {
40+
const content = readFileSync(file, 'utf-8')
41+
const str = new MagicString(content)
42+
let ast: ParseResult<File>
43+
try {
44+
ast = parse(content, {
45+
sourceType: 'module',
46+
plugins: ['typescript', 'classProperties']
47+
})
48+
} catch (e) {
49+
console.log(colors.red(`failed to parse ${file}`))
50+
throw e
51+
}
52+
for (const statement of ast.program.body) {
53+
if (
54+
statement.type === 'ImportDeclaration' ||
55+
statement.type === 'ExportNamedDeclaration' ||
56+
statement.type === 'ExportAllDeclaration'
57+
) {
58+
const source = statement.source
59+
if (source?.value) {
60+
const newImportPath = rewrite(source.value)
61+
if (newImportPath) {
62+
str.overwrite(
63+
source.start!,
64+
source.end!,
65+
JSON.stringify(newImportPath)
66+
)
67+
}
68+
}
69+
}
70+
}
71+
writeFileSync(file, str.toString())
72+
}

0 commit comments

Comments
 (0)