framework icon indicating copy to clipboard operation
framework copied to clipboard

feat(nuxt): parse html to treeshake client-only components

Open danielroe opened this issue 3 years ago • 7 comments

🔗 Linked issue

resolves #7517

❓ Type of change

  • [ ] 📖 Documentation (updates to the documentation or readme)
  • [x] 🐞 Bug fix (a non-breaking change that fixes an issue)
  • [ ] 👌 Enhancement (improving an existing functionality like performance)
  • [ ] ✨ New feature (a non-breaking change that adds functionality)
  • [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

This switches from regexp -> parse5 (fast HTML parsing) to remove client only component nodes. It's more stable and also allows us to preserve fallback slots, for example.

The blocker for this PR is currently https://github.com/unjs/jiti/issues/84; jiti is having trouble transforming parse5, blocking testing.

📝 Checklist

  • [x] I have linked an issue or discussion.
  • [ ] I have updated the documentation accordingly.

danielroe avatar Sep 14 '22 22:09 danielroe

Deploy Preview for nuxt3-docs canceled.

Name Link
Latest commit 83bf655840c63bd7a93f1f697244831d843013d7
Latest deploy log https://app.netlify.com/sites/nuxt3-docs/deploys/633051aa1e602c0009eca831

netlify[bot] avatar Sep 14 '22 22:09 netlify[bot]

I will look into jiti issue. Isn't there an easy way to fix the regex issue? Parse5, even if super fast is stil parsing the strings. We might use a hybrid method (like mlly) to improve precision.

pi0 avatar Sep 15 '22 06:09 pi0

Indeed I could fix that particular issue with regexp but I feel parsing the HTML is more reliable. For example, there was always the caveat of nested client-only components.

At some point you reinvent the parser. And I believe parse5 will soon be exposed to us by vite, so we can even benefit from vite caching ast (iirc): https://github.com/vitejs/vite/pull/9678

danielroe avatar Sep 15 '22 07:09 danielroe

Yes, I'm aware that vite itself is using parse5 and it is a really good decision.

But here we are (re) parsing the same template code into AST in a plugin for a particular optimization that benefits only some components. Full parsing makes the built-time overall slower.

If there are finally more edge cases that we cannot handle with regex only, same as mlly we can use a two phase detection with quick regex matcher and precision AST (or Tokenized) verifier when we really are going to make a change to the code.

It would be nice if first could resolve the linked issue via regex and keep working on this PR as a general enhancenment.

pi0 avatar Sep 15 '22 07:09 pi0

@danielroe Anyway we can workaround https://github.com/nuxt/nuxt.js/issues/14896 regex issue?

pi0 avatar Sep 19 '22 09:09 pi0

~> https://github.com/nuxt/framework/pull/7659

danielroe avatar Sep 19 '22 21:09 danielroe

Updating this PR just to keep it in sync. You were right to be careful; parse5 doesn't handle arbitrary self-closing elements. I suppose we could use an xml parser, but a big appeal of it for me was aligning with vite.

danielroe avatar Sep 20 '22 08:09 danielroe

🚀 Switched to ultrahtml, a 1.75kB library with zero dependencies and deliberate support for parsing Vue.

danielroe avatar Sep 25 '22 12:09 danielroe