[ci] format
This commit is contained in:
parent
4412fe61f4
commit
b043fb1980
18 changed files with 104 additions and 70 deletions
|
@ -19,6 +19,6 @@ test.describe('Error: React Spectrum', () => {
|
|||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const message = await getErrorOverlayMessage(page);
|
||||
expect(message).toMatch('@adobe/react-spectrum is not compatible')
|
||||
expect(message).toMatch('@adobe/react-spectrum is not compatible');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,6 +19,6 @@ test.describe('Error: Sass', () => {
|
|||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
const message = await getErrorOverlayMessage(page);
|
||||
expect(message).toMatch('Undefined variable')
|
||||
expect(message).toMatch('Undefined variable');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,13 +19,16 @@ test.describe('Error display', () => {
|
|||
await page.goto(astro.resolveUrl('/astro-syntax-error'));
|
||||
|
||||
const message = await getErrorOverlayMessage(page);
|
||||
expect(message).toMatch('Unexpected "}"')
|
||||
expect(message).toMatch('Unexpected "}"');
|
||||
|
||||
await Promise.all([
|
||||
// Wait for page reload
|
||||
page.waitForNavigation(),
|
||||
// Edit the component file
|
||||
await astro.editFile('./src/pages/astro-syntax-error.astro', () => `<h1>No syntax error</h1>`)
|
||||
await astro.editFile(
|
||||
'./src/pages/astro-syntax-error.astro',
|
||||
() => `<h1>No syntax error</h1>`
|
||||
),
|
||||
]);
|
||||
|
||||
expect(await page.locator('vite-error-overlay').count()).toEqual(0);
|
||||
|
@ -35,13 +38,13 @@ test.describe('Error display', () => {
|
|||
await page.goto(astro.resolveUrl('/import-not-found'));
|
||||
|
||||
const message = await getErrorOverlayMessage(page);
|
||||
expect(message).toMatch('failed to load module for ssr: ../abc.astro')
|
||||
expect(message).toMatch('failed to load module for ssr: ../abc.astro');
|
||||
|
||||
await Promise.all([
|
||||
// Wait for page reload
|
||||
page.waitForNavigation(),
|
||||
// Edit the component file
|
||||
astro.editFile('./src/pages/import-not-found.astro', () => `<h1>No import error</h1>`)
|
||||
astro.editFile('./src/pages/import-not-found.astro', () => `<h1>No import error</h1>`),
|
||||
]);
|
||||
|
||||
expect(await page.locator('vite-error-overlay').count()).toEqual(0);
|
||||
|
@ -51,17 +54,15 @@ test.describe('Error display', () => {
|
|||
await page.goto(astro.resolveUrl('/svelte-syntax-error'));
|
||||
|
||||
const message = await getErrorOverlayMessage(page);
|
||||
expect(message).toMatch('</div> attempted to close an element that was not open')
|
||||
expect(message).toMatch('</div> attempted to close an element that was not open');
|
||||
|
||||
await Promise.all([
|
||||
// Wait for page reload
|
||||
page.waitForNavigation(),
|
||||
// Edit the component file
|
||||
astro.editFile('./src/components/SvelteSyntaxError.svelte', () => `<h1>No mismatch</h1>`)
|
||||
astro.editFile('./src/components/SvelteSyntaxError.svelte', () => `<h1>No mismatch</h1>`),
|
||||
]);
|
||||
|
||||
expect(await page.locator('vite-error-overlay').count()).toEqual(0);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -3,9 +3,9 @@ import { prepareTestFactory } from './shared-component-tests.js';
|
|||
const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-compat-component/' });
|
||||
|
||||
const config = {
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
}
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
};
|
||||
|
||||
test.describe('preact/compat components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -3,9 +3,9 @@ import { prepareTestFactory } from './shared-component-tests.js';
|
|||
const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-component/' });
|
||||
|
||||
const config = {
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
}
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
};
|
||||
|
||||
test.describe('Preact components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -3,9 +3,9 @@ import { prepareTestFactory } from './shared-component-tests.js';
|
|||
const { test, createTests } = prepareTestFactory({ root: './fixtures/react-component/' });
|
||||
|
||||
const config = {
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
}
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
};
|
||||
|
||||
test.describe('React components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -5,7 +5,7 @@ const { test, createTests } = prepareTestFactory({ root: './fixtures/solid-compo
|
|||
const config = {
|
||||
componentFilePath: './src/components/SolidComponent.jsx',
|
||||
counterComponentFilePath: './src/components/Counter.jsx',
|
||||
}
|
||||
};
|
||||
|
||||
test.describe('Solid components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -6,7 +6,7 @@ const config = {
|
|||
componentFilePath: './src/components/SvelteComponent.svelte',
|
||||
counterComponentFilePath: './src/components/Counter.svelte',
|
||||
counterCssFilePath: './src/components/Counter.svelte',
|
||||
}
|
||||
};
|
||||
|
||||
test.describe('Svelte components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -31,9 +31,12 @@ export function testFactory(inlineConfig) {
|
|||
}
|
||||
|
||||
export async function getErrorOverlayMessage(page) {
|
||||
const overlay = await page.waitForSelector('vite-error-overlay', { strict: true, timeout: 10 * 1000 })
|
||||
|
||||
expect(overlay).toBeTruthy()
|
||||
|
||||
return await overlay.$$eval('.message-body', (m) => m[0].textContent)
|
||||
const overlay = await page.waitForSelector('vite-error-overlay', {
|
||||
strict: true,
|
||||
timeout: 10 * 1000,
|
||||
});
|
||||
|
||||
expect(overlay).toBeTruthy();
|
||||
|
||||
return await overlay.$$eval('.message-body', (m) => m[0].textContent);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ const config = {
|
|||
componentFilePath: './src/components/VueComponent.vue',
|
||||
counterCssFilePath: './src/components/Counter.vue',
|
||||
counterComponentFilePath: './src/components/Counter.vue',
|
||||
}
|
||||
};
|
||||
|
||||
test.describe('Vue components in Astro files', () => {
|
||||
createTests({
|
||||
|
|
|
@ -33,7 +33,7 @@ const config = {
|
|||
use: {
|
||||
browserName: 'chromium',
|
||||
channel: 'chrome',
|
||||
args: ["--use-gl=egl"]
|
||||
args: ['--use-gl=egl'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -4,7 +4,6 @@ import type { LogOptions } from './logger/core';
|
|||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import * as vite from 'vite';
|
||||
import { createCustomViteLogger } from './errors.js';
|
||||
import astroPostprocessVitePlugin from '../vite-plugin-astro-postprocess/index.js';
|
||||
import astroViteServerPlugin from '../vite-plugin-astro-server/index.js';
|
||||
import astroVitePlugin from '../vite-plugin-astro/index.js';
|
||||
|
@ -14,6 +13,7 @@ import astroIntegrationsContainerPlugin from '../vite-plugin-integrations-contai
|
|||
import jsxVitePlugin from '../vite-plugin-jsx/index.js';
|
||||
import markdownVitePlugin from '../vite-plugin-markdown/index.js';
|
||||
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
|
||||
import { createCustomViteLogger } from './errors.js';
|
||||
import { resolveDependency } from './util.js';
|
||||
|
||||
// note: ssr is still an experimental API hence the type omission from `vite`
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import type { BuildResult } from 'esbuild';
|
||||
import type { ViteDevServer, ErrorPayload, LogLevel, Logger } from 'vite';
|
||||
import type { ErrorPayload, Logger, LogLevel, ViteDevServer } from 'vite';
|
||||
import type { SSRError } from '../@types/astro';
|
||||
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { createLogger } from 'vite';
|
||||
import eol from 'eol';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import { createLogger } from 'vite';
|
||||
import { codeFrame, createSafeError } from './util.js';
|
||||
|
||||
export enum AstroErrorCodes {
|
||||
|
@ -38,7 +38,7 @@ export function cleanErrorStack(stack: string) {
|
|||
return stack
|
||||
.split(/\n/g)
|
||||
.filter((l) => /^\s*at/.test(l))
|
||||
.map(l => l.replace(/\/@fs\//g, '/'))
|
||||
.map((l) => l.replace(/\/@fs\//g, '/'))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,11 @@ export function fixViteErrorMessage(_err: unknown, server: ViteDevServer, filePa
|
|||
const importName = err.message.split('for ssr:').at(1)?.trim();
|
||||
if (importName) {
|
||||
const content = fs.readFileSync(fileURLToPath(filePath)).toString();
|
||||
const lns = content.split('\n')
|
||||
const line = lns.findIndex(ln => ln.includes(importName));
|
||||
const lns = content.split('\n');
|
||||
const line = lns.findIndex((ln) => ln.includes(importName));
|
||||
const column = lns[line].indexOf(importName);
|
||||
if (!(err as any).id) {
|
||||
(err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`
|
||||
(err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ const incompatiblePackages = {
|
|||
};
|
||||
const incompatPackageExp = new RegExp(`(${Object.keys(incompatiblePackages).join('|')})`);
|
||||
|
||||
|
||||
export function createCustomViteLogger(logLevel: LogLevel): Logger {
|
||||
const viteLogger = createLogger(logLevel);
|
||||
const logger: Logger = {
|
||||
|
@ -82,7 +81,7 @@ export function createCustomViteLogger(logLevel: LogLevel): Logger {
|
|||
if (incompatPackageExp.test(msg)) return;
|
||||
return viteLogger.error(msg, options);
|
||||
},
|
||||
}
|
||||
};
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
@ -112,27 +111,30 @@ export function collectErrorMetadata(e: any, filePath?: URL): ErrorWithMetadata
|
|||
// derive error location from stack (if possible)
|
||||
const stackText = stripAnsi(e.stack);
|
||||
// TODO: this could be better, `src` might be something else
|
||||
const possibleFilePath = err.pluginCode || err.id || stackText.split('\n').find(ln => ln.includes('src') || ln.includes('node_modules'));
|
||||
const possibleFilePath =
|
||||
err.pluginCode ||
|
||||
err.id ||
|
||||
stackText.split('\n').find((ln) => ln.includes('src') || ln.includes('node_modules'));
|
||||
const source = possibleFilePath?.replace(/^[^(]+\(([^)]+).*$/, '$1');
|
||||
const [file, line, column] = source?.split(':') ?? [];
|
||||
if (!err.loc && line && column) {
|
||||
err.loc = {
|
||||
file,
|
||||
line: Number.parseInt(line),
|
||||
column: Number.parseInt(column)
|
||||
}
|
||||
column: Number.parseInt(column),
|
||||
};
|
||||
}
|
||||
|
||||
// Derive plugin from stack (if possible)
|
||||
if (!err.plugin) {
|
||||
err.plugin =
|
||||
/withastro\/astro\/packages\/integrations\/([\w-]+)/gmi.exec(stackText)?.at(1) ||
|
||||
/(@astrojs\/[\w-]+)\/(server|client|index)/gmi.exec(stackText)?.at(1) ||
|
||||
err.plugin =
|
||||
/withastro\/astro\/packages\/integrations\/([\w-]+)/gim.exec(stackText)?.at(1) ||
|
||||
/(@astrojs\/[\w-]+)\/(server|client|index)/gim.exec(stackText)?.at(1) ||
|
||||
undefined;
|
||||
}
|
||||
|
||||
// Normalize stack (remove `/@fs/` urls, etc)
|
||||
err.stack = cleanErrorStack(e.stack)
|
||||
err.stack = cleanErrorStack(e.stack);
|
||||
}
|
||||
|
||||
if (e.name === 'YAMLException') {
|
||||
|
@ -189,6 +191,6 @@ export function getViteErrorPayload(err: ErrorWithMetadata): ErrorPayload {
|
|||
plugin,
|
||||
message: message.trim(),
|
||||
stack: err.stack,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -79,7 +79,10 @@ export function createSafeError(err: any): Error {
|
|||
/** generate code frame from esbuild error */
|
||||
export function codeFrame(src: string, loc: ErrorPayload['err']['loc']): string {
|
||||
if (!loc) return '';
|
||||
const lines = eol.lf(src).split('\n').map(ln => ln.replace(/\t/g, ' '));
|
||||
const lines = eol
|
||||
.lf(src)
|
||||
.split('\n')
|
||||
.map((ln) => ln.replace(/\t/g, ' '));
|
||||
// grab 2 lines before, and 3 lines after focused line
|
||||
const visibleLines = [];
|
||||
for (let n = -2; n <= 2; n++) {
|
||||
|
@ -98,7 +101,9 @@ export function codeFrame(src: string, loc: ErrorPayload['err']['loc']): string
|
|||
output += isFocusedLine ? '> ' : ' ';
|
||||
output += `${lineNo + 1} | ${lines[lineNo]}\n`;
|
||||
if (isFocusedLine)
|
||||
output += `${Array.from({ length: gutterWidth }).join(' ')} | ${Array.from({ length: loc.column }).join(' ')}^\n`;
|
||||
output += `${Array.from({ length: gutterWidth }).join(' ')} | ${Array.from({
|
||||
length: loc.column,
|
||||
}).join(' ')}^\n`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -190,8 +190,8 @@ export function __astro_tag_component__(Component: unknown, rendererName: string
|
|||
Object.defineProperty(Component, Renderer, {
|
||||
value: rendererName,
|
||||
enumerable: false,
|
||||
writable: false
|
||||
})
|
||||
writable: false,
|
||||
});
|
||||
}
|
||||
|
||||
export async function renderComponent(
|
||||
|
@ -801,7 +801,7 @@ export async function renderPage(
|
|||
}
|
||||
controller.close();
|
||||
} catch (e) {
|
||||
controller.error(e)
|
||||
controller.error(e);
|
||||
}
|
||||
}
|
||||
read();
|
||||
|
@ -877,7 +877,7 @@ export async function* renderAstroComponent(
|
|||
if (value || value === 0) {
|
||||
for await (const chunk of _render(value)) {
|
||||
yield markHTMLString(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,12 @@ import type { SSROptions } from '../core/render/dev/index';
|
|||
|
||||
import { Readable } from 'stream';
|
||||
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
|
||||
import { collectErrorMetadata, ErrorWithMetadata, fixViteErrorMessage, getViteErrorPayload } from '../core/errors.js';
|
||||
import {
|
||||
collectErrorMetadata,
|
||||
ErrorWithMetadata,
|
||||
fixViteErrorMessage,
|
||||
getViteErrorPayload,
|
||||
} from '../core/errors.js';
|
||||
import { error, info, LogOptions, warn } from '../core/logger/core.js';
|
||||
import * as msg from '../core/messages.js';
|
||||
import { appendForwardSlash } from '../core/path.js';
|
||||
|
@ -151,11 +156,15 @@ async function handle500Response(
|
|||
res: http.ServerResponse,
|
||||
err: ErrorWithMetadata
|
||||
) {
|
||||
res.on('close', () => setTimeout(() => viteServer.ws.send(getViteErrorPayload(err)), 200))
|
||||
res.on('close', () => setTimeout(() => viteServer.ws.send(getViteErrorPayload(err)), 200));
|
||||
if (res.headersSent) {
|
||||
res.end()
|
||||
res.end();
|
||||
} else {
|
||||
writeHtmlResponse(res, 500, `<title>${err.name}</title><script type="module" src="/@vite/client"></script>`);
|
||||
writeHtmlResponse(
|
||||
res,
|
||||
500,
|
||||
`<title>${err.name}</title><script type="module" src="/@vite/client"></script>`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +234,7 @@ async function handleRequest(
|
|||
clientAddress: buildingToSSR ? req.socket.remoteAddress : undefined,
|
||||
});
|
||||
|
||||
let filePath: URL|undefined;
|
||||
let filePath: URL | undefined;
|
||||
try {
|
||||
if (!pathname.startsWith(devRoot)) {
|
||||
log404(logging, pathname);
|
||||
|
|
|
@ -5,13 +5,13 @@ import type { LogOptions } from '../core/logger/core.js';
|
|||
import type { PluginMetadata } from '../vite-plugin-astro/types';
|
||||
|
||||
import babel from '@babel/core';
|
||||
import tagExportsPlugin from './tag.js';
|
||||
import * as eslexer from 'es-module-lexer';
|
||||
import esbuild from 'esbuild';
|
||||
import * as colors from 'kleur/colors';
|
||||
import path from 'path';
|
||||
import { error } from '../core/logger/core.js';
|
||||
import { parseNpmName } from '../core/util.js';
|
||||
import tagExportsPlugin from './tag.js';
|
||||
|
||||
const JSX_RENDERER_CACHE = new WeakMap<AstroConfig, Map<string, AstroRenderer>>();
|
||||
const JSX_EXTENSIONS = new Set(['.jsx', '.tsx', '.mdx']);
|
||||
|
|
|
@ -9,7 +9,11 @@ import * as t from '@babel/types';
|
|||
* This plugin crawls each export in the file and "tags" each export with a given `rendererName`.
|
||||
* This allows us to automatically match a component to a renderer and skip the usual `check()` calls.
|
||||
*/
|
||||
export default function tagExportsWithRenderer({ rendererName }: { rendererName: string }): PluginObj {
|
||||
export default function tagExportsWithRenderer({
|
||||
rendererName,
|
||||
}: {
|
||||
rendererName: string;
|
||||
}): PluginObj {
|
||||
return {
|
||||
visitor: {
|
||||
Program: {
|
||||
|
@ -19,22 +23,32 @@ export default function tagExportsWithRenderer({ rendererName }: { rendererName:
|
|||
0,
|
||||
0,
|
||||
t.importDeclaration(
|
||||
[t.importSpecifier(t.identifier('__astro_tag_component__'), t.identifier('__astro_tag_component__'))],
|
||||
[
|
||||
t.importSpecifier(
|
||||
t.identifier('__astro_tag_component__'),
|
||||
t.identifier('__astro_tag_component__')
|
||||
),
|
||||
],
|
||||
t.stringLiteral('astro/server/index.js')
|
||||
)
|
||||
);
|
||||
},
|
||||
// For each export we found, inject `__astro_tag_component__(exportName, rendererName)`
|
||||
exit(path, state) {
|
||||
const exportedIds = state.get('astro:tags')
|
||||
const exportedIds = state.get('astro:tags');
|
||||
if (exportedIds) {
|
||||
for (const id of exportedIds) {
|
||||
path.node.body.push(
|
||||
t.expressionStatement(t.callExpression(t.identifier('__astro_tag_component__'), [t.identifier(id), t.stringLiteral(rendererName)]))
|
||||
)
|
||||
t.expressionStatement(
|
||||
t.callExpression(t.identifier('__astro_tag_component__'), [
|
||||
t.identifier(id),
|
||||
t.stringLiteral(rendererName),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
ExportDeclaration(path, state) {
|
||||
const node = path.node;
|
||||
|
@ -45,20 +59,20 @@ export default function tagExportsWithRenderer({ rendererName }: { rendererName:
|
|||
if (t.isFunctionDeclaration(node.declaration)) {
|
||||
if (node.declaration.id?.name) {
|
||||
const id = node.declaration.id.name;
|
||||
const tags = state.get('astro:tags') ?? []
|
||||
state.set('astro:tags', [...tags, id])
|
||||
const tags = state.get('astro:tags') ?? [];
|
||||
state.set('astro:tags', [...tags, id]);
|
||||
}
|
||||
}
|
||||
} else if (node.type === 'ExportDefaultDeclaration') {
|
||||
if (t.isFunctionDeclaration(node.declaration)) {
|
||||
if (node.declaration.id?.name) {
|
||||
const id = node.declaration.id.name;
|
||||
const tags = state.get('astro:tags') ?? []
|
||||
state.set('astro:tags', [...tags, id])
|
||||
const tags = state.get('astro:tags') ?? [];
|
||||
state.set('astro:tags', [...tags, id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue