Skip to content

Commit ed99a2c

Browse files
bteasapphi-red
andauthored
perf: reduce bundle size for Object.keys(import.meta.glob(...)) / Object.values(import.meta.glob(...)) (#18666)
Co-authored-by: 翠 / green <[email protected]>
1 parent a384d8f commit ed99a2c

File tree

3 files changed

+175
-14
lines changed

3 files changed

+175
-14
lines changed

packages/vite/src/node/__tests__/plugins/importGlob/__snapshots__/fixture.spec.ts.snap

+88-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,60 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`fixture > transform 1`] = `
4-
"import * as __vite_glob_1_0 from "./modules/a.ts";import * as __vite_glob_1_1 from "./modules/b.ts";import * as __vite_glob_1_2 from "./modules/index.ts";import { name as __vite_glob_3_0 } from "./modules/a.ts";import { name as __vite_glob_3_1 } from "./modules/b.ts";import { name as __vite_glob_3_2 } from "./modules/index.ts";import { default as __vite_glob_5_0 } from "./modules/a.ts?raw";import { default as __vite_glob_5_1 } from "./modules/b.ts?raw";import "types/importMeta";
4+
"import * as __vite_glob_3_0 from "./modules/a.ts";import * as __vite_glob_3_1 from "./modules/b.ts";import * as __vite_glob_3_2 from "./modules/index.ts";import * as __vite_glob_5_0 from "./modules/a.ts";import * as __vite_glob_5_1 from "./modules/b.ts";import * as __vite_glob_5_2 from "./modules/index.ts";import { name as __vite_glob_9_0 } from "./modules/a.ts";import { name as __vite_glob_9_1 } from "./modules/b.ts";import { name as __vite_glob_9_2 } from "./modules/index.ts";import { name as __vite_glob_11_0 } from "./modules/a.ts";import { name as __vite_glob_11_1 } from "./modules/b.ts";import { name as __vite_glob_11_2 } from "./modules/index.ts";import { default as __vite_glob_15_0 } from "./modules/a.ts?raw";import { default as __vite_glob_15_1 } from "./modules/b.ts?raw";import "types/importMeta";
55
export const basic = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts"),"./modules/index.ts": () => import("./modules/index.ts")});
6-
export const basicEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_1_0,"./modules/b.ts": __vite_glob_1_1,"./modules/index.ts": __vite_glob_1_2
6+
export const basicWithObjectKeys = Object.keys({"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0});
7+
export const basicWithObjectValues = Object.values([() => import("./modules/a.ts"),() => import("./modules/b.ts"),() => import("./modules/index.ts")]);
8+
export const basicEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_3_0,"./modules/b.ts": __vite_glob_3_1,"./modules/index.ts": __vite_glob_3_2
79
810
});
11+
export const basicEagerWithObjectKeys = Object.keys(
12+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
13+
14+
}
15+
);
16+
export const basicEagerWithObjectValues = Object.values(
17+
[__vite_glob_5_0,__vite_glob_5_1,__vite_glob_5_2
18+
19+
]
20+
);
921
export const ignore = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts")});
10-
export const namedEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_3_0,"./modules/b.ts": __vite_glob_3_1,"./modules/index.ts": __vite_glob_3_2
22+
export const ignoreWithObjectKeys = Object.keys(
23+
{"./modules/a.ts": 0,"./modules/b.ts": 0}
24+
);
25+
export const ignoreWithObjectValues = Object.values(
26+
[() => import("./modules/a.ts"),() => import("./modules/b.ts")]
27+
);
28+
export const namedEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_9_0,"./modules/b.ts": __vite_glob_9_1,"./modules/index.ts": __vite_glob_9_2
1129
1230
1331
});
32+
export const namedEagerWithObjectKeys = Object.keys(
33+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
34+
35+
36+
}
37+
);
38+
export const namedEagerWithObjectValues = Object.values(
39+
[__vite_glob_11_0,__vite_glob_11_1,__vite_glob_11_2
40+
41+
42+
]
43+
);
1444
export const namedDefault = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts").then(m => m["default"]),"./modules/b.ts": () => import("./modules/b.ts").then(m => m["default"]),"./modules/index.ts": () => import("./modules/index.ts").then(m => m["default"])
1545
1646
});
17-
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_5_0,"./modules/b.ts": __vite_glob_5_1
47+
export const namedDefaultWithObjectKeys = Object.keys(
48+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
49+
50+
}
51+
);
52+
export const namedDefaultWithObjectValues = Object.values(
53+
[() => import("./modules/a.ts").then(m => m["default"]),() => import("./modules/b.ts").then(m => m["default"]),() => import("./modules/index.ts").then(m => m["default"])
54+
55+
]
56+
);
57+
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_15_0,"./modules/b.ts": __vite_glob_15_1
1858
1959
2060
});
@@ -56,20 +96,60 @@ export const cleverCwd2 = /* #__PURE__ */ Object.assign({"./modules/a.ts": () =>
5696
`;
5797

