Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
54 changes: 54 additions & 0 deletions packages/astro/src/vite-plugin-config-alias/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from 'node:fs';
import path from 'node:path';
import type { CompilerOptions } from 'typescript';
import { normalizePath, type ResolvedConfig, type Plugin as VitePlugin } from 'vite';

import type { AstroSettings } from '../types/astro.js';

type Alias = {
Expand Down Expand Up @@ -65,6 +67,49 @@ const getConfigAlias = (settings: AstroSettings): Alias[] | null => {
return aliases;
};

/** Generate vite.resolve.alias entries from tsconfig paths */
const getViteResolveAlias = (settings: AstroSettings) => {
const { tsConfig, tsConfigPath } = settings;
if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions) return [];

const { baseUrl, paths } = tsConfig.compilerOptions as CompilerOptions;
const effectiveBaseUrl = baseUrl ?? (paths ? '.' : undefined);
if (!effectiveBaseUrl) return [];

const resolvedBaseUrl = path.resolve(path.dirname(tsConfigPath), effectiveBaseUrl);
const aliases: Array<{ find: string | RegExp; replacement: string; customResolver?: any }> = [];

// Build aliases with custom resolver that tries multiple paths
if (paths) {
for (const [aliasPattern, values] of Object.entries(paths)) {
const resolvedValues = values.map((v) => path.resolve(resolvedBaseUrl, v));

const customResolver = (id: string) => {
// Try each path in order
// id is already the wildcard part (e.g., 'extra.css' for '@styles/*')
// resolvedValues still have the * in them, so replace * with id
for (const resolvedValue of resolvedValues) {
const resolved = resolvedValue.replace('*', id);
if (fs.existsSync(resolved)) {
return resolved;
}
}
return null;
};

aliases.push({
find: new RegExp(
`^${aliasPattern.replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '(.+)')}$`,
),
replacement: aliasPattern.includes('*') ? '$1' : aliasPattern,
customResolver,
});
}
}

return aliases;
};

/** Returns a Vite plugin used to alias paths from tsconfig.json and jsconfig.json. */
export default function configAliasVitePlugin({
settings,
Expand All @@ -78,6 +123,14 @@ export default function configAliasVitePlugin({
name: 'astro:tsconfig-alias',
// use post to only resolve ids that all other plugins before it can't
enforce: 'post',
config() {
// Return vite.resolve.alias config with custom resolvers
return {
resolve: {
alias: getViteResolveAlias(settings),
},
};
},
configResolved(config) {
patchCreateResolver(config, plugin);
},
Expand Down Expand Up @@ -107,6 +160,7 @@ export default function configAliasVitePlugin({
return plugin;
}

// TODO this is a deprecated API and should be removed when its safe to do so
/**
* Vite's `createResolver` is used to resolve various things, including CSS `@import`.
* However, there's no way to extend this resolver, besides patching it. This function
Expand Down
126 changes: 0 additions & 126 deletions packages/astro/test/alias-tsconfig-baseurl-only.test.js

This file was deleted.

Loading