From 91c8eaea7be170a0d145d89f00ef20ac5acdb4c0 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Thu, 29 Aug 2024 12:01:10 +0200 Subject: [PATCH] fix: createResolver compat --- .../src/node/__tests__/environment.spec.ts | 4 +- packages/vite/src/node/config.ts | 90 ++++--------------- packages/vite/src/node/idResolver.ts | 22 ++++- .../src/node/optimizer/esbuildDepPlugin.ts | 19 ++-- packages/vite/src/node/optimizer/resolve.ts | 4 +- .../src/node/plugins/assetImportMetaUrl.ts | 4 +- packages/vite/src/node/plugins/css.ts | 10 +-- .../src/node/plugins/dynamicImportVars.ts | 4 +- .../src/node/plugins/workerImportMetaUrl.ts | 4 +- 9 files changed, 63 insertions(+), 98 deletions(-) diff --git a/packages/vite/src/node/__tests__/environment.spec.ts b/packages/vite/src/node/__tests__/environment.spec.ts index 5009f5b0ae7340..cae672513be806 100644 --- a/packages/vite/src/node/__tests__/environment.spec.ts +++ b/packages/vite/src/node/__tests__/environment.spec.ts @@ -4,7 +4,7 @@ import { expect, test } from 'vitest' import { createServer } from '../server' import { createServerModuleRunner } from '../ssr/runtime/serverModuleRunner' import type { ResolveIdFn } from '../idResolver' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' import { normalizePath } from '../utils' const root = fileURLToPath(new URL('./', import.meta.url)) @@ -20,7 +20,7 @@ async function createDevServer() { return { name: 'environment-alias-test-plugin', configResolved(config) { - idResolver = createIdResolver(config, {}) + idResolver = createBackCompatIdResolver(config) }, async resolveId(id) { return await idResolver(this.environment, id) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 591a8c6e3f480f..7580290df5764c 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -7,9 +7,8 @@ import { performance } from 'node:perf_hooks' import { createRequire } from 'node:module' import colors from 'picocolors' import type { Alias, AliasOptions } from 'dep-types/alias' -import aliasPlugin from '@rollup/plugin-alias' import { build } from 'esbuild' -import type { PartialResolvedId, RollupOptions } from 'rollup' +import type { RollupOptions } from 'rollup' import picomatch from 'picomatch' import type { AnymatchFn } from '../types/anymatch' import { withTrailingSlash } from '../shared/utils' @@ -67,7 +66,6 @@ import { normalizeAlias, normalizePath, } from './utils' -import { getFsUtils } from './fsUtils' import { createPluginHookUtils, getHookHandler, @@ -76,19 +74,18 @@ import { } from './plugins' import type { ESBuildOptions } from './plugins/esbuild' import type { InternalResolveOptions, ResolveOptions } from './plugins/resolve' -import { resolvePlugin, tryNodeResolve } from './plugins/resolve' +import { tryNodeResolve } from './plugins/resolve' import type { LogLevel, Logger } from './logger' import { createLogger } from './logger' import type { DepOptimizationOptions } from './optimizer' import type { JsonOptions } from './plugins/json' -import type { EnvironmentPluginContainer } from './server/pluginContainer' -import { createEnvironmentPluginContainer } from './server/pluginContainer' import type { PackageCache } from './packages' import { findNearestPackageData } from './packages' import { loadEnv, resolveEnvPrefix } from './env' import type { ResolvedSSROptions, SSROptions } from './ssr' import { resolveSSROptions } from './ssr' -import { FutureCompatEnvironment } from './baseEnvironment' +import { PartialEnvironment } from './baseEnvironment' +import { createIdResolver } from './idResolver' import type { FutureDeprecationWarningsOptions } from './deprecations' const debug = createDebugger('vite:config') @@ -1256,75 +1253,20 @@ export async function resolveConfig( * optimizer & handling css @imports */ createResolver(options) { - const alias: { - client?: EnvironmentPluginContainer - ssr?: EnvironmentPluginContainer - } = {} - const resolver: { - client?: EnvironmentPluginContainer - ssr?: EnvironmentPluginContainer - } = {} - const environments = this.environments ?? resolvedEnvironments - const createPluginContainer = async ( - environmentName: string, - plugins: Plugin[], - ) => { - // The used alias and resolve plugins only use configuration options from the - // environment so we can safely just use the FutureCompatEnvironment here - const environment = new FutureCompatEnvironment(environmentName, this) - const pluginContainer = await createEnvironmentPluginContainer( - environment, - plugins, - ) - await pluginContainer.buildStart({}) - return pluginContainer - } - async function resolve( - id: string, - importer?: string, - aliasOnly?: boolean, - ssr?: boolean, - ): Promise { - const environmentName = ssr ? 'ssr' : 'client' - let container: EnvironmentPluginContainer - if (aliasOnly) { - let aliasContainer = alias[environmentName] - if (!aliasContainer) { - aliasContainer = alias[environmentName] = - await createPluginContainer(environmentName, [ - aliasPlugin({ entries: resolved.resolve.alias }), - ]) - } - container = aliasContainer - } else { - let resolverContainer = resolver[environmentName] - if (!resolverContainer) { - resolverContainer = resolver[environmentName] = - await createPluginContainer(environmentName, [ - aliasPlugin({ entries: resolved.resolve.alias }), - resolvePlugin( - { - ...resolved.resolve, - root: resolvedRoot, - isProduction, - isBuild: command === 'build', - asSrc: true, - preferRelative: false, - tryIndex: true, - ...options, - idOnly: true, - fsUtils: getFsUtils(resolved), - }, - environments, - ), - ]) - } - container = resolverContainer + const resolve = createIdResolver(this, options) + const clientEnvironment = new PartialEnvironment('client', this) + let ssrEnvironment: PartialEnvironment | undefined + return async (id, importer, aliasOnly, ssr) => { + if (ssr) { + ssrEnvironment ??= new PartialEnvironment('ssr', this) } - return await container.resolveId(id, importer, { scan: options?.scan }) + return await resolve( + ssr ? ssrEnvironment! : clientEnvironment, + id, + importer, + aliasOnly, + ) } - return async (id, importer, aliasOnly, ssr) => - (await resolve(id, importer, aliasOnly, ssr))?.id }, fsDenyGlob: picomatch( // matchBase: true does not work as it's documented diff --git a/packages/vite/src/node/idResolver.ts b/packages/vite/src/node/idResolver.ts index 8576da9c5f37b1..5923e985a844cc 100644 --- a/packages/vite/src/node/idResolver.ts +++ b/packages/vite/src/node/idResolver.ts @@ -16,13 +16,33 @@ export type ResolveIdFn = ( aliasOnly?: boolean, ) => Promise +/** + * Some projects like Astro were overriding config.createResolver to add a custom + * alias plugin. For the client and ssr environments, we root through it to avoid + * breaking changes for now. + */ +export function createBackCompatIdResolver( + config: ResolvedConfig, + options?: Partial, +): ResolveIdFn { + const compatResolve = config.createResolver(options) + let resolve: ResolveIdFn + return async (environment, id, importer, aliasOnly) => { + if (environment.name === 'client' || environment.name === 'ssr') { + return compatResolve(id, importer, aliasOnly, environment.name === 'ssr') + } + resolve ??= createIdResolver(config, options) + return resolve(environment, id, importer, aliasOnly) + } +} + /** * Create an internal resolver to be used in special scenarios, e.g. * optimizer and handling css @imports */ export function createIdResolver( config: ResolvedConfig, - options: Partial, + options?: Partial, ): ResolveIdFn { const scan = options?.scan diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts index 10303795fa108f..4fc5a1d53b1560 100644 --- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts +++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts @@ -13,7 +13,7 @@ import { import { browserExternalId, optionalPeerDepId } from '../plugins/resolve' import { isCSSRequest, isModuleCSSRequest } from '../plugins/css' import type { Environment } from '../environment' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' const externalWithConversionNamespace = 'vite:dep-pre-bundle:external-conversion' @@ -66,19 +66,22 @@ export function esbuildDepPlugin( const cjsPackageCache: PackageCache = new Map() // default resolver which prefers ESM - const _resolve = createIdResolver(environment.getTopLevelConfig(), { + const _resolve = createBackCompatIdResolver(environment.getTopLevelConfig(), { asSrc: false, scan: true, packageCache: esmPackageCache, }) // cjs resolver that prefers Node - const _resolveRequire = createIdResolver(environment.getTopLevelConfig(), { - asSrc: false, - isRequire: true, - scan: true, - packageCache: cjsPackageCache, - }) + const _resolveRequire = createBackCompatIdResolver( + environment.getTopLevelConfig(), + { + asSrc: false, + isRequire: true, + scan: true, + packageCache: cjsPackageCache, + }, + ) const resolve = ( id: string, diff --git a/packages/vite/src/node/optimizer/resolve.ts b/packages/vite/src/node/optimizer/resolve.ts index 71a0de87325ce5..43cf52cd41467f 100644 --- a/packages/vite/src/node/optimizer/resolve.ts +++ b/packages/vite/src/node/optimizer/resolve.ts @@ -6,13 +6,13 @@ import { escapeRegex, getNpmPackageName } from '../utils' import { resolvePackageData } from '../packages' import { slash } from '../../shared/utils' import type { Environment } from '../environment' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' export function createOptimizeDepsIncludeResolver( environment: Environment, ): (id: string) => Promise { const topLevelConfig = environment.getTopLevelConfig() - const resolve = createIdResolver(topLevelConfig, { + const resolve = createBackCompatIdResolver(topLevelConfig, { asSrc: false, scan: true, ssrOptimizeCheck: environment.config.consumer === 'server', diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index 90fd866674eade..1b2473137c5431 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -6,7 +6,7 @@ import type { ResolvedConfig } from '../config' import { injectQuery, isParentDirectory, transformStableResult } from '../utils' import { CLIENT_ENTRY } from '../constants' import { slash } from '../../shared/utils' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' import { fileToUrl } from './asset' import { preloadHelperId } from './importAnalysisBuild' @@ -107,7 +107,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { file = slash(path.resolve(path.dirname(id), url)) file = tryFsResolve(file, fsResolveOptions) ?? file } else { - assetResolver ??= createIdResolver(config, { + assetResolver ??= createBackCompatIdResolver(config, { extensions: [], mainFields: [], tryIndex: false, diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 6f6369f7dd1cb0..f2566d3681d1e7 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -69,7 +69,7 @@ import { } from '../utils' import type { Logger } from '../logger' import { cleanUrl, slash } from '../../shared/utils' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' import { PartialEnvironment } from '../baseEnvironment' import type { TransformPluginContext } from '../server/pluginContainer' @@ -261,7 +261,7 @@ export function cssPlugin(config: ResolvedConfig): Plugin { const isBuild = config.command === 'build' let moduleCache: Map> - const idResolver = createIdResolver(config, { + const idResolver = createBackCompatIdResolver(config, { preferRelative: true, tryIndex: false, extensions: [], @@ -1065,7 +1065,7 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers { let lessResolve: ResolveIdFn | undefined return { get css() { - return (cssResolve ??= createIdResolver(config, { + return (cssResolve ??= createBackCompatIdResolver(config, { extensions: ['.css'], mainFields: ['style'], conditions: ['style'], @@ -1076,7 +1076,7 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers { get sass() { if (!sassResolve) { - const resolver = createIdResolver(config, { + const resolver = createBackCompatIdResolver(config, { extensions: ['.scss', '.sass', '.css'], mainFields: ['sass', 'style'], conditions: ['sass', 'style'], @@ -1099,7 +1099,7 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers { }, get less() { - return (lessResolve ??= createIdResolver(config, { + return (lessResolve ??= createBackCompatIdResolver(config, { extensions: ['.less', '.css'], mainFields: ['less', 'style'], conditions: ['less', 'style'], diff --git a/packages/vite/src/node/plugins/dynamicImportVars.ts b/packages/vite/src/node/plugins/dynamicImportVars.ts index 6f8eb84d9d8f41..e6dcb756bc035a 100644 --- a/packages/vite/src/node/plugins/dynamicImportVars.ts +++ b/packages/vite/src/node/plugins/dynamicImportVars.ts @@ -7,7 +7,7 @@ import { dynamicImportToGlob } from '@rollup/plugin-dynamic-import-vars' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '../config' import { CLIENT_ENTRY } from '../constants' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' import { createFilter, normalizePath, @@ -164,7 +164,7 @@ export async function transformDynamicImport( } export function dynamicImportVarsPlugin(config: ResolvedConfig): Plugin { - const resolve = createIdResolver(config, { + const resolve = createBackCompatIdResolver(config, { preferRelative: true, tryIndex: false, extensions: [], diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 26e757965093d0..8d8d316a4ec214 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -5,7 +5,7 @@ import { stripLiteral } from 'strip-literal' import type { ResolvedConfig } from '../config' import type { Plugin } from '../plugin' import { evalValue, injectQuery, transformStableResult } from '../utils' -import { createIdResolver } from '../idResolver' +import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' import { cleanUrl, slash } from '../../shared/utils' import type { WorkerType } from './worker' @@ -159,7 +159,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { file = path.resolve(path.dirname(id), url) file = tryFsResolve(file, fsResolveOptions) ?? file } else { - workerResolver ??= createIdResolver(config, { + workerResolver ??= createBackCompatIdResolver(config, { extensions: [], tryIndex: false, preferRelative: true,