From b672f773bd539637e2ef52342ed4e9c3166eabcb Mon Sep 17 00:00:00 2001 From: bluwy Date: Fri, 13 Jan 2023 17:49:28 +0800 Subject: [PATCH] Safer alias --- .../core/build/vite-plugin-alias-resolve.ts | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/packages/astro/src/core/build/vite-plugin-alias-resolve.ts b/packages/astro/src/core/build/vite-plugin-alias-resolve.ts index 53fc08491b87..ac37e66cd6fb 100644 --- a/packages/astro/src/core/build/vite-plugin-alias-resolve.ts +++ b/packages/astro/src/core/build/vite-plugin-alias-resolve.ts @@ -1,32 +1,50 @@ -import type { Plugin as VitePlugin } from 'vite'; +import type { Alias, Plugin as VitePlugin } from 'vite'; import type { BuildInternals } from '../../core/build/internal.js'; /** - * `@rollup/plugin-alias` doesn't resolve aliases in Rollup input by default. This plugin fixes it. + * `@rollup/plugin-alias` doesn't resolve aliases in Rollup input by default. This plugin fixes it + * with a partial fork of it's resolve function. https://github.com/rollup/plugins/blob/master/packages/alias/src/index.ts * When https://github.com/rollup/plugins/pull/1402 is merged, we can remove this plugin. */ export function vitePluginAliasResolve(internals: BuildInternals): VitePlugin { - let inputResolve: (id: string) => Promise; + let aliases: Alias[]; return { name: '@astro/plugin-alias-resolve', enforce: 'pre', configResolved(config) { - const viteResolve = config.createResolver(); - inputResolve = async (id) => { - const resolved = await viteResolve(id, ' ', true); - return resolved || id; - }; + aliases = config.resolve.alias; }, - async resolveId(id, importer) { + async resolveId(id, importer, opts) { if ( !importer && (internals.discoveredHydratedComponents.has(id) || internals.discoveredClientOnlyComponents.has(id)) ) { - const resolved = await inputResolve(id); - return await this.resolve(resolved, importer, { skipSelf: true }); + const matchedEntry = aliases.find((entry) => matches(entry.find, id)); + if (!matchedEntry) { + return null; + } + + const updatedId = id.replace(matchedEntry.find, matchedEntry.replacement); + + return this.resolve(updatedId, importer, Object.assign({ skipSelf: true }, opts)).then( + (resolved) => resolved || { id: updatedId } + ); } }, }; } + +function matches(pattern: string | RegExp, importee: string) { + if (pattern instanceof RegExp) { + return pattern.test(importee); + } + if (importee.length < pattern.length) { + return false; + } + if (importee === pattern) { + return true; + } + return importee.startsWith(pattern + '/'); +}