ElMassimo / iles

🏝 The joyful site generator
https://iles.pages.dev
MIT License
1.08k stars 31 forks source link

Add support for detecting islands in pug templates #83

Open luminarious opened 2 years ago

luminarious commented 2 years ago

Description 📖

client:* directives cannot be used with Pug templating language.

Reproduction 🐞

https://stackblitz.com/edit/iles-dy6fcn?file=src/pages/index.vue None of the GrowButtons are recognized as islands.

luminarious commented 2 years ago

Stackblitz runs dev mode by default, have to manually stop and run npm run build && npm run preview

ElMassimo commented 2 years ago

Hi again Hardi!

Currently, hydration directives are detected by traversing the template nodes obtained using parse from @vue/compiler-sfc, and then checking whether a node has a client: property.

For Pug templates, @vue/compiler-sfc will parse the template as text (instead of html nodes), which means the current algorithm does not have the necessary data to work with.


I'm open to adding support for pug, as long as it doesn't affect performance for other use cases.

It's likely that it will require using the pug engine to parse the template content and obtain an AST or some kind of tree, which allows traversing the nodes to detect hydration directives, to then wrap those nodes inside an Island.

Let me know if you are interested in exploring this, contributions are welcome!

luminarious commented 2 years ago

I wish I could be of any help there, but parsing and compilation are so far outside my comfort zone 😅

Would it be possible to add the entire Island component manually, instead of using the attribute?

ElMassimo commented 2 years ago

parsing and compilation are so far outside my comfort zone 😅

It's ok, just checking. I might be able to take a look over the next couple of weeks.

Would it be possible to add the entire Island component manually, instead of using the attribute?

Possible, yes, but very cumbersome (to a point where using an html template might end up being more convenient, ha)


In the meantime, a workaround if you want to keep using pug, is to create a dummy component with a normal template, and apply the hydration tags passing any additional props:

// src/components/LazyGrowButton.vue
<template>
  <GrowButton client:load v-bind="$attrs"/>
</template>

You can then use LazyGrowButton in pug templates without issues, and it will be hydrated as expected.