diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 2ccb4fef4f89d5..a1d88a46e90d8c 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -125,6 +125,14 @@ export interface DepOptimizationConfig { * @experimental */ disabled?: boolean | 'build' | 'dev' + /** + * Automatic dependency discovery. When `noDiscovery` is true, only dependencies + * listed in `include` will be optimized. The scanner isn't run for cold start + * in this case. CJS-only dependencies must be present in `include` during dev. + * @default false + * @experimental + */ + noDiscovery?: boolean } export type DepOptimizationOptions = DepOptimizationConfig & { diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts index f82dbe0f3bcf85..1ba95b5ffca274 100644 --- a/packages/vite/src/node/optimizer/optimizer.ts +++ b/packages/vite/src/node/optimizer/optimizer.ts @@ -217,7 +217,11 @@ async function createDepsOptimizer( newDepsDiscovered = true } - if (!isBuild) { + if (config.optimizeDeps.noDiscovery) { + // We don't need to scan for dependencies or wait for the static crawl to end + // Run the first optimization run immediately + runOptimizer() + } else if (!isBuild) { // Important, the scanner is dev only depsOptimizer.scanProcessing = new Promise((resolve) => { // Runs in the background in case blocking high priority tasks diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts index 7aa33ef2fdc7c2..1ba06fac265ffb 100644 --- a/packages/vite/src/node/plugins/preAlias.ts +++ b/packages/vite/src/node/plugins/preAlias.ts @@ -49,7 +49,9 @@ export function preAliasPlugin(config: ResolvedConfig): Plugin { if (optimizedId) { return optimizedId // aliased dep already optimized } - + if (depsOptimizer.options.noDiscovery) { + return + } const resolved = await this.resolve(id, importer, { ...options, custom: { ...options.custom, 'vite:pre-alias': true }, diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 0d5f4100877dbe..8966d4ac6aa043 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -816,6 +816,7 @@ export function tryNodeResolve( } const skipOptimization = + depsOptimizer?.options.noDiscovery || !isJsType || (importer && isInNodeModules(importer)) || exclude?.includes(pkgId) || diff --git a/playground/optimize-deps-no-discovery/__tests__/optimize-deps.spec.ts b/playground/optimize-deps-no-discovery/__tests__/optimize-deps.spec.ts new file mode 100644 index 00000000000000..12bf4e5b57efaa --- /dev/null +++ b/playground/optimize-deps-no-discovery/__tests__/optimize-deps.spec.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' +import { isBuild, page, readFile } from '~utils' + +test('optimized dep', async () => { + expect(await page.textContent('.optimized-dep')).toBe('[success]') +}) + +test('vue + vuex', async () => { + expect(await page.textContent('.vue')).toMatch(`[success]`) +}) + +test.runIf(!isBuild)('metadata', async () => { + const meta = await readFile('node_modules/.vite/deps/_metadata.json') + expect(meta).toMatch(`"@vitejs/test-dep-no-discovery"`) + expect(meta).not.toMatch(`"vue"`) + expect(meta).not.toMatch(`"vuex"`) +}) diff --git a/playground/optimize-deps-no-discovery/dep-no-discovery/index.js b/playground/optimize-deps-no-discovery/dep-no-discovery/index.js new file mode 100644 index 00000000000000..8096b3eca30104 --- /dev/null +++ b/playground/optimize-deps-no-discovery/dep-no-discovery/index.js @@ -0,0 +1,2 @@ +// written in cjs, optimization should convert this to esm +module.exports = '[success]' diff --git a/playground/optimize-deps-no-discovery/dep-no-discovery/package.json b/playground/optimize-deps-no-discovery/dep-no-discovery/package.json new file mode 100644 index 00000000000000..00c68ab6f39275 --- /dev/null +++ b/playground/optimize-deps-no-discovery/dep-no-discovery/package.json @@ -0,0 +1,6 @@ +{ + "name": "@vitejs/test-dep-no-discovery", + "private": true, + "version": "1.0.0", + "main": "index.js" +} diff --git a/playground/optimize-deps-no-discovery/index.html b/playground/optimize-deps-no-discovery/index.html new file mode 100644 index 00000000000000..1d0ccb72106bcb --- /dev/null +++ b/playground/optimize-deps-no-discovery/index.html @@ -0,0 +1,24 @@ +