Improve error messages (#1875)
* Fix error handling in correct scope Also improve Vite IDs for better module graph lookups * Improve code frame * Add changeset * maybeLoc can be undefined * Add tests Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
78b3371adb
commit
8986d33bfc
39 changed files with 449 additions and 62 deletions
6
.changeset/two-ducks-sit.md
Normal file
6
.changeset/two-ducks-sit.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'astro': patch
|
||||
'@astrojs/renderer-vue': patch
|
||||
---
|
||||
|
||||
Improve error display
|
|
@ -104,7 +104,7 @@ class AstroBuilder {
|
|||
return routes;
|
||||
})
|
||||
.catch((err) => {
|
||||
debug(logging, 'build', `├── ${colors.bold(colors.red(' '))} ${route.component}`);
|
||||
debug(logging, 'build', `├── ${colors.bold(colors.red('✘'))} ${route.component}`);
|
||||
throw err;
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import type vite from '../vite';
|
||||
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import slash from 'slash';
|
||||
import { viteifyURL } from '../util.js';
|
||||
|
||||
// https://vitejs.dev/guide/features.html#css-pre-processors
|
||||
export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.scss', '.sass', '.styl', '.stylus', '.less']);
|
||||
|
@ -11,7 +10,7 @@ export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.scss', '.sass', '.st
|
|||
export function getStylesForURL(filePath: URL, viteServer: vite.ViteDevServer): Set<string> {
|
||||
const css = new Set<string>();
|
||||
const { idToModuleMap } = viteServer.moduleGraph;
|
||||
const rootID = slash(fileURLToPath(filePath)); // Vite fix: Windows URLs must have forward slashes
|
||||
const rootID = viteifyURL(filePath);
|
||||
const moduleGraph = idToModuleMap.get(rootID);
|
||||
if (!moduleGraph) return css;
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ import type {
|
|||
} from '../../@types/astro';
|
||||
import type { LogOptions } from '../logger';
|
||||
|
||||
import eol from 'eol';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import slash from 'slash';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { renderPage, renderSlot } from '../../runtime/server/index.js';
|
||||
import { canonicalURL as getCanonicalURL, codeFrame, resolveDependency, viteifyPath } from '../util.js';
|
||||
import { canonicalURL as getCanonicalURL, codeFrame, resolveDependency, viteifyURL } from '../util.js';
|
||||
import { getStylesForURL } from './css.js';
|
||||
import { injectTags } from './html.js';
|
||||
import { generatePaginateFunction } from './paginate.js';
|
||||
|
@ -88,22 +88,34 @@ async function resolveRenderers(viteServer: vite.ViteDevServer, astroConfig: Ast
|
|||
return renderers;
|
||||
}
|
||||
|
||||
async function errorHandler(e: unknown, viteServer: vite.ViteDevServer, filePath: URL) {
|
||||
interface ErrorHandlerOptions {
|
||||
filePath: URL;
|
||||
viteServer: vite.ViteDevServer;
|
||||
}
|
||||
|
||||
async function errorHandler(e: unknown, { viteServer, filePath }: ErrorHandlerOptions) {
|
||||
// normalize error stack line-endings to \n
|
||||
if ((e as any).stack) {
|
||||
(e as any).stack = eol.lf((e as any).stack);
|
||||
}
|
||||
|
||||
// fix stack trace with Vite (this searches its module graph for matches)
|
||||
if (e instanceof Error) {
|
||||
viteServer.ssrFixStacktrace(e);
|
||||
}
|
||||
|
||||
// Astro error (thrown by esbuild so it needs to be formatted for Vite)
|
||||
const anyError = e as any;
|
||||
if (anyError.errors) {
|
||||
if (Array.isArray((e as any).errors)) {
|
||||
const { location, pluginName, text } = (e as BuildResult).errors[0];
|
||||
const err = e as SSRError;
|
||||
if (location) err.loc = { file: location.file, line: location.line, column: location.column };
|
||||
const frame = codeFrame(await fs.promises.readFile(filePath, 'utf8'), err.loc);
|
||||
err.frame = frame;
|
||||
let src = err.pluginCode;
|
||||
if (!src && err.id && fs.existsSync(err.id)) src = await fs.promises.readFile(err.id, 'utf8');
|
||||
if (!src) src = await fs.promises.readFile(filePath, 'utf8');
|
||||
err.frame = codeFrame(src, err.loc);
|
||||
err.id = location?.file;
|
||||
err.message = `${location?.file}: ${text}
|
||||
${frame}
|
||||
${err.frame}
|
||||
`;
|
||||
if (pluginName) err.plugin = pluginName;
|
||||
throw err;
|
||||
|
@ -119,8 +131,7 @@ export async function preload({ astroConfig, filePath, viteServer }: SSROptions)
|
|||
// Important: This needs to happen first, in case a renderer provides polyfills.
|
||||
const renderers = await resolveRenderers(viteServer, astroConfig);
|
||||
// Load the module from the Vite SSR Runtime.
|
||||
const viteFriendlyURL = viteifyPath(filePath.pathname);
|
||||
const mod = (await viteServer.ssrLoadModule(viteFriendlyURL)) as ComponentInstance;
|
||||
const mod = (await viteServer.ssrLoadModule(viteifyURL(filePath))) as ComponentInstance;
|
||||
|
||||
return [renderers, mod];
|
||||
}
|
||||
|
@ -250,8 +261,7 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO
|
|||
|
||||
// run transformIndexHtml() in dev to run Vite dev transformations
|
||||
if (mode === 'development') {
|
||||
const viteFilePath = slash(fileURLToPath(filePath)); // Vite Windows fix: URLs on Windows have forward slashes (not .pathname, which has a leading '/' on Windows)
|
||||
html = await viteServer.transformIndexHtml(viteFilePath, html, pathname);
|
||||
html = await viteServer.transformIndexHtml(viteifyURL(filePath), html, pathname);
|
||||
}
|
||||
|
||||
return html;
|
||||
|
@ -269,9 +279,9 @@ async function getHmrScript() {
|
|||
export async function ssr(ssrOpts: SSROptions): Promise<string> {
|
||||
try {
|
||||
const [renderers, mod] = await preload(ssrOpts);
|
||||
return render(renderers, mod, ssrOpts);
|
||||
return await render(renderers, mod, ssrOpts); // note(drew): without "await", errors won’t get caught by errorHandler()
|
||||
} catch (e: unknown) {
|
||||
await errorHandler(e, ssrOpts.viteServer, ssrOpts.filePath);
|
||||
await errorHandler(e, { viteServer: ssrOpts.viteServer, filePath: ssrOpts.filePath });
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import type { AstroConfig } from '../@types/astro';
|
|||
import type { ErrorPayload } from 'vite';
|
||||
import eol from 'eol';
|
||||
import path from 'path';
|
||||
import slash from 'slash';
|
||||
import { fileURLToPath, pathToFileURL } from 'url';
|
||||
import resolve from 'resolve';
|
||||
|
||||
|
@ -72,6 +73,13 @@ export function resolveDependency(dep: string, astroConfig: AstroConfig) {
|
|||
return pathToFileURL(resolved).toString();
|
||||
}
|
||||
|
||||
export function viteifyPath(pathname: string): string {
|
||||
return `/@fs/${pathname.replace(/^\//, '')}`;
|
||||
/**
|
||||
* Vite-ify URL
|
||||
* Given a file URL, return an ID that matches Vite’s module graph. Needed for resolution and stack trace fixing.
|
||||
* Must match the following format:
|
||||
* Linux/Mac: /Users/astro/code/my-project/src/pages/index.astro
|
||||
* Windows: C:/Users/astro/code/my-project/src/pages/index.astro
|
||||
*/
|
||||
export function viteifyURL(filePath: URL): string {
|
||||
return slash(fileURLToPath(filePath));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import fs from 'fs';
|
|||
import { fileURLToPath } from 'url';
|
||||
import os from 'os';
|
||||
import { transform } from '@astrojs/compiler';
|
||||
import { decode } from 'sourcemap-codec';
|
||||
import { AstroDevServer } from '../core/dev/index.js';
|
||||
import { getViteTransform, TransformHook, transformWithVite } from './styles.js';
|
||||
|
||||
|
@ -121,16 +120,6 @@ ${err.url}`;
|
|||
err.stack = ` at ${id}`;
|
||||
}
|
||||
|
||||
// improve esbuild errors
|
||||
if (err.errors && tsResult?.map) {
|
||||
const json = JSON.parse(tsResult.map);
|
||||
const mappings = decode(json.mappings);
|
||||
const focusMapping = mappings[err.errors[0].location.line + 1];
|
||||
if (Array.isArray(focusMapping) && focusMapping.length) {
|
||||
err.sourceLoc = { file: id, line: (focusMapping[0][2] || 0) + 1, column: (focusMapping[0][3] || 0) + 1 };
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -8,13 +8,10 @@ import srcsetParse from 'srcset-parse';
|
|||
import * as npath from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import { getAttribute, hasAttribute, getTagName, insertBefore, remove, createScript, createElement, setAttribute } from '@web/parse5-utils';
|
||||
import slash from 'slash';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { addRollupInput } from './add-rollup-input.js';
|
||||
import { findAssets, findExternalScripts, findInlineScripts, findInlineStyles, getTextContent, isStylesheetLink } from './extract-assets.js';
|
||||
import { render as ssrRender } from '../core/ssr/index.js';
|
||||
import { getAstroStyleId, getAstroPageStyleId } from '../vite-plugin-build-css/index.js';
|
||||
import { viteifyPath } from '../core/util.js';
|
||||
|
||||
// This package isn't real ESM, so have to coerce it
|
||||
const matchSrcset: typeof srcsetParse = (srcsetParse as any).default;
|
||||
|
@ -140,8 +137,7 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin {
|
|||
for (let node of findAssets(document)) {
|
||||
if (isBuildableLink(node, srcRoot)) {
|
||||
const href = getAttribute(node, 'href')!;
|
||||
const linkId = viteifyPath(href);
|
||||
assetImports.push(linkId);
|
||||
assetImports.push(href);
|
||||
}
|
||||
|
||||
if (isBuildableImage(node, srcRoot)) {
|
||||
|
|
|
@ -137,6 +137,8 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin
|
|||
const { code: jsxCode } = await esbuild.transform(code, {
|
||||
loader: getEsbuildLoader(path.extname(id)) as esbuild.Loader,
|
||||
jsx: 'preserve',
|
||||
sourcefile: id,
|
||||
sourcemap: 'inline',
|
||||
});
|
||||
return transformJSX({ code: jsxCode, id, renderer: [...jsxRenderers.values()][0], mode, ssr });
|
||||
}
|
||||
|
@ -148,6 +150,8 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin
|
|||
jsx: 'transform',
|
||||
jsxFactory: 'h',
|
||||
jsxFragment: 'Fragment',
|
||||
sourcefile: id,
|
||||
sourcemap: 'inline',
|
||||
});
|
||||
|
||||
let imports: eslexer.ImportSpecifier[] = [];
|
||||
|
@ -191,8 +195,10 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin
|
|||
const { code: jsxCode } = await esbuild.transform(code, {
|
||||
loader: getEsbuildLoader(path.extname(id)) as esbuild.Loader,
|
||||
jsx: 'preserve',
|
||||
sourcefile: id,
|
||||
sourcemap: 'inline',
|
||||
});
|
||||
return transformJSX({ code: jsxCode, id, renderer: jsxRenderers.get(importSource) as Renderer, mode, ssr });
|
||||
return await transformJSX({ code: jsxCode, id, renderer: jsxRenderers.get(importSource) as Renderer, mode, ssr });
|
||||
}
|
||||
|
||||
// if we still can’t tell, throw error
|
||||
|
|
|
@ -2,25 +2,25 @@ import { expect } from 'chai';
|
|||
import cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
let fixture;
|
||||
let index$;
|
||||
let bundledCSS;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
projectRoot: './fixtures/astro-styles-ssr/',
|
||||
renderers: ['@astrojs/renderer-react', '@astrojs/renderer-svelte', '@astrojs/renderer-vue'],
|
||||
});
|
||||
await fixture.build();
|
||||
|
||||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
const html = await fixture.readFile('/index.html');
|
||||
index$ = cheerio.load(html);
|
||||
const bundledCSSHREF = index$('link[rel=stylesheet][href^=assets/]').attr('href');
|
||||
bundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
|
||||
});
|
||||
|
||||
describe('Styles SSR', function () {
|
||||
let fixture;
|
||||
let index$;
|
||||
let bundledCSS;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
projectRoot: './fixtures/astro-styles-ssr/',
|
||||
renderers: ['@astrojs/renderer-react', '@astrojs/renderer-svelte', '@astrojs/renderer-vue'],
|
||||
});
|
||||
await fixture.build();
|
||||
|
||||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
const html = await fixture.readFile('/index.html');
|
||||
index$ = cheerio.load(html);
|
||||
const bundledCSSHREF = index$('link[rel=stylesheet][href^=assets/]').attr('href');
|
||||
bundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
|
||||
});
|
||||
|
||||
describe('Astro styles', () => {
|
||||
it('HTML and CSS scoped correctly', async () => {
|
||||
const $ = index$;
|
||||
|
|
225
packages/astro/test/errors.test.js
Normal file
225
packages/astro/test/errors.test.js
Normal file
|
@ -0,0 +1,225 @@
|
|||
import { expect } from 'chai';
|
||||
import os from 'os';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
// TODO: fix these tests on macOS
|
||||
const isMacOS = os.platform() === 'darwin';
|
||||
|
||||
let fixture;
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
projectRoot: './fixtures/errors',
|
||||
renderers: ['@astrojs/renderer-preact', '@astrojs/renderer-react', '@astrojs/renderer-solid', '@astrojs/renderer-svelte', '@astrojs/renderer-vue'],
|
||||
vite: {
|
||||
optimizeDeps: false, // necessary to prevent Vite throwing on bad files
|
||||
},
|
||||
});
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
describe('Error display', () => {
|
||||
describe('Astro', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/astro-syntax-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message includes "unrecoverable error"
|
||||
const body = await res.text();
|
||||
expect(body).to.include('unrecoverable error');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/astro-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message contains error
|
||||
const body = await res.text();
|
||||
expect(body).to.include('ReferenceError: title is not defined');
|
||||
|
||||
// TODO: improve stacktrace
|
||||
});
|
||||
});
|
||||
|
||||
describe('JS', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/js-syntax-error');
|
||||
|
||||
// 500 returnd
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Parse failure');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/js-runtime-error');
|
||||
|
||||
// 500 returnd
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('ReferenceError: undefinedvar is not defined');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Preact', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/preact-syntax-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Syntax error');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/preact-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Error: PreactRuntimeError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('React', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/react-syntax-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Syntax error');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/react-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Error: ReactRuntimeError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Solid', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/solid-syntax-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Syntax error');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/solid-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Error: SolidRuntimeError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Svelte', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/svelte-syntax-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('ParseError');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/svelte-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.include('Error: SvelteRuntimeError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Vue', () => {
|
||||
it('syntax error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/vue-syntax-error');
|
||||
|
||||
const body = await res.text();
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
expect(body).to.include('Parse failure');
|
||||
});
|
||||
|
||||
it('runtime error', async () => {
|
||||
if (isMacOS) return;
|
||||
|
||||
const res = await fixture.fetch('/vue-runtime-error');
|
||||
|
||||
// 500 returned
|
||||
expect(res.status).to.equal(500);
|
||||
|
||||
// error message is helpful
|
||||
const body = await res.text();
|
||||
expect(body).to.match(/Cannot read.*undefined/); // note: error differs slightly between Node versions
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
3
packages/astro/test/fixtures/errors/src/components/JSRuntimeError.js
vendored
Normal file
3
packages/astro/test/fixtures/errors/src/components/JSRuntimeError.js
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function Error() {
|
||||
return undefinedvar;
|
||||
}
|
4
packages/astro/test/fixtures/errors/src/components/JSSyntaxError.js
vendored
Normal file
4
packages/astro/test/fixtures/errors/src/components/JSSyntaxError.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
export default function Error() {
|
||||
const 1badvar = true;
|
||||
return 1badvar;
|
||||
}
|
6
packages/astro/test/fixtures/errors/src/components/PreactRuntimeError.jsx
vendored
Normal file
6
packages/astro/test/fixtures/errors/src/components/PreactRuntimeError.jsx
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function PreactRuntimeError({shouldThrow = true}) {
|
||||
if (shouldThrow) throw new Error('PreactRuntimeError')
|
||||
return <div>I shouldn’t be here</div>;
|
||||
}
|
5
packages/astro/test/fixtures/errors/src/components/PreactSyntaxError.jsx
vendored
Normal file
5
packages/astro/test/fixtures/errors/src/components/PreactSyntaxError.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function PreactSyntaxError() {
|
||||
return (<div></div></div>);
|
||||
}
|
6
packages/astro/test/fixtures/errors/src/components/ReactRuntimeError.jsx
vendored
Normal file
6
packages/astro/test/fixtures/errors/src/components/ReactRuntimeError.jsx
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function ReactRuntimeError({shouldThrow = true}) {
|
||||
if (shouldThrow) throw new Error('ReactRuntimeError')
|
||||
return <div>I shouldn’t be here</div>;
|
||||
}
|
5
packages/astro/test/fixtures/errors/src/components/ReactSyntaxError.jsx
vendored
Normal file
5
packages/astro/test/fixtures/errors/src/components/ReactSyntaxError.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function ReactSyntaxError() {
|
||||
return (<div></div></div>);
|
||||
}
|
6
packages/astro/test/fixtures/errors/src/components/SolidRuntimeError.jsx
vendored
Normal file
6
packages/astro/test/fixtures/errors/src/components/SolidRuntimeError.jsx
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { h } from 'solid-js/web';
|
||||
|
||||
export default function SolidRuntimeError({shouldThrow = true}) {
|
||||
if (shouldThrow) throw new Error('SolidRuntimeError')
|
||||
return <div>I shouldn’t be here</div>;
|
||||
}
|
5
packages/astro/test/fixtures/errors/src/components/SolidSyntaxError.jsx
vendored
Normal file
5
packages/astro/test/fixtures/errors/src/components/SolidSyntaxError.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'solid-js/web'
|
||||
|
||||
export default function ReactSyntaxError() {
|
||||
return (<div></div></div>);
|
||||
}
|
9
packages/astro/test/fixtures/errors/src/components/SvelteRuntimeError.svelte
vendored
Normal file
9
packages/astro/test/fixtures/errors/src/components/SvelteRuntimeError.svelte
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<script>
|
||||
export let shouldThrow = true;
|
||||
|
||||
if (shouldThrow) {
|
||||
throw new Error('SvelteRuntimeError');
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>I shouldn’t be here</h1>
|
1
packages/astro/test/fixtures/errors/src/components/SvelteSyntaxError.svelte
vendored
Normal file
1
packages/astro/test/fixtures/errors/src/components/SvelteSyntaxError.svelte
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>Tag mismatch</div>
|
3
packages/astro/test/fixtures/errors/src/components/VueRuntimeError.vue
vendored
Normal file
3
packages/astro/test/fixtures/errors/src/components/VueRuntimeError.vue
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<h1>Wanna see something undefined? {{ not.here }}</h1>
|
||||
</template>
|
3
packages/astro/test/fixtures/errors/src/components/VueSyntaxError.vue
vendored
Normal file
3
packages/astro/test/fixtures/errors/src/components/VueSyntaxError.vue
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<p>This needs a template</p>
|
||||
<p>But alas, this is lacking</p>
|
||||
<p>Look 5 syllables</p>
|
1
packages/astro/test/fixtures/errors/src/pages/astro-runtime-error.astro
vendored
Normal file
1
packages/astro/test/fixtures/errors/src/pages/astro-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>{title}</h1>
|
1
packages/astro/test/fixtures/errors/src/pages/astro-syntax-error.astro
vendored
Normal file
1
packages/astro/test/fixtures/errors/src/pages/astro-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>{// comment
|
4
packages/astro/test/fixtures/errors/src/pages/js-runtime-error.astro
vendored
Normal file
4
packages/astro/test/fixtures/errors/src/pages/js-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
import Error from '../components/JSRuntimeError';
|
||||
---
|
||||
<div>{Error()}</div>
|
4
packages/astro/test/fixtures/errors/src/pages/js-syntax-error.astro
vendored
Normal file
4
packages/astro/test/fixtures/errors/src/pages/js-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
const Error = await import( '../components/JSSyntaxError.js');
|
||||
---
|
||||
<h1>{Error()}</h1>
|
7
packages/astro/test/fixtures/errors/src/pages/preact-runtime-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/preact-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import PreactRuntimeError from '../components/PreactRuntimeError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<PreactRuntimeError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/preact-syntax-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/preact-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import PreactSyntaxError from '../components/PreactSyntaxError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<PreactSyntaxError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/react-runtime-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/react-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import ReactRuntimeError from '../components/ReactRuntimeError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<ReactRuntimeError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/react-syntax-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/react-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import ReactSyntaxError from '../components/ReactSyntaxError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<ReactSyntaxError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/solid-runtime-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/solid-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import SolidRuntimeError from '../components/SolidRuntimeError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<SolidRuntimeError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/solid-syntax-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/solid-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import SolidSyntaxError from '../components/SolidSyntaxError.jsx';
|
||||
---
|
||||
|
||||
<div>
|
||||
<SolidSyntaxError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/svelte-runtime-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/svelte-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import SvelteRuntimeError from '../components/SvelteRuntimeError.svelte';
|
||||
---
|
||||
|
||||
<div>
|
||||
<SvelteRuntimeError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/svelte-syntax-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/svelte-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import SvelteSyntaxError from '../components/SvelteSyntaxError.svelte';
|
||||
---
|
||||
|
||||
<div>
|
||||
<SvelteSyntaxError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/vue-runtime-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/vue-runtime-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import VueRuntimeError from '../components/VueRuntimeError.vue';
|
||||
---
|
||||
|
||||
<div>
|
||||
<VueRuntimeError />
|
||||
</div>
|
7
packages/astro/test/fixtures/errors/src/pages/vue-syntax-error.astro
vendored
Normal file
7
packages/astro/test/fixtures/errors/src/pages/vue-syntax-error.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import VueSyntaxError from '../components/VueSyntaxError.vue';
|
||||
---
|
||||
|
||||
<div>
|
||||
<VueSyntaxError />
|
||||
</div>
|
|
@ -11,8 +11,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^1.9.4",
|
||||
"@vue/compiler-sfc": "^3.2.22",
|
||||
"@vue/server-renderer": "^3.2.22",
|
||||
"vue": "^3.2.22"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { renderToString } from '@vue/server-renderer';
|
||||
import { h, createSSRApp } from 'vue';
|
||||
import { renderToString } from 'vue/server-renderer';
|
||||
import StaticHtml from './static-html.js';
|
||||
|
||||
function check(Component) {
|
||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -351,7 +351,12 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.15.0", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3", "@babel/parser@^7.4.5":
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.4.5":
|
||||
version "7.15.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae"
|
||||
integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==
|
||||
|
||||
"@babel/parser@^7.15.0", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3":
|
||||
version "7.16.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e"
|
||||
integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==
|
||||
|
@ -2095,7 +2100,7 @@
|
|||
"@vue/compiler-core" "3.2.22"
|
||||
"@vue/shared" "3.2.22"
|
||||
|
||||
"@vue/compiler-sfc@3.2.22", "@vue/compiler-sfc@^3.2.22":
|
||||
"@vue/compiler-sfc@3.2.22":
|
||||
version "3.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.22.tgz#ffd0e5e35479b6ade18d12fefec369cbaf2f7718"
|
||||
integrity sha512-tWRQ5ge1tsTDhUwHgueicKJ8rYm6WUVAPTaIpFW3GSwZKcOEJ2rXdfkHFShNVGupeRALz2ET2H84OL0GeRxY0A==
|
||||
|
@ -2154,7 +2159,7 @@
|
|||
"@vue/shared" "3.2.22"
|
||||
csstype "^2.6.8"
|
||||
|
||||
"@vue/server-renderer@3.2.22", "@vue/server-renderer@^3.2.22":
|
||||
"@vue/server-renderer@3.2.22":
|
||||
version "3.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.22.tgz#049c91a495cb0fcdac02dec485c31cb99410885f"
|
||||
integrity sha512-jCwbQgKPXiXoH9VS9F7K+gyEvEMrjutannwEZD1R8fQ9szmOTqC+RRbIY3Uf2ibQjZtZ8DV9a4FjxICvd9zZlQ==
|
||||
|
@ -8450,7 +8455,7 @@ postcss-value-parser@^4.1.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
|
||||
|
||||
postcss@^8.1.10, postcss@^8.1.6, postcss@^8.2.1, postcss@^8.3.8:
|
||||
postcss@^8.1.10, postcss@^8.3.8:
|
||||
version "8.3.11"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858"
|
||||
integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==
|
||||
|
@ -8459,6 +8464,15 @@ postcss@^8.1.10, postcss@^8.1.6, postcss@^8.2.1, postcss@^8.3.8:
|
|||
picocolors "^1.0.0"
|
||||
source-map-js "^0.6.2"
|
||||
|
||||
postcss@^8.1.6, postcss@^8.2.1:
|
||||
version "8.3.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.6.tgz#2730dd76a97969f37f53b9a6096197be311cc4ea"
|
||||
integrity sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==
|
||||
dependencies:
|
||||
colorette "^1.2.2"
|
||||
nanoid "^3.1.23"
|
||||
source-map-js "^0.6.2"
|
||||
|
||||
preact-render-to-string@^5.1.19:
|
||||
version "5.1.19"
|
||||
resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.1.19.tgz#ffae7c3bd1680be5ecf5991d41fe3023b3051e0e"
|
||||
|
|
Loading…
Reference in a new issue