Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: reduce bundle size for Object.keys(import.meta.glob(...)) / Object.values(import.meta.glob(...)) #18666

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,60 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`fixture > transform 1`] = `
"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";
"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";
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")});
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
export const basicWithObjectKeys = Object.keys({"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0});
export const basicWithObjectValues = Object.values([() => import("./modules/a.ts"),() => import("./modules/b.ts"),() => import("./modules/index.ts")]);
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

});
export const basicEagerWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0

}
);
export const basicEagerWithObjectValues = Object.values(
[__vite_glob_5_0,__vite_glob_5_1,__vite_glob_5_2

]
);
export const ignore = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts")});
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
export const ignoreWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0}
);
export const ignoreWithObjectValues = Object.values(
[() => import("./modules/a.ts"),() => import("./modules/b.ts")]
);
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


});
export const namedEagerWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0


}
);
export const namedEagerWithObjectValues = Object.values(
[__vite_glob_11_0,__vite_glob_11_1,__vite_glob_11_2


]
);
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"])

});
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_5_0,"./modules/b.ts": __vite_glob_5_1
export const namedDefaultWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0

}
);
export const namedDefaultWithObjectValues = Object.values(
[() => import("./modules/a.ts").then(m => m["default"]),() => import("./modules/b.ts").then(m => m["default"]),() => import("./modules/index.ts").then(m => m["default"])

]
);
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_15_0,"./modules/b.ts": __vite_glob_15_1


});
Expand Down Expand Up @@ -56,20 +96,60 @@ export const cleverCwd2 = /* #__PURE__ */ Object.assign({"./modules/a.ts": () =>
`;

