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

Add support for client:only hydrator #935

Merged
merged 16 commits into from
Aug 17, 2021

Conversation

tony-sull
Copy link
Contributor

RFC #751

Changes

Adding support for client:only hydration to skip components during SSR

Testing

The astro-dynamic.test.js suite was updated to include test coverage for:

  • client:only components are skipped during SSR
  • renderer scripts are included in the build
  • renderer scripts can be loaded

Docs

Component hydration docs have been updated to include client:only

@changeset-bot
Copy link

changeset-bot bot commented Jul 29, 2021

🦋 Changeset detected

Latest commit: 10bc040

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

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

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

@vercel
Copy link

vercel bot commented Jul 29, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployments, click below or on the icon next to each commit.

astro-www – ./www

🔍 Inspect: https://vercel.com/pikapkg/astro-www/4zAtNdT3Rb7WantKJsk4Y7tSuGWJ
✅ Preview: https://astro-www-git-fork-tony-sull-client-only-hydration-pikapkg.vercel.app

[Deployment for 10bc040 canceled]

astro-docs – ./docs

🔍 Inspect: https://vercel.com/pikapkg/astro-docs/6U8ms3QLsKE61YCBw5QUYV3roGS9
✅ Preview: https://astro-docs-git-fork-tony-sull-client-only-hydration-pikapkg.vercel.app

@matthewp
Copy link
Contributor

Thanks @tony-sull ! One thing missing from this is, we need to remove the import statements when client:only is used. One of the main use-cases for using client:only is when a dependency doesn't work in Node.js

I would create a test where a component depends on browser APIs... maybe it uses document.addEventListener in the module body. That will throw in Node.js.

To remove the import statement might be a little tricky because we compile the JS part before walking the HTML AST. Discovery of components happens here: https://github.com/snowpackjs/astro/blob/main/packages/astro/src/compiler/codegen/index.ts#L441

However, we won't know that an import needs to be removed until we've walked the HTML AST and found the client:only attr.

Idea: can we have compileModule return a function instead? That way we still have an opportunity to modify the AST inside of compileHtml. What I'm suggesting is that this part: https://github.com/snowpackjs/astro/blob/main/packages/astro/src/compiler/codegen/index.ts#L483-L487

would be wrapped in a function that only gets called after walking the HTML AST part.

@tony-sull tony-sull marked this pull request as draft July 30, 2021 14:32
@github-actions github-actions bot force-pushed the main branch 3 times, most recently from 983e6e0 to fc739c2 Compare August 3, 2021 14:50
@tony-sull
Copy link
Contributor Author

Think I'm finally getting close on this one! Delaying the component imports took much more knowledge of Astro's compiler than I realized 😄

The last piece I think I'm missing is including the correct renderer without actually executing the client-only component on the server

@matthewp
Copy link
Contributor

matthewp commented Aug 9, 2021

@tony-sull I think if you leave the import in at first the correct renderer will be added. Then remove it at the end of codegen. That's why I was suggesting to change the signature of that function to return a function rather than the JS string, that way you can modify the AST when walking the HTML part of the tree. Hope this helps.

@tony-sull
Copy link
Contributor Author

@tony-sull I think if you leave the import in at first the correct renderer will be added. Then remove it at the end of codegen. That's why I was suggesting to change the signature of that function to return a function rather than the JS string, that way you can modify the AST when walking the HTML part of the tree. Hope this helps.

Thanks for your help here @matthewp!

I may very well be misunderstanding a key bit here, but I'm not sure if that would do the trick for finding the right renderer. The import has to be removed before __astro_component is called in the build, but __astro_component is what actually inspects the compiled Component to decide which renderer to include in the hydration script.

I ended up solving how to remove the import slightly differently and may need to move it to use the callback function mentioned, but I'm not quite sure yet how to have __astro_component find the correct hydration renderer for the component since it can't be imported and passed as a prop to __astro_component

@FredKSchott
Copy link
Member

Will leave for others to review but overall +1 on this feature! Thanks for working to make it a reality, @tony-navillus !

@matthewp
Copy link
Contributor

@tony-sull is this ready to be merged?

@tony-sull
Copy link
Contributor Author

@tony-sull is this ready to be merged?

@matthewp Just pushed the final update to match renderers by full name (+ shorthand for @astrojs renderers)

The push ~30 min ago was just me rebasing from main before the final commit

@matthewp matthewp merged commit 1971ab3 into withastro:main Aug 17, 2021
@tony-sull tony-sull deleted the client-only-hydration branch August 17, 2021 19:01
FredKSchott pushed a commit that referenced this pull request Aug 18, 2021
* Adding support for client:only hydration

* Adding documentation for client:only

* Adding changeset

* Updating the test to use a browser-only API

* Adding a browser-specific import script, this reproduces the issue where client:only imports must be removed

* typo fix

* removing mispelled test component

* WIP: delaying inclusion of component imports until the hydration method is known

* WIP: tweaking the test to use window instead of document

* When only one renderer is included, use that for client:only hydration

* temporary test script snuck into the last commit

* WIP: adding check for a client:only renderer hint

* refactor: Remove client:only components instead of delaying all component import statements

* Updating the changeset and docs for the renderer hint

* refactor: pull client:only render matching out to it's own function

* Updating renderer hinting to match full name, with shorthand for internal renderers

Co-authored-by: Tony Sullivan <[email protected]>
FredKSchott added a commit that referenced this pull request Aug 18, 2021
* wip

* Add support for `client:only` hydrator (#935)

* Adding support for client:only hydration

* Adding documentation for client:only

* Adding changeset

* Updating the test to use a browser-only API

* Adding a browser-specific import script, this reproduces the issue where client:only imports must be removed

* typo fix

* removing mispelled test component

* WIP: delaying inclusion of component imports until the hydration method is known

* WIP: tweaking the test to use window instead of document

* When only one renderer is included, use that for client:only hydration

* temporary test script snuck into the last commit

* WIP: adding check for a client:only renderer hint

* refactor: Remove client:only components instead of delaying all component import statements

* Updating the changeset and docs for the renderer hint

* refactor: pull client:only render matching out to it's own function

* Updating renderer hinting to match full name, with shorthand for internal renderers

Co-authored-by: Tony Sullivan <[email protected]>

* [ci] yarn format

* Update CONTRIBUTING.md (#1131)

* [ci] yarn format

* docs: fix select language in Safari (#1127) (#1128)

* docs: fix select language in Safari (#1127)

* docs: fix select language top position

* docs: fix select language position

* Make congratsbot not run in forks (#1145)

* add back dark-mode aware favicons

* make example favicons prefer non-dark mode

* Version Packages (next) (#1129)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* code review comments

Co-authored-by: Tony Sullivan <[email protected]>
Co-authored-by: Tony Sullivan <[email protected]>
Co-authored-by: matthewp <[email protected]>
Co-authored-by: FredKSchott <[email protected]>
Co-authored-by: Oleg <[email protected]>
Co-authored-by: Marcus Otterström <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
SiriousHunter pushed a commit to SiriousHunter/astro that referenced this pull request Feb 3, 2023
* Adding support for client:only hydration

* Adding documentation for client:only

* Adding changeset

* Updating the test to use a browser-only API

* Adding a browser-specific import script, this reproduces the issue where client:only imports must be removed

* typo fix

* removing mispelled test component

* WIP: delaying inclusion of component imports until the hydration method is known

* WIP: tweaking the test to use window instead of document

* When only one renderer is included, use that for client:only hydration

* temporary test script snuck into the last commit

* WIP: adding check for a client:only renderer hint

* refactor: Remove client:only components instead of delaying all component import statements

* Updating the changeset and docs for the renderer hint

* refactor: pull client:only render matching out to it's own function

* Updating renderer hinting to match full name, with shorthand for internal renderers

Co-authored-by: Tony Sullivan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants