Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate Astro frontmatter JS/TS on compiler error #2115

Merged
merged 5 commits into from
Dec 7, 2021

Conversation

FredKSchott
Copy link
Member

@FredKSchott FredKSchott commented Dec 3, 2021

Changes

  • Before passing a component to the compiler, use esbuild to validate the frontmatter against JS/TS syntax.
  • This will prevent a class of bug where bad front-matter syntax can break the compiled output in very obscure ways (for example, an unclosed parenthesis).
  • Once the compiler can handle this better, we can remove this.

Before

---
import Layout from '../layouts/MainLayout.astro';
{
--- 

Unclear error output.

Screen Shot 2021-12-03 at 11 58 30 AM

After

Clear error output, with the correct bug location. "end of file" is still a little odd wording (it should say "end of frontmatter", which we can fix by re-writing this error message if that makes sense) but this is already a nice improvement over broken output, compiler panics, etc.

Screen Shot 2021-12-03 at 11 58 49 AM

Testing

  • Still TODO

Docs

  • Not needed

@changeset-bot
Copy link

changeset-bot bot commented Dec 3, 2021

🦋 Changeset detected

Latest commit: 7bf85a3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
astro Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Dec 3, 2021
@netlify
Copy link

netlify bot commented Dec 3, 2021

✔️ Deploy Preview for astro-www ready!

🔨 Explore the source changes: b487414

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-www/deploys/61aa759143dd430008646dc7

😎 Browse the preview: https://deploy-preview-2115--astro-www.netlify.app

@netlify
Copy link

netlify bot commented Dec 3, 2021

✔️ Deploy Preview for astro-docs-2 ready!

🔨 Explore the source changes: b487414

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-docs-2/deploys/61aa75913ff0f2000ad00f03

😎 Browse the preview: https://deploy-preview-2115--astro-docs-2.netlify.app/guides/styling

@@ -88,6 +97,7 @@ export default function astro({ config, devServer }: AstroPluginOptions): vite.P
if (cssTransformError) throw cssTransformError;

// Compile `.ts` to `.js`
console.log(tsResult.code);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh, this should be removed. Thanks lint-bot!

Copy link
Member

@drwpow drwpow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty clever! This makes a lot of sense to me. And good error output

@matthewp
Copy link
Contributor

matthewp commented Dec 3, 2021

Can we do this in the catch instead? That way the cost is only occurred on code that has an error anyways and not for every compile that we do.

@FredKSchott
Copy link
Member Author

@matthewp clever! yes, that makes a ton of sense.

I'll make that change, clean the PR up, and some tests, and submit for re-review.

Copy link
Member

@natemoo-re natemoo-re left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On board with the concept, have reservations about this apporach.

Since the Astro compiler already does a lexical scan, what if it exposed a utility to output the raw frontmatter? We could then validate it separately from the rest of the generated file.

// The compiler doesn't currently validate the frontmatter, so invalid JS/TS can cause issues
// in the final output. This prevents bad JS from becoming a compiler panic or otherwise
// breaking the final output.
const scannedFrontmatter = /^\-\-\-(.*)^\-\-\-/ms.exec(source);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This RegExp approach would be too brittle IMO, this should use a lexical scan.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@natemoo-re if we can't validate it inside of the compiler, what if the compiler exported a function like validateFrontmatter or even validateJsExpression so we could run it on template fragments as well? I little nervous about this being async though, if called on every template expression.

Could this be a short-term fix, and then a longer-term fix would be to add this kind of checking into the Go compiler itself later on down the road? We'll probably want the same for valid CSS...

Copy link
Member

@drwpow drwpow Dec 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we follow @matthewp’s “only try on catch” strategy then this should only improve the experience. IMO the lexical scan won’t be as important because on catch we know for sure this is invalid JS. Then this would only be for error display and nothing more. So if by some happenstance that RegEx failed, it would only return a weird error message on edge cases (would would have been weird anyway, so same experience), but in most cases would vastly improve the UX.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on board with that reasoning and this being the short-term fix. No objections to moving forward with Matthew's suggested approach.

@FredKSchott
Copy link
Member Author

I'll also rewrite "unexpected end of file" to "unexpected end of frontmatter" if there are no objections.

@drwpow
Copy link
Member

drwpow commented Dec 4, 2021

IMO this doesn’t need a test, but if you do add one, adding a dev test in errors.test.js would be the easiest solution because there are very similar tests there.

@FredKSchott FredKSchott self-assigned this Dec 6, 2021
@FredKSchott FredKSchott changed the title Validate Astro frontmatter JS/TS ahead of compilation Validate Astro frontmatter JS/TS on compiler error Dec 7, 2021
@netlify
Copy link

netlify bot commented Dec 7, 2021

✔️ Deploy Preview for astro-www ready!

🔨 Explore the source changes: 71e47a1

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-www/deploys/61aea68024aac5000741f704

😎 Browse the preview: https://deploy-preview-2115--astro-www.netlify.app

@netlify
Copy link

netlify bot commented Dec 7, 2021

✔️ Deploy Preview for astro-docs-2 ready!

🔨 Explore the source changes: 71e47a1

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-docs-2/deploys/61aea680804b4e000794f470

😎 Browse the preview: https://deploy-preview-2115--astro-docs-2.netlify.app

@netlify
Copy link

netlify bot commented Dec 7, 2021

✔️ Deploy Preview for astro-www ready!

🔨 Explore the source changes: f7da6db

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-www/deploys/61aea7569ac477000796bf5b

😎 Browse the preview: https://deploy-preview-2115--astro-www.netlify.app

@netlify
Copy link

netlify bot commented Dec 7, 2021

✔️ Deploy Preview for astro-docs-2 ready!

🔨 Explore the source changes: 869adf8

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-docs-2/deploys/61aea6c084aebb000795e8f5

😎 Browse the preview: https://deploy-preview-2115--astro-docs-2.netlify.app

});

it('runtime error', async () => {
if (isMacOS) return;

// if (isMacOS) return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: i can run these locally, so I figured I'd uncomment to see what happens.

If they pass, I'll remove entirely.
If they fail, I'll uncomment.

Copy link
Member Author

@FredKSchott FredKSchott Dec 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update: tests are passing in CI so I'll remove completely
update: removed

@netlify
Copy link

netlify bot commented Dec 7, 2021

✔️ Deploy Preview for astro-docs-2 ready!

🔨 Explore the source changes: f7da6db

🔍 Inspect the deploy log: https://app.netlify.com/sites/astro-docs-2/deploys/61aea756f9f9730008bd5751

😎 Browse the preview: https://deploy-preview-2115--astro-docs-2.netlify.app

Copy link
Contributor

@matthewp matthewp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great

@FredKSchott FredKSchott merged commit 0ef682c into main Dec 7, 2021
@FredKSchott FredKSchott deleted the validate-frontmatter branch December 7, 2021 16:18
@FredKSchott
Copy link
Member Author

works great in build too:

$ astro build
Error: Transform failed with 1 error:
/Users/fks/Code/astro/docs/src/pages/index.astro:4:0: error: Unexpected end of frontmatter

@github-actions github-actions bot mentioned this pull request Dec 7, 2021
vineryap pushed a commit to vineryap/astro that referenced this pull request Dec 22, 2021
* validate the astro component frontmatter ahead of compilation

* add test, update existing tests

* chore(lint): Prettier fix

* Update index.ts

* remove macos skip lines, no longer needed

Co-authored-by: GitHub Action <[email protected]>
SiriousHunter pushed a commit to SiriousHunter/astro that referenced this pull request Feb 3, 2023
* validate the astro component frontmatter ahead of compilation

* add test, update existing tests

* chore(lint): Prettier fix

* Update index.ts

* remove macos skip lines, no longer needed

Co-authored-by: GitHub Action <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants