Skip to content

Commit df2cc3d

Browse files
authoredMay 27, 2022
fix: missing types for es-module-lexer (fixes #8349) (#8352)
1 parent 3f742b6 commit df2cc3d

File tree

6 files changed

+124
-2
lines changed

6 files changed

+124
-2
lines changed
 

‎CONTRIBUTING.md

+2
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ Vite aims to be fully usable as a dependency in a TypeScript project (e.g. it sh
214214

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

217+
Use `pnpm run check-dist-types` to check bundled types does not rely on types in `devDependencies`. If you are adding `dependencies`, make sure to configure `tsconfig.check.json`.
218+
217219
### Think before adding yet another option
218220

219221
We already have many config options, and we should avoid fixing an issue by adding yet another one. Before adding an option, try to think about:

‎packages/vite/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@
4949
"dev": "rimraf dist && pnpm run build-bundle -w",
5050
"build": "rimraf dist && run-s build-bundle build-types",
5151
"build-bundle": "rollup --config rollup.config.ts --configPlugin typescript",
52-
"build-types": "run-s build-temp-types patch-types roll-types",
52+
"build-types": "run-s build-temp-types patch-types roll-types check-dist-types",
5353
"build-temp-types": "tsc --emitDeclarationOnly --outDir temp/node -p src/node",
5454
"patch-types": "esno scripts/patchTypes.ts",
5555
"roll-types": "api-extractor run && rimraf temp",
56+
"check-dist-types": "tsc --project tsconfig.check.json",
5657
"lint": "eslint --ext .ts src/**",
5758
"format": "prettier --write --parser typescript \"src/**/*.ts\"",
5859
"prepublishOnly": "npm run build"

‎packages/vite/src/node/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export type {
3737
DepOptimizationProcessing,
3838
OptimizedDepInfo,
3939
DepsOptimizer,
40+
EsModuleLexerImportSpecifier,
41+
EsModuleLexerParseReturnType,
4042
ExportsData
4143
} from './optimizer'
4244
export type { Plugin } from './plugin'

‎packages/vite/src/node/optimizer/index.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import colors from 'picocolors'
66
import type { BuildOptions as EsbuildBuildOptions } from 'esbuild'
77
import { build } from 'esbuild'
88
import { init, parse } from 'es-module-lexer'
9+
import type { ImportSpecifier as EsModuleLexerImportSpecifier } from 'types/es-module-lexer'
910
import type { ResolvedConfig } from '../config'
1011
import {
1112
createDebugger,
@@ -31,7 +32,13 @@ const isDebugEnabled = _debug('vite:deps').enabled
3132
const jsExtensionRE = /\.js$/i
3233
const jsMapExtensionRE = /\.js\.map$/i
3334

34-
export type ExportsData = ReturnType<typeof parse> & {
35+
export type { EsModuleLexerImportSpecifier }
36+
export type EsModuleLexerParseReturnType = readonly [
37+
imports: ReadonlyArray<EsModuleLexerImportSpecifier>,
38+
exports: ReadonlyArray<string>,
39+
facade: boolean
40+
]
41+
export type ExportsData = EsModuleLexerParseReturnType & {
3542
// es-module-lexer has a facade detection but isn't always accurate for our
3643
// use case when the module has default export
3744
hasReExports?: true

‎packages/vite/tsconfig.check.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"noEmit": true,
4+
"moduleResolution": "classic",
5+
// Only add entries to `paths` when you are adding/updating dependencies (not devDependencies)
6+
// See CONTRIBUTING.md "Ensure type support" for more details
7+
"paths": {
8+
// direct
9+
"rollup": ["./node_modules/rollup/dist/rollup.d.ts"],
10+
// direct
11+
"esbuild": ["./node_modules/esbuild/lib/main.d.ts"],
12+
// direct
13+
"postcss": ["./node_modules/postcss/lib/postcss.d.ts"],
14+
// indirect: postcss depends on it
15+
"source-map-js": ["./node_modules/source-map-js/source-map.d.ts"]
16+
},
17+
"typeRoots": []
18+
},
19+
"include": ["dist/**/*.d.ts"]
20+
}
+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Modified and inlined to avoid extra dependency
2+
// Source: https://github.com/guybedford/es-module-lexer/blob/main/types/lexer.d.ts
3+
// MIT Licensed https://github.com/guybedford/es-module-lexer/blob/main/LICENSE
4+
5+
export interface ImportSpecifier {
6+
/**
7+
* Module name
8+
*
9+
* To handle escape sequences in specifier strings, the .n field of imported specifiers will be provided where possible.
10+
*
11+
* For dynamic import expressions, this field will be empty if not a valid JS string.
12+
*
13+
* @example
14+
* const [imports1, exports1] = parse(String.raw`import './\u0061\u0062.js'`);
15+
* imports1[0].n;
16+
* // Returns "./ab.js"
17+
*
18+
* const [imports2, exports2] = parse(`import("./ab.js")`);
19+
* imports2[0].n;
20+
* // Returns "./ab.js"
21+
*
22+
* const [imports3, exports3] = parse(`import("./" + "ab.js")`);
23+
* imports3[0].n;
24+
* // Returns undefined
25+
*/
26+
readonly n: string | undefined
27+
/**
28+
* Start of module specifier
29+
*
30+
* @example
31+
* const source = `import { a } from 'asdf'`;
32+
* const [imports, exports] = parse(source);
33+
* source.substring(imports[0].s, imports[0].e);
34+
* // Returns "asdf"
35+
*/
36+
readonly s: number
37+
/**
38+
* End of module specifier
39+
*/
40+
readonly e: number
41+
42+
/**
43+
* Start of import statement
44+
*
45+
* @example
46+
* const source = `import { a } from 'asdf'`;
47+
* const [imports, exports] = parse(source);
48+
* source.substring(imports[0].ss, imports[0].se);
49+
* // Returns `"import { a } from 'asdf';"`
50+
*/
51+
readonly ss: number
52+
/**
53+
* End of import statement
54+
*/
55+
readonly se: number
56+
57+
/**
58+
* If this import statement is a dynamic import, this is the start value.
59+
* Otherwise this is `-1`.
60+
*/
61+
readonly d: number
62+
63+
/**
64+
* If this import has an import assertion, this is the start value.
65+
* Otherwise this is `-1`.
66+
*/
67+
readonly a: number
68+
}
69+
70+
/**
71+
* Wait for init to resolve before calling `parse`.
72+
*/
73+
export const init: Promise<void>
74+
75+
/**
76+
* Outputs the list of exports and locations of import specifiers,
77+
* including dynamic import and import meta handling.
78+
*
79+
* @param source - Source code to parser
80+
* @param name - Optional sourcename
81+
* @returns Tuple contaning imports list and exports list.
82+
*/
83+
export function parse(
84+
source: string,
85+
name?: string
86+
): readonly [
87+
imports: ReadonlyArray<ImportSpecifier>,
88+
exports: ReadonlyArray<string>,
89+
facade: boolean
90+
]

0 commit comments

Comments
 (0)
Please sign in to comment.