Revert tsconfig-alias
plugin changes (#6633)
* Revert "Fix tsconfig alias regression (#6617)" This reverts commit38e6ec21e2
. * chore: changeset * fix: add back fs * chore: remove stray console log * Revert "Support tsconfig aliases in styles (#6566)" This reverts commitea9b3dd72b
. * chore: add note on css style aliases
This commit is contained in:
parent
58c612b746
commit
9caf2a9ccc
10 changed files with 96 additions and 101 deletions
5
.changeset/sharp-timers-lick.md
Normal file
5
.changeset/sharp-timers-lick.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix failed `astro sync` call when running `astro check`. This change also reverts alias support in CSS styles.
|
|
@ -1,19 +1,47 @@
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type { AstroSettings } from '../@types/astro';
|
import type { AstroSettings } from '../@types/astro';
|
||||||
|
|
||||||
import slash from 'slash';
|
import type * as vite from 'vite';
|
||||||
import type { TsConfigJson } from 'tsconfig-resolver';
|
|
||||||
import type { Alias, Plugin as VitePlugin } from 'vite';
|
/** Result of successfully parsed tsconfig.json or jsconfig.json. */
|
||||||
|
export declare interface Alias {
|
||||||
|
find: RegExp;
|
||||||
|
replacement: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a path with its slashes replaced with posix slashes. */
|
||||||
|
const normalize = (pathname: string) => String(pathname).split(path.sep).join(path.posix.sep);
|
||||||
|
|
||||||
/** Returns a list of compiled aliases. */
|
/** Returns a list of compiled aliases. */
|
||||||
const getConfigAlias = (
|
const getConfigAlias = (settings: AstroSettings): Alias[] | null => {
|
||||||
paths: NonNullable<TsConfigJson.CompilerOptions['paths']>,
|
/** Closest tsconfig.json or jsconfig.json */
|
||||||
baseUrl: NonNullable<TsConfigJson.CompilerOptions['baseUrl']>
|
const config = settings.tsConfig;
|
||||||
): Alias[] => {
|
const configPath = settings.tsConfigPath;
|
||||||
|
|
||||||
|
// if no config was found, return null
|
||||||
|
if (!config || !configPath) return null;
|
||||||
|
|
||||||
|
/** Compiler options from tsconfig.json or jsconfig.json. */
|
||||||
|
const compilerOptions = Object(config.compilerOptions);
|
||||||
|
|
||||||
|
// if no compilerOptions.baseUrl was defined, return null
|
||||||
|
if (!compilerOptions.baseUrl) return null;
|
||||||
|
|
||||||
|
// resolve the base url from the configuration file directory
|
||||||
|
const baseUrl = path.posix.resolve(
|
||||||
|
path.posix.dirname(normalize(configPath).replace(/^\/?/, '/')),
|
||||||
|
normalize(compilerOptions.baseUrl)
|
||||||
|
);
|
||||||
|
|
||||||
|
/** List of compiled alias expressions. */
|
||||||
const aliases: Alias[] = [];
|
const aliases: Alias[] = [];
|
||||||
|
|
||||||
// compile any alias expressions and push them to the list
|
// compile any alias expressions and push them to the list
|
||||||
for (const [alias, values] of Object.entries(paths)) {
|
for (let [alias, values] of Object.entries(
|
||||||
|
Object(compilerOptions.paths) as { [key: string]: string[] }
|
||||||
|
)) {
|
||||||
|
values = [].concat(values as never);
|
||||||
|
|
||||||
/** Regular Expression used to match a given path. */
|
/** Regular Expression used to match a given path. */
|
||||||
const find = new RegExp(
|
const find = new RegExp(
|
||||||
`^${[...alias]
|
`^${[...alias]
|
||||||
|
@ -26,7 +54,7 @@ const getConfigAlias = (
|
||||||
/** Internal index used to calculate the matching id in a replacement. */
|
/** Internal index used to calculate the matching id in a replacement. */
|
||||||
let matchId = 0;
|
let matchId = 0;
|
||||||
|
|
||||||
for (const value of values) {
|
for (let value of values) {
|
||||||
/** String used to replace a matched path. */
|
/** String used to replace a matched path. */
|
||||||
const replacement = [...path.posix.resolve(baseUrl, value)]
|
const replacement = [...path.posix.resolve(baseUrl, value)]
|
||||||
.map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment))
|
.map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment))
|
||||||
|
@ -36,6 +64,14 @@ const getConfigAlias = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compile the baseUrl expression and push it to the list
|
||||||
|
// - `baseUrl` changes the way non-relative specifiers are resolved
|
||||||
|
// - if `baseUrl` exists then all non-relative specifiers are resolved relative to it
|
||||||
|
aliases.push({
|
||||||
|
find: /^(?!\.*\/)(.+)$/,
|
||||||
|
replacement: `${[...baseUrl].map((segment) => (segment === '$' ? '$$' : segment)).join('')}/$1`,
|
||||||
|
});
|
||||||
|
|
||||||
return aliases;
|
return aliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,45 +80,40 @@ export default function configAliasVitePlugin({
|
||||||
settings,
|
settings,
|
||||||
}: {
|
}: {
|
||||||
settings: AstroSettings;
|
settings: AstroSettings;
|
||||||
}): VitePlugin | null {
|
}): vite.PluginOption {
|
||||||
const { tsConfig, tsConfigPath } = settings;
|
const { config } = settings;
|
||||||
if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions) return null;
|
/** Aliases from the tsconfig.json or jsconfig.json configuration. */
|
||||||
|
const configAlias = getConfigAlias(settings);
|
||||||
|
|
||||||
const { baseUrl, paths } = tsConfig.compilerOptions;
|
// if no config alias was found, bypass this plugin
|
||||||
if (!baseUrl || !paths) return null;
|
if (!configAlias) return {} as vite.PluginOption;
|
||||||
|
|
||||||
// resolve the base url from the configuration file directory
|
|
||||||
const resolvedBaseUrl = path.posix.resolve(
|
|
||||||
path.posix.dirname(slash(tsConfigPath).replace(/^\/?/, '/')),
|
|
||||||
slash(baseUrl)
|
|
||||||
);
|
|
||||||
|
|
||||||
const configAlias = getConfigAlias(paths, resolvedBaseUrl);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'astro:tsconfig-alias',
|
name: 'astro:tsconfig-alias',
|
||||||
enforce: 'pre',
|
enforce: 'pre',
|
||||||
config() {
|
async resolveId(sourceId: string, importer, options) {
|
||||||
if (configAlias.length) {
|
/** Resolved ID conditionally handled by any other resolver. (this gives priority to all other resolvers) */
|
||||||
return {
|
const resolvedId = await this.resolve(sourceId, importer, { skipSelf: true, ...options });
|
||||||
resolve: {
|
|
||||||
alias: configAlias,
|
// if any other resolver handles the file, return that resolution
|
||||||
},
|
if (resolvedId) return resolvedId;
|
||||||
};
|
|
||||||
|
// conditionally resolve the source ID from any matching alias or baseUrl
|
||||||
|
for (const alias of configAlias) {
|
||||||
|
if (alias.find.test(sourceId)) {
|
||||||
|
/** Processed Source ID with our alias applied. */
|
||||||
|
const aliasedSourceId = sourceId.replace(alias.find, alias.replacement);
|
||||||
|
|
||||||
|
/** Resolved ID conditionally handled by any other resolver. (this also gives priority to all other resolvers) */
|
||||||
|
const resolvedAliasedId = await this.resolve(aliasedSourceId, importer, {
|
||||||
|
skipSelf: true,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
|
||||||
|
// if the existing resolvers find the file, return that resolution
|
||||||
|
if (resolvedAliasedId) return resolvedAliasedId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async resolveId(id, importer, options) {
|
|
||||||
if (id.startsWith('.') || path.isAbsolute(id)) return;
|
|
||||||
|
|
||||||
// Handle baseUrl mapping for non-relative and non-root imports.
|
|
||||||
// Since TypeScript only applies `baseUrl` autocompletions for files that exist
|
|
||||||
// in the filesystem only, we can use this heuristic to skip resolve if needed.
|
|
||||||
const resolved = path.posix.join(resolvedBaseUrl, id);
|
|
||||||
|
|
||||||
return await this.resolve(resolved, importer, {
|
|
||||||
skipSelf: true,
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,26 +34,5 @@ describe('Aliases with tsconfig.json', () => {
|
||||||
const scripts = $('script').toArray();
|
const scripts = $('script').toArray();
|
||||||
expect(scripts.length).to.be.greaterThan(0);
|
expect(scripts.length).to.be.greaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can load via baseUrl', async () => {
|
|
||||||
const html = await fixture.fetch('/').then((res) => res.text());
|
|
||||||
const $ = cheerio.load(html);
|
|
||||||
|
|
||||||
expect($('#foo').text()).to.equal('foo');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works in css @import', async () => {
|
|
||||||
const html = await fixture.fetch('/').then((res) => res.text());
|
|
||||||
// imported css should be bundled
|
|
||||||
expect(html).to.include('#style-red');
|
|
||||||
expect(html).to.include('#style-blue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can load load typescript files without .ts or .d.ts extensions', async () => {
|
|
||||||
const html = await fixture.fetch('/').then((res) => res.text());
|
|
||||||
const $ = cheerio.load(html);
|
|
||||||
|
|
||||||
expect($('#mistery').text()).to.equal("I'm a TypeScript file!");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<p id="foo">foo</p>
|
|
|
@ -1,2 +0,0 @@
|
||||||
<p id="style-blue">i am blue</p>
|
|
||||||
<p id="style-red">i am red</p>
|
|
|
@ -1,24 +1,15 @@
|
||||||
---
|
---
|
||||||
import Client from '@components/Client.svelte';
|
import Client from '@components/Client.svelte'
|
||||||
import Foo from 'src/components/Foo.astro';
|
|
||||||
import StyleComp from 'src/components/Style.astro';
|
|
||||||
import '@styles/main.css';
|
|
||||||
import { whoImI } from 'src/ts-file';
|
|
||||||
const mistery = whoImI();
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<title>Aliases using tsconfig</title>
|
<title>Aliases using tsconfig</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<Client client:load />
|
<Client client:load />
|
||||||
<Foo />
|
</main>
|
||||||
<StyleComp />
|
</body>
|
||||||
<div id="mistery">{mistery}</div>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#style-red {
|
|
||||||
color: red;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
@import "@styles/extra.css";
|
|
||||||
|
|
||||||
#style-blue {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
export function whoImI() {
|
|
||||||
return "I'm a TypeScript file!";
|
|
||||||
}
|
|
|
@ -5,9 +5,12 @@
|
||||||
"@components/*": [
|
"@components/*": [
|
||||||
"src/components/*"
|
"src/components/*"
|
||||||
],
|
],
|
||||||
"@styles/*": [
|
"@layouts/*": [
|
||||||
"src/styles/*"
|
"src/layouts/*"
|
||||||
]
|
],
|
||||||
|
"@assets/*": [
|
||||||
|
"src/assets/*"
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue