diff --git a/docs/config/build-options.md b/docs/config/build-options.md index 3713daf534b349..ee89fb8273704d 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -41,12 +41,13 @@ type ResolveModulePreloadDependenciesFn = ( url: string, deps: string[], context: { - importer: string + hostId: string + hostType: 'html' | 'js' }, ) => string[] ``` -The `resolveDependencies` function will be called for each dynamic import with a list of the chunks it depends on, and it will also be called for each chunk imported in entry HTML files. A new dependencies array can be returned with these filtered or more dependencies injected, and their paths modified. The `deps` paths are relative to the `build.outDir`. Returning a relative path to the `hostId` for `hostType === 'js'` is allowed, in which case `new URL(dep, import.meta.url)` is used to get an absolute path when injecting this module preload in the HTML head. +The `resolveDependencies` function will be called for each dynamic import with a list of the chunks it depends on, and it will also be called for each chunk imported in entry HTML files. A new dependencies array can be returned with these filtered or more dependencies injected, and their paths modified. The `deps` paths are relative to the `build.outDir`. The return value should be a relative path to the `build.outDir`. ```js twoslash /** @type {import('vite').UserConfig} */ diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index 22a0d61ef3aae3..602466749b4cce 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -160,15 +160,9 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { const isWorker = config.isWorker const insertPreload = !(ssr || !!config.build.lib || isWorker) - const resolveModulePreloadDependencies = - config.build.modulePreload && config.build.modulePreload.resolveDependencies const renderBuiltUrl = config.experimental.renderBuiltUrl - const customModulePreloadPaths = !!( - resolveModulePreloadDependencies || renderBuiltUrl - ) const isRelativeBase = config.base === './' || config.base === '' - const optimizeModulePreloadRelativePaths = - isRelativeBase && !customModulePreloadPaths + const optimizeModulePreloadRelativePaths = isRelativeBase && !renderBuiltUrl const { modulePreload } = config.build const scriptRel = @@ -183,10 +177,10 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { // This is maintained to keep backwards compatibility as some users developed plugins // using regex over this list to workaround the fact that module preload wasn't // configurable. - const assetsURL = customModulePreloadPaths - ? // If `experimental.renderBuiltUrl` or `build.modulePreload.resolveDependencies` are used - // the dependencies are already resolved. To avoid the need for `new URL(dep, import.meta.url)` - // a helper `__vitePreloadRelativeDep` is used to resolve from relative paths which can be minimized. + const assetsURL = renderBuiltUrl + ? // If `experimental.renderBuiltUrl` is used, the dependencies are already resolved. + // To avoid the need for `new URL(dep, import.meta.url)`, a helper `__vitePreloadRelativeDep` is + // used to resolve from relative paths which can be minimized. `function(dep, importerUrl) { return dep[0] === '.' ? new URL(dep, importerUrl).href : dep }` : optimizeModulePreloadRelativePaths ? // If there isn't custom resolvers affecting the deps list, deps in the list are relative @@ -269,7 +263,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { str().appendRight( expEnd, `,${isModernFlag}?${preloadMarker}:void 0${ - optimizeModulePreloadRelativePaths || customModulePreloadPaths + optimizeModulePreloadRelativePaths || renderBuiltUrl ? ',import.meta.url' : '' })`, @@ -437,7 +431,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { if (markerStartPos > 0) { // the dep list includes the main chunk, so only need to reload when there are actual other deps. - const depsArray = + let depsArray = deps.size > 1 || // main chunk is removed (hasRemovedPureCssChunk && deps.size > 0) @@ -448,33 +442,29 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { : [...deps] : [] - let renderedDeps: number[] - if (normalizedFile && customModulePreloadPaths) { - const { modulePreload } = config.build - const resolveDependencies = modulePreload - ? modulePreload.resolveDependencies - : undefined - let resolvedDeps: string[] - if (resolveDependencies) { - // We can't let the user remove css deps as these aren't really preloads, they are just using - // the same mechanism as module preloads for this chunk - const cssDeps: string[] = [] - const otherDeps: string[] = [] - for (const dep of depsArray) { - ;(dep.endsWith('.css') ? cssDeps : otherDeps).push(dep) - } - resolvedDeps = [ - ...resolveDependencies(normalizedFile, otherDeps, { - hostId: file, - hostType: 'js', - }), - ...cssDeps, - ] - } else { - resolvedDeps = depsArray + const resolveDependencies = modulePreload + ? modulePreload.resolveDependencies + : undefined + if (resolveDependencies && normalizedFile) { + // We can't let the user remove css deps as these aren't really preloads, they are just using + // the same mechanism as module preloads for this chunk + const cssDeps: string[] = [] + const otherDeps: string[] = [] + for (const dep of depsArray) { + ;(dep.endsWith('.css') ? cssDeps : otherDeps).push(dep) } + depsArray = [ + ...resolveDependencies(normalizedFile, otherDeps, { + hostId: file, + hostType: 'js', + }), + ...cssDeps, + ] + } - renderedDeps = resolvedDeps.map((dep) => { + let renderedDeps: number[] + if (renderBuiltUrl) { + renderedDeps = depsArray.map((dep) => { const replacement = toOutputFilePathInJS( dep, 'asset',