summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/astro/src/compiler/codegen/index.ts19
-rw-r--r--packages/astro/test/astro-basic.test.js8
-rw-r--r--packages/astro/test/astro-components.test.js14
-rw-r--r--packages/astro/test/fixtures/astro-components/src/pages/frontmatter-component.astro (renamed from packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro)0
-rw-r--r--packages/astro/test/fixtures/astro-components/src/pages/undefined-component.astro11
5 files changed, 41 insertions, 11 deletions
diff --git a/packages/astro/src/compiler/codegen/index.ts b/packages/astro/src/compiler/codegen/index.ts
index 39f39dc38..fb3bd3451 100644
--- a/packages/astro/src/compiler/codegen/index.ts
+++ b/packages/astro/src/compiler/codegen/index.ts
@@ -309,6 +309,7 @@ interface CodegenState {
markers: {
insideMarkdown: boolean | Record<string, any>;
};
+ declarations: Set<string>;
exportStatements: Set<string>;
importStatements: Set<string>;
customElementCandidates: Map<string, string>;
@@ -375,6 +376,9 @@ function compileModule(ast: Ast, module: Script, state: CodegenState, compileOpt
break;
}
case 'FunctionDeclaration': {
+ if (node.id?.name) {
+ state.declarations.add(node.id?.name);
+ }
break;
}
case 'ImportDeclaration': {
@@ -384,8 +388,14 @@ function compileModule(ast: Ast, module: Script, state: CodegenState, compileOpt
}
case 'VariableDeclaration': {
for (const declaration of node.declarations) {
- // only select Astro.fetchContent() calls here. this utility filters those out for us.
- if (!isFetchContent(declaration)) continue;
+ // only select Astro.fetchContent() calls for more processing,
+ // otherwise just push name to declarations
+ if (!isFetchContent(declaration)) {
+ if (declaration.id.type === 'Identifier') {
+ state.declarations.add(declaration.id.name);
+ }
+ continue;
+ }
// remove node
body.splice(i, 1);
@@ -687,7 +697,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
const [componentNamespace] = componentName.split('.');
componentInfo = components.get(componentNamespace);
}
- if (!componentInfo && !isCustomElementTag(componentName)) {
+ if (state.declarations.has(componentName) && !componentInfo && !isCustomElementTag(componentName)) {
if (hydrationAttributes.method) {
throw new Error(
`Unable to hydrate "${componentName}" because it is statically defined in the frontmatter script. Hydration directives may only be used on imported components.`
@@ -705,6 +715,8 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
paren++;
buffers[curr] += `h(${componentName}, ${attributes ? generateAttributes(attributes) : 'null'}`;
return;
+ } else if (!state.declarations.has(componentName) && !componentInfo && !isCustomElementTag(componentName)) {
+ throw new Error(`Unable to render "${componentName}" because it is undefined\n ${state.filename}`)
}
if (componentName === 'Markdown') {
const { $scope } = attributes ?? {};
@@ -870,6 +882,7 @@ export async function codegen(ast: Ast, { compileOptions, filename, fileID }: Co
markers: {
insideMarkdown: false,
},
+ declarations: new Set(),
importStatements: new Set(),
exportStatements: new Set(),
customElementCandidates: new Map(),
diff --git a/packages/astro/test/astro-basic.test.js b/packages/astro/test/astro-basic.test.js
index c2051b3eb..38f62085e 100644
--- a/packages/astro/test/astro-basic.test.js
+++ b/packages/astro/test/astro-basic.test.js
@@ -95,12 +95,4 @@ Basics('Allows spread attributes with TypeScript (#521)', async ({ runtime }) =>
assert.equal($('#spread-ts').attr('c'), '2');
});
-Basics('Allows Components defined in frontmatter', async ({ runtime }) => {
- const result = await runtime.load('/frontmatter-component');
- const html = result.contents;
- const $ = doc(html);
-
- assert.equal($('h1').length, 1);
-});
-
Basics.run();
diff --git a/packages/astro/test/astro-components.test.js b/packages/astro/test/astro-components.test.js
index 4f6fc05ab..aa5630584 100644
--- a/packages/astro/test/astro-components.test.js
+++ b/packages/astro/test/astro-components.test.js
@@ -26,4 +26,18 @@ Components('Astro components are able to render framework components', async ({
assert.not.type($svelte, 'undefined', 'Renders Svelte component');
});
+
+Components('Allows Components defined in frontmatter', async ({ runtime }) => {
+ const result = await runtime.load('/frontmatter-component');
+ const html = result.contents;
+ const $ = doc(html);
+
+ assert.equal($('h1').length, 1);
+});
+
+Components('Still throws an error for undefined components', async ({ runtime }) => {
+ const result = await runtime.load('/undefined-component');
+ assert.equal(result.statusCode, 500);
+});
+
Components.run();
diff --git a/packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro b/packages/astro/test/fixtures/astro-components/src/pages/frontmatter-component.astro
index 69f708505..69f708505 100644
--- a/packages/astro/test/fixtures/astro-basic/src/pages/frontmatter-component.astro
+++ b/packages/astro/test/fixtures/astro-components/src/pages/frontmatter-component.astro
diff --git a/packages/astro/test/fixtures/astro-components/src/pages/undefined-component.astro b/packages/astro/test/fixtures/astro-components/src/pages/undefined-component.astro
new file mode 100644
index 000000000..bdf9424bc
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-components/src/pages/undefined-component.astro
@@ -0,0 +1,11 @@
+---
+function FnComponent() {
+ const lame = 'ugh';
+ return <h2>Hey</h2>
+}
+const Defined = 'h1'
+---
+
+<FnComponent />
+<Defined>Hello world!</Defined>
+<Undefined />