exports[`fixture > transform with restoreQueryExtension 1`] = `
"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";
"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";
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")});
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
export const basicWithObjectKeys = Object.keys({"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0});
export const basicWithObjectValues = Object.values([() => import("./modules/a.ts"),() => import("./modules/b.ts"),() => import("./modules/index.ts")]);
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

});
export const basicEagerWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0

}
);
export const basicEagerWithObjectValues = Object.values(
[__vite_glob_5_0,__vite_glob_5_1,__vite_glob_5_2

]
);
export const ignore = /* #__PURE__ */ Object.assign({"./modules/a.ts": () => import("./modules/a.ts"),"./modules/b.ts": () => import("./modules/b.ts")});
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
export const ignoreWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0}
);
export const ignoreWithObjectValues = Object.values(
[() => import("./modules/a.ts"),() => import("./modules/b.ts")]
);
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


});
export const namedEagerWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0


}
);
export const namedEagerWithObjectValues = Object.values(
[__vite_glob_11_0,__vite_glob_11_1,__vite_glob_11_2


]
);
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"])

});
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_5_0,"./modules/b.ts": __vite_glob_5_1
export const namedDefaultWithObjectKeys = Object.keys(
{"./modules/a.ts": 0,"./modules/b.ts": 0,"./modules/index.ts": 0

}
);
export const namedDefaultWithObjectValues = Object.values(
[() => import("./modules/a.ts").then(m => m["default"]),() => import("./modules/b.ts").then(m => m["default"]),() => import("./modules/index.ts").then(m => m["default"])

]
);
export const eagerAs = /* #__PURE__ */ Object.assign({"./modules/a.ts": __vite_glob_15_0,"./modules/b.ts": __vite_glob_15_1


});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,63 @@ export interface ModuleType {
}

export const basic = import.meta.glob<ModuleType>('./modules/*.ts')
// prettier-ignore
export const basicWithObjectKeys = Object.keys(import.meta.glob<ModuleType>('./modules/*.ts'))
// prettier-ignore
export const basicWithObjectValues = Object.values(import.meta.glob<ModuleType>('./modules/*.ts'))

export const basicEager = import.meta.glob<ModuleType>('./modules/*.ts', {
eager: true,
})
export const basicEagerWithObjectKeys = Object.keys(
import.meta.glob<ModuleType>('./modules/*.ts', {
eager: true,
}),
)
export const basicEagerWithObjectValues = Object.values(
import.meta.glob<ModuleType>('./modules/*.ts', {
eager: true,
}),
)

export const ignore = import.meta.glob(['./modules/*.ts', '!**/index.ts'])
export const ignoreWithObjectKeys = Object.keys(
import.meta.glob(['./modules/*.ts', '!**/index.ts']),
)
export const ignoreWithObjectValues = Object.values(
import.meta.glob(['./modules/*.ts', '!**/index.ts']),
)

export const namedEager = import.meta.glob<string>('./modules/*.ts', {
eager: true,
import: 'name',
})
export const namedEagerWithObjectKeys = Object.keys(
import.meta.glob<string>('./modules/*.ts', {
eager: true,
import: 'name',
}),
)
export const namedEagerWithObjectValues = Object.values(
import.meta.glob<string>('./modules/*.ts', {
eager: true,
import: 'name',
}),
)

export const namedDefault = import.meta.glob<string>('./modules/*.ts', {
import: 'default',
})
export const namedDefaultWithObjectKeys = Object.keys(
import.meta.glob<string>('./modules/*.ts', {
import: 'default',
}),
)
export const namedDefaultWithObjectValues = Object.values(
import.meta.glob<string>('./modules/*.ts', {
import: 'default',
}),
)

export const eagerAs = import.meta.glob<ModuleType>(
['./modules/*.ts', '!**/index.ts'],
Expand Down
51 changes: 45 additions & 6 deletions packages/vite/src/node/plugins/importMetaGlob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export interface ParsedImportGlob {
options: ParsedGeneralImportGlobOptions
start: number
end: number
onlyKeys: boolean
onlyValues: boolean
}

interface ParsedGeneralImportGlobOptions extends GeneralImportGlobOptions {
Expand Down Expand Up @@ -107,6 +109,8 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
}

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

const knownOptions = {
as: ['string'],
Expand Down Expand Up @@ -306,6 +310,12 @@ export async function parseImportGlob(
globs.map((glob) => toAbsoluteGlob(glob, root, importer, resolveId)),
)
const isRelative = globs.every((i) => '.!'.includes(i[0]))
const sliceCode = cleanCode.slice(0, start)
const onlyKeys = objectKeysRE.test(sliceCode)
let onlyValues = false
if (!onlyKeys) {
onlyValues = objectValuesRE.test(sliceCode)
}

return {
index,
Expand All @@ -315,6 +325,8 @@ export async function parseImportGlob(
options,
start,
end,
onlyKeys,
onlyValues,
}
})

Expand Down Expand Up @@ -390,7 +402,16 @@ export async function transformGlobImport(
const staticImports = (
await Promise.all(
matches.map(
async ({ globsResolved, isRelative, options, index, start, end }) => {
async ({
globsResolved,
isRelative,
options,
index,
start,
end,
onlyKeys,
onlyValues,
}) => {
const cwd = getCommonBase(globsResolved) ?? root
const files = (
await glob(globsResolved, {
Expand Down Expand Up @@ -437,6 +458,11 @@ export async function transformGlobImport(
let importPath = paths.importPath
let importQuery = options.query ?? ''

if (onlyKeys) {
objectProps.push(`${JSON.stringify(filePath)}: 0`)
return
}

btea marked this conversation as resolved.
Show resolved Hide resolved
if (importQuery && importQuery !== '?raw') {
const fileExtension = basename(file).split('.').slice(-1)[0]
if (fileExtension && restoreQueryExtension)
Expand All @@ -458,13 +484,19 @@ export async function transformGlobImport(
staticImports.push(
`import ${expression} from ${JSON.stringify(importPath)}`,
)
objectProps.push(`${JSON.stringify(filePath)}: ${variableName}`)
objectProps.push(
onlyValues
? `${variableName}`
: `${JSON.stringify(filePath)}: ${variableName}`,
)
} else {
let importStatement = `import(${JSON.stringify(importPath)})`
if (importKey)
importStatement += `.then(m => m[${JSON.stringify(importKey)}])`
objectProps.push(
`${JSON.stringify(filePath)}: () => ${importStatement}`,
onlyValues
? `() => ${importStatement}`
: `${JSON.stringify(filePath)}: () => ${importStatement}`,
)
}
})
Expand All @@ -477,10 +509,17 @@ export async function transformGlobImport(
originalLineBreakCount > 0
? '\n'.repeat(originalLineBreakCount)
: ''
let replacement = ''
if (onlyKeys) {
replacement = `{${objectProps.join(',')}${lineBreaks}}`
} else if (onlyValues) {
replacement = `[${objectProps.join(',')}${lineBreaks}]`
} else {
replacement = `/* #__PURE__ */ Object.assign({${objectProps.join(
',',
)}${lineBreaks}})`
}

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

return staticImports
Expand Down