feat(nuxt): parse html to treeshake client-only components
🔗 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.
Deploy Preview for nuxt3-docs canceled.
| Name | Link |
|---|---|
| Latest commit | 83bf655840c63bd7a93f1f697244831d843013d7 |
| Latest deploy log | https://app.netlify.com/sites/nuxt3-docs/deploys/633051aa1e602c0009eca831 |
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.
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
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.
@danielroe Anyway we can workaround https://github.com/nuxt/nuxt.js/issues/14896 regex issue?
~> https://github.com/nuxt/framework/pull/7659
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.
🚀 Switched to ultrahtml, a 1.75kB library with zero dependencies and deliberate support for parsing Vue.