5898
exports[`fixture > transform with restoreQueryExtension 1`] = `
59-
"import * as __vite_glob_1_0 from "./modules/a.ts";import * as __vite_glob_1_1 from "./modules/b.ts";import * as __vite_glob_1_2 from "./modules/index.ts";import { name as __vite_glob_3_0 } from "./modules/a.ts";import { name as __vite_glob_3_1 } from "./modules/b.ts";import { name as __vite_glob_3_2 } from "./modules/index.ts";import { default as __vite_glob_5_0 } from "./modules/a.ts?raw";import { default as __vite_glob_5_1 } from "./modules/b.ts?raw";import "types/importMeta";
99+
"import * as __vite_glob_3_0 from "./modules/a.ts";import * as __vite_glob_3_1 from "./modules/b.ts";import * as __vite_glob_3_2 from "./modules/index.ts";import * as __vite_glob_5_0 from "./modules/a.ts";import * as __vite_glob_5_1 from "./modules/b.ts";import * as __vite_glob_5_2 from "./modules/index.ts";import { name as __vite_glob_9_0 } from "./modules/a.ts";import { name as __vite_glob_9_1 } from "./modules/b.ts";import { name as __vite_glob_9_2 } from "./modules/index.ts";import { name as __vite_glob_11_0 } from "./modules/a.ts";import { name as __vite_glob_11_1 } from "./modules/b.ts";import { name as __vite_glob_11_2 } from "./modules/index.ts";import { default as __vite_glob_15_0 } from "./modules/a.ts?raw";import { default as __vite_glob_15_1 } from "./modules/b.ts?raw";import "types/importMeta";
60100
export const basic = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts"),"./modules/index.ts": () => import("./modules/index.ts")});
61-
export const basicEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_1_0,"./modules/b.ts": __vite_glob_1_1,"./modules/index.ts": __vite_glob_1_2
101+
export const basicWithObjectKeys = Object.keys({"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0});
102+
export const basicWithObjectValues = Object.values([() => import("./modules/a.ts"),() => import("./modules/b.ts"),() => import("./modules/index.ts")]);
103+
export const basicEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_3_0,"./modules/b.ts": __vite_glob_3_1,"./modules/index.ts": __vite_glob_3_2
62104
63105
});
106+
export const basicEagerWithObjectKeys = Object.keys(
107+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
108+
109+
}
110+
);
111+
export const basicEagerWithObjectValues = Object.values(
112+
[__vite_glob_5_0,__vite_glob_5_1,__vite_glob_5_2
113+
114+
]
115+
);
64116
export const ignore = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts")});
65-
export const namedEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_3_0,"./modules/b.ts": __vite_glob_3_1,"./modules/index.ts": __vite_glob_3_2
117+
export const ignoreWithObjectKeys = Object.keys(
118+
{"./modules/a.ts": 0,"./modules/b.ts": 0}
119+
);
120+
export const ignoreWithObjectValues = Object.values(
121+
[() => import("./modules/a.ts"),() => import("./modules/b.ts")]
122+
);
123+
export const namedEager = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_9_0,"./modules/b.ts": __vite_glob_9_1,"./modules/index.ts": __vite_glob_9_2
66124
67125
68126
});
127+
export const namedEagerWithObjectKeys = Object.keys(
128+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
129+
130+
131+
}
132+
);
133+
export const namedEagerWithObjectValues = Object.values(
134+
[__vite_glob_11_0,__vite_glob_11_1,__vite_glob_11_2
135+
136+
137+
]
138+
);
69139
export const namedDefault = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts").then(m => m["default"]),"./modules/b.ts": () => import("./modules/b.ts").then(m => m["default"]),"./modules/index.ts": () => import("./modules/index.ts").then(m => m["default"])
70140
71141
});
72-
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_5_0,"./modules/b.ts": __vite_glob_5_1
142+
export const namedDefaultWithObjectKeys = Object.keys(
143+
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0
144+
145+
}
146+
);
147+
export const namedDefaultWithObjectValues = Object.values(
148+
[() => import("./modules/a.ts").then(m => m["default"]),() => import("./modules/b.ts").then(m => m["default"]),() => import("./modules/index.ts").then(m => m["default"])
149+
150+
]
151+
);
152+
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_15_0,"./modules/b.ts": __vite_glob_15_1
73153
74154
75155
});

packages/vite/src/node/__tests__/plugins/importGlob/fixture-a/index.ts

+42
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,63 @@ export interface ModuleType {
55
}
66

77
export const basic = import.meta.glob<ModuleType>('./modules/*.ts')
8+
// prettier-ignore
9+
export const basicWithObjectKeys = Object.keys(import.meta.glob<ModuleType>('./modules/*.ts'))
10+
// prettier-ignore
11+
export const basicWithObjectValues = Object.values(import.meta.glob<ModuleType>('./modules/*.ts'))
812

913
export const basicEager = import.meta.glob<ModuleType>('./modules/*.ts', {
1014
eager: true,
1115
})
16+
export const basicEagerWithObjectKeys = Object.keys(
17+
import.meta.glob<ModuleType>('./modules/*.ts', {
18+
eager: true,
19+
}),
20+
)
21+
export const basicEagerWithObjectValues = Object.values(
22+
import.meta.glob<ModuleType>('./modules/*.ts', {
23+
eager: true,
24+
}),
25+
)
1226

1327
export const ignore = import.meta.glob(['./modules/*.ts', '!**/index.ts'])
28+
export const ignoreWithObjectKeys = Object.keys(
29+
import.meta.glob(['./modules/*.ts', '!**/index.ts']),
30+
)
31+
export const ignoreWithObjectValues = Object.values(
32+
import.meta.glob(['./modules/*.ts', '!**/index.ts']),
33+
)
1434

1535
export const namedEager = import.meta.glob<string>('./modules/*.ts', {
1636
eager: true,
1737
import: 'name',
1838
})
39+
export const namedEagerWithObjectKeys = Object.keys(
40+
import.meta.glob<string>('./modules/*.ts', {
41+
eager: true,
42+
import: 'name',
43+
}),
44+
)
45+
export const namedEagerWithObjectValues = Object.values(
46+
import.meta.glob<string>('./modules/*.ts', {
47+
eager: true,
48+
import: 'name',
49+
}),
50+
)
1951

2052
export const namedDefault = import.meta.glob<string>('./modules/*.ts', {
2153
import: 'default',
2254
})
55+
export const namedDefaultWithObjectKeys = Object.keys(
56+
import.meta.glob<string>('./modules/*.ts', {
57+
import: 'default',
58+
}),
59+
)
60+
export const namedDefaultWithObjectValues = Object.values(
61+
import.meta.glob<string>('./modules/*.ts', {
62+
import: 'default',
63+
}),
64+
)
2365

2466
export const eagerAs = import.meta.glob<ModuleType>(
2567
['./modules/*.ts', '!**/index.ts'],

packages/vite/src/node/plugins/importMetaGlob.ts

+45-6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export interface ParsedImportGlob {
3232
options: ParsedGeneralImportGlobOptions
3333
start: number
3434
end: number
35+
onlyKeys: boolean
36+
onlyValues: boolean
3537
}
3638

3739
interface ParsedGeneralImportGlobOptions extends GeneralImportGlobOptions {
@@ -107,6 +109,8 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
107109
}
108110

109111
const importGlobRE = /\bimport\.meta\.glob(?:<\w+>)?\s*\(/g
112+
const objectKeysRE = /\bObject\.keys\(\s*$/
113+
const objectValuesRE = /\bObject\.values\(\s*$/
110114

111115
const knownOptions = {
112116
as: ['string'],
@@ -306,6 +310,12 @@ export async function parseImportGlob(
306310
globs.map((glob) => toAbsoluteGlob(glob, root, importer, resolveId)),
307311
)
308312
const isRelative = globs.every((i) => '.!'.includes(i[0]))
313+
const sliceCode = cleanCode.slice(0, start)
314+
const onlyKeys = objectKeysRE.test(sliceCode)
315+
let onlyValues = false
316+
if (!onlyKeys) {
317+
onlyValues = objectValuesRE.test(sliceCode)
318+
}
309319

310320
return {
311321
index,
@@ -315,6 +325,8 @@ export async function parseImportGlob(
315325
options,
316326
start,
317327
end,
328+
onlyKeys,
329+
onlyValues,
318330
}
319331
})
320332

@@ -390,7 +402,16 @@ export async function transformGlobImport(
390402
const staticImports = (
391403
await Promise.all(
392404
matches.map(
393-
async ({ globsResolved, isRelative, options, index, start, end }) => {
405+
async ({
406+
globsResolved,
407+
isRelative,
408+
options,
409+
index,
410+
start,
411+
end,
412+
onlyKeys,
413+
onlyValues,
414+
}) => {
394415
const cwd = getCommonBase(globsResolved) ?? root
395416
const files = (
396417
await glob(globsResolved, {
@@ -437,6 +458,11 @@ export async function transformGlobImport(
437458
let importPath = paths.importPath
438459
let importQuery = options.query ?? ''
439460

461+
if (onlyKeys) {
462+
objectProps.push(`${JSON.stringify(filePath)}: 0`)
463+
return
464+
}
465+
440466
if (importQuery && importQuery !== '?raw') {
441467
const fileExtension = basename(file).split('.').slice(-1)[0]
442468
if (fileExtension && restoreQueryExtension)
@@ -458,13 +484,19 @@ export async function transformGlobImport(
458484
staticImports.push(
459485
`import ${expression} from ${JSON.stringify(importPath)}`,
460486
)
461-
objectProps.push(`${JSON.stringify(filePath)}: ${variableName}`)
487+
objectProps.push(
488+
onlyValues
489+
? `${variableName}`
490+
: `${JSON.stringify(filePath)}: ${variableName}`,
491+
)
462492
} else {
463493
let importStatement = `import(${JSON.stringify(importPath)})`
464494
if (importKey)
465495
importStatement += `.then(m => m[${JSON.stringify(importKey)}])`
466496
objectProps.push(
467-
`${JSON.stringify(filePath)}: () => ${importStatement}`,
497+
onlyValues
498+
? `() => ${importStatement}`
499+
: `${JSON.stringify(filePath)}: () => ${importStatement}`,
468500
)
469501
}
470502
})
@@ -477,10 +509,17 @@ export async function transformGlobImport(
477509
originalLineBreakCount > 0
478510
? '\n'.repeat(originalLineBreakCount)
479511
: ''
512+
let replacement = ''
513+
if (onlyKeys) {
514+
replacement = `{${objectProps.join(',')}${lineBreaks}}`
515+
} else if (onlyValues) {
516+
replacement = `[${objectProps.join(',')}${lineBreaks}]`
517+
} else {
518+
replacement = `/* #__PURE__ */ Object.assign({${objectProps.join(
519+
',',
520+
)}${lineBreaks}})`
521+
}
480522

481-
const replacement = `/* #__PURE__ */ Object.assign({${objectProps.join(
482-
',',
483-
)}${lineBreaks}})`
484523
s.overwrite(start, end, replacement)
485524

486525
return staticImports

0 commit comments

Comments
 (